From 180d3c8e22d2ce38b92cb0f178add09277105a24 Mon Sep 17 00:00:00 2001 From: Ruben Date: Tue, 3 Feb 2026 17:35:11 +0100 Subject: [PATCH] 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 --- custom/petition-cli.php | 183 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 14 deletions(-) diff --git a/custom/petition-cli.php b/custom/petition-cli.php index 1f50051..5170814 100755 --- a/custom/petition-cli.php +++ b/custom/petition-cli.php @@ -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'); } } }