feat: implement global autoresponder plugin
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
final class RepeatState
|
||||
{
|
||||
public function __construct(private string $baseDir = Settings::STATE_DIR, private ?int $now = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function shouldSend(string $owner, string $ruleId, string $recipient, string $sender, int $repeatMinutes): bool
|
||||
{
|
||||
if ($repeatMinutes <= 0) {
|
||||
return true;
|
||||
}
|
||||
$path = $this->path($owner, $ruleId, $recipient, $sender);
|
||||
if (!is_file($path)) {
|
||||
return true;
|
||||
}
|
||||
$data = json_decode((string)file_get_contents($path), true);
|
||||
$last = is_array($data) ? (int)($data['last_sent_at'] ?? 0) : 0;
|
||||
return ($this->time() - $last) >= ($repeatMinutes * 60);
|
||||
}
|
||||
|
||||
public function record(string $owner, string $ruleId, string $recipient, string $sender): void
|
||||
{
|
||||
$path = $this->path($owner, $ruleId, $recipient, $sender);
|
||||
$dir = dirname($path);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0700, true);
|
||||
}
|
||||
file_put_contents($path, json_encode(['last_sent_at' => $this->time()], JSON_PRETTY_PRINT), LOCK_EX);
|
||||
@chmod($path, 0600);
|
||||
}
|
||||
|
||||
private function path(string $owner, string $ruleId, string $recipient, string $sender): string
|
||||
{
|
||||
if (!preg_match('/^[A-Za-z0-9._-]+$/', $owner)) {
|
||||
throw new InvalidArgumentException('Invalid owner');
|
||||
}
|
||||
$hash = hash('sha256', implode('|', [$owner, $ruleId, strtolower($recipient), strtolower($sender)]));
|
||||
return rtrim($this->baseDir, '/') . '/replies/' . $owner . '/' . $hash . '.json';
|
||||
}
|
||||
|
||||
private function time(): int
|
||||
{
|
||||
return $this->now ?? time();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user