Add option to send confirmation to specific email addresses

Add customizable email delay for bulk operations
Fix URL typo in confirmation email
Update menu options and case handling
This commit is contained in:
Ruben 2026-02-03 17:35:11 +01:00
parent 201f5ebb6a
commit 180d3c8e22

View file

@ -312,7 +312,7 @@ function sendEmail(string $to, string $toName, string $subject, string $body): a
* Build confirmation email body
*/
function buildConfirmationEmail(array $signature, string $petitionTitle): array {
$confirmUrl = "https://stopplidelsen.no/underskriftskampanjer/{$signature['petition_id']}/?confirm={$signature['token']}#sign-now";
$confirmUrl = "https://stopplidelsen.no/underskriftskampanje/{$signature['petition_id']}/?confirm={$signature['token']}#sign-now";
$body = "Hei {$signature['firstname']}!\n\n";
$body .= "Takk for at du signerte underskriftskampanjen \"{$petitionTitle}\".\n\n";
@ -406,10 +406,11 @@ function showMenu(): void {
echo " 2) Vis ubekreftede signaturer\n";
echo " 3) Send e-post pa nytt til mislykkede\n";
echo " 4) Send bekreftelse pa nytt til ubekreftede\n";
echo " 5) Marker oppforinger som ignorert\n";
echo " 6) Manuell bekreftelse av signaturer\n";
echo " 7) Slett signaturer\n";
echo " 8) Avslutt\n";
echo " 5) Send bekreftelse til spesifikke e-postadresser\n";
echo " 6) Marker oppforinger som ignorert\n";
echo " 7) Manuell bekreftelse av signaturer\n";
echo " 8) Slett signaturer\n";
echo " 9) Avslutt\n";
echo "\n";
}
@ -602,12 +603,23 @@ function resendToUnconfirmed(): void {
return;
}
// Ask for custom delay
$delaySeconds = EMAIL_DELAY_SECONDS;
$customDelay = prompt("\nForsinkelse mellom e-poster i sekunder [standard: " . EMAIL_DELAY_SECONDS . "]: ");
if (!empty($customDelay) && is_numeric($customDelay) && (int)$customDelay >= 0) {
$delaySeconds = (int)$customDelay;
}
$total = count($valid);
$estimatedMinutes = ceil(($total * EMAIL_DELAY_SECONDS) / 60);
$estimatedMinutes = $delaySeconds > 0 ? ceil(($total * $delaySeconds) / 60) : 0;
echo "\n";
printColor("Sender med " . EMAIL_DELAY_SECONDS . " sekunders mellomrom (maks 250/time)...\n", 'blue');
echo "Estimert tid: ca. {$estimatedMinutes} minutter\n\n";
printColor("Sender med " . $delaySeconds . " sekunders mellomrom...\n", 'blue');
if ($estimatedMinutes > 0) {
echo "Estimert tid: ca. {$estimatedMinutes} minutter\n\n";
} else {
echo "\n";
}
$success = 0;
$failures = 0;
@ -635,8 +647,148 @@ function resendToUnconfirmed(): void {
}
// Wait before next email (except for last one)
if ($i < $total - 1) {
sleep(EMAIL_DELAY_SECONDS);
if ($i < $total - 1 && $delaySeconds > 0) {
sleep($delaySeconds);
}
}
echo "\n";
printColor("Ferdig: {$success} vellykket, {$failures} mislykket\n", $failures > 0 ? 'yellow' : 'green');
}
/**
* Send confirmation to specific email addresses
*/
function sendToSpecificEmails(): void {
echo "\n";
printColor("Send bekreftelse til spesifikke e-postadresser\n", 'cyan');
echo "\n";
$input = prompt("Skriv inn e-postadresse(r) (kommaseparert): ");
if (empty(trim($input))) {
echo "Ingen e-postadresser oppgitt.\n";
return;
}
// Parse and clean email addresses
$emails = array_map('trim', explode(',', $input));
$emails = array_filter($emails, fn($e) => !empty($e));
$emails = array_map('strtolower', $emails);
if (empty($emails)) {
echo "Ingen gyldige e-postadresser oppgitt.\n";
return;
}
echo "\n";
echo "Soker etter " . count($emails) . " e-postadresse(r)...\n\n";
// Find matching unconfirmed signatures
$found = [];
$currentTime = time();
foreach (getPetitionFiles() as $petitionId) {
$signatures = getUnconfirmedSignatures($petitionId, false); // Include ignored
foreach ($signatures as $sig) {
if (in_array(strtolower($sig['email']), $emails)) {
$sig['expired'] = ($currentTime - $sig['token_created']) > 2592000;
$found[] = $sig;
}
}
}
// Determine which emails were not found
$foundEmails = array_map(fn($f) => strtolower($f['email']), $found);
$notFound = [];
foreach ($emails as $email) {
if (!in_array($email, $foundEmails)) {
$notFound[] = $email;
}
}
if (!empty($notFound)) {
printColor("Ikke funnet (eller allerede bekreftet):\n", 'red');
foreach ($notFound as $email) {
echo " - {$email}\n";
}
echo "\n";
}
if (empty($found)) {
echo "Ingen ubekreftede signaturer a sende til.\n";
return;
}
// Show what will be sent
printColor("Fant folgende ubekreftede signaturer:\n", 'yellow');
foreach ($found as $entry) {
$date = formatDate($entry['timestamp']);
$name = $entry['firstname'] . ' ' . $entry['surname'];
$status = $entry['expired'] ? ' [UTLOPT]' : '';
echo " - {$entry['email']} ({$name}) - {$entry['petition_id']}{$status}\n";
}
// Filter out expired
$valid = array_filter($found, fn($f) => !$f['expired']);
$valid = array_values($valid);
$expiredCount = count($found) - count($valid);
if ($expiredCount > 0) {
echo "\n";
printColor("{$expiredCount} signatur(er) har utlopt token og vil bli hoppet over.\n", 'yellow');
}
if (empty($valid)) {
echo "Ingen gyldige signaturer a sende til.\n";
return;
}
echo "\n";
if (!confirm("Sende bekreftelse til " . count($valid) . " adresse(r)?")) {
echo "Avbrutt.\n";
return;
}
// Ask for custom delay
$delaySeconds = EMAIL_DELAY_SECONDS;
$customDelay = prompt("\nForsinkelse mellom e-poster i sekunder [standard: " . EMAIL_DELAY_SECONDS . "]: ");
if (!empty($customDelay) && is_numeric($customDelay) && (int)$customDelay >= 0) {
$delaySeconds = (int)$customDelay;
}
$total = count($valid);
echo "\n";
printColor("Sender...\n", 'blue');
echo "\n";
$success = 0;
$failures = 0;
foreach ($valid as $i => $signature) {
$num = $i + 1;
echo "[{$num}/{$total}] {$signature['email']} ... ";
$email = buildConfirmationEmail($signature, $signature['petition_id']);
$result = sendEmail(
$signature['email'],
$signature['firstname'] . ' ' . $signature['surname'],
$email['subject'],
$email['body']
);
if ($result['success']) {
printColor("OK\n", 'green');
logEmailResult('confirmation', $signature['petition_id'], $signature['email'], true);
$success++;
} else {
printColor("FEILET: {$result['error']}\n", 'red');
logEmailResult('confirmation', $signature['petition_id'], $signature['email'], false, $result['error']);
$failures++;
}
// Wait before next email (except for last one)
if ($i < $total - 1 && $delaySeconds > 0) {
sleep($delaySeconds);
}
}
@ -1129,22 +1281,25 @@ function main(): void {
resendToUnconfirmed();
break;
case '5':
markAsIgnored();
sendToSpecificEmails();
break;
case '6':
manuallyConfirmSignatures();
markAsIgnored();
break;
case '7':
manuallyDeleteSignatures();
manuallyConfirmSignatures();
break;
case '8':
manuallyDeleteSignatures();
break;
case '9':
case 'q':
case 'quit':
case 'exit':
echo "Ha det!\n";
exit(0);
default:
printColor("Ugyldig valg. Velg 1-8.\n", 'red');
printColor("Ugyldig valg. Velg 1-9.\n", 'red');
}
}
}