Implement IMAP email-to-ticket gateway
This commit is contained in:
1 parent
b7e5884457
commit
6f25869345
33 files changed
+5619
-5
No files matched your search
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Box\Mod\Mailgateway;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
|
||||
class NotificationCooldown
|
||||
{
|
||||
private int $seconds;
|
||||
|
||||
public function __construct(private Connection $connection, ?int $seconds = null)
|
||||
{
|
||||
$this->seconds = $seconds ?? RuntimeConfig::get('notification_cooldown_seconds');
|
||||
}
|
||||
|
||||
/** Atomically reserve a sender's notification slot and queue the email. */
|
||||
public function run(string $sender, callable $queue): bool
|
||||
{
|
||||
$key = hash('sha256', strtolower(trim($sender)));
|
||||
$now = time();
|
||||
|
||||
return $this->connection->transactional(function () use ($key, $now, $queue): bool {
|
||||
try {
|
||||
$this->connection->insert('mailgateway_notification', ['sender_key' => $key, 'last_notified_at' => 0]);
|
||||
} catch (UniqueConstraintViolationException) {
|
||||
// Existing sender; the conditional update decides who owns the slot.
|
||||
}
|
||||
$claimed = $this->connection->executeStatement(
|
||||
'UPDATE mailgateway_notification SET last_notified_at = ? WHERE sender_key = ? AND last_notified_at <= ?',
|
||||
[$now, $key, $now - $this->seconds],
|
||||
);
|
||||
if ($claimed !== 1) {
|
||||
return false;
|
||||
}
|
||||
if ($queue() === false) {
|
||||
// Disabled templates do not consume the sender's notification slot.
|
||||
$this->connection->delete('mailgateway_notification', ['sender_key' => $key]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user