Δεν είναι σωστή η ώρα; Το email στάλθηκε πολύ νωρίς; Η καθυστέρηση των μηνυμάτων ηλεκτρονικού ταχυδρομείου μπορεί να είναι χρήσιμη σε πολλές περιπτώσεις: είτε για να δώσετε στον εαυτό σας χρόνο αναθεώρησης είτε για να διαχειριστείτε αποτελεσματικά τον δικό σας φόρτο εργασίας - ο χρόνος μπορεί να είναι ζωτικής σημασίας. Ακολουθούν τρεις τρόποι με τους οποίους μπορείτε να καθυστερήσετε την αποστολή email και να βελτιστοποιήσετε τις δικές σας επικοινωνίες.
Αποψη
Το Microsoft Outlook προσφέρει μια ενσωματωμένη δυνατότητα που σας επιτρέπει να καθυστερείτε τα email. Για να το κάνετε αυτό, χρησιμοποιείτε τη συνάρτηση "Επιλογές > Καθυστέρηση παράδοσης":

Το μεγάλο μειονέκτημα αυτής της λύσης είναι ότι (ακόμη και σε περιβάλλοντα Exchange) το Outlook πρέπει να εκτελείται από την πλευρά του πελάτη τη στιγμή της αποστολής.
Το Gmail προσφέρει μια ελαφρώς καλύτερη λύση εδώ. Για να το κάνετε αυτό, μεταβείτε στο "Προγραμματισμός αποστολής" πριν στείλετε ένα email.:

Τα email που έχουν ήδη αποσταλεί μπορούν επίσης να «αναιρηθούν» εντός 30 δευτερολέπτων. Για να το κάνετε αυτό, ορίστε πρώτα την αντίστοιχη ρύθμιση στην ενότητα "Κλήση όλων των ρυθμίσεων".:

Εάν στείλετε τώρα ένα email, μπορείτε να το αναιρέσετε εντός αυτής της χρονικής περιόδου κάτω αριστερά:

Μπούμερανγκ
Υπάρχουν πάροχοι υπηρεσιών επί πληρωμή όπως το Boomerang for Outlook που, εκτός από υπενθυμίσεις ή αυτοματοποιημένες επακόλουθες ενέργειες, προσφέρουν επίσης καθυστερημένη αποστολή email:

Το μειονέκτημα εδώ είναι ότι τα email καταλήγουν σε διακομιστές τρίτων και υπάρχει χρέωση για τη χρήση τους.
PHP
Αρκετός λόγος για να δημιουργήσετε κάτι μόνοι σας: Μπορείτε επίσης να πετύχετε αυτό που θέλετε με τη βοήθεια ενός μικρού σεναρίου PHP . Αρχικά, δημιουργούμε μια δομή φακέλου στο γραμματοκιβώτιό μας:

Αυτό αντικατοπτρίζει τον επιθυμητό χρόνο αποστολής. Η ροή εργασίας αποτελείται πλέον από την αποθήκευση του γραπτού email ως πρόχειρο αντί να το στείλετε και να το μετακινήσετε στον σχετικό φάκελο. Στη συνέχεια εγκαθιστούμε όλα τα απαιτούμενα πακέτα PHP:
composer require php-imap/php-imap phpmailer/phpmailer vlucas/phpdotenv
Τέλος δημιουργούμε ένα .env
-Αρχείο με δεδομένα πρόσβασης και ρυθμίσεις:
HOST_SMTP="xxx"
PORT_SMTP=465
HOST_IMAP="xxx"
PORT_IMAP=993
USERNAME="foo@bar.com"
PASSWORD="xxx"
ENCRYPTION="ssl"
FROM_ADDRESS="foo@bar.com"
FROM_NAME="Foo Bar"
FOLDER_INBOX="INBOX/DELAY"
FOLDER_OUTBOX="Gesendete Elemente"
PHP_EXECUTABLE="/usr/bin/php"
Το παρακάτω σενάριο PHP κάνει τα υπόλοιπα:
<?php
require_once __DIR__ . '/vendor/autoload.php';
class MailDelay
{
private \PhpImap\Mailbox $mailbox;
private array $folders;
public function init(): void
{
$this->loadEnvironmentVariables();
$this->initMailbox();
$this->initFolders();
$this->processFolders();
}
private function loadEnvironmentVariables(): void
{
$dotenv = \Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
}
private function initMailbox(): void
{
$this->mailbox = new \PhpImap\Mailbox(
'{' . $_SERVER['HOST_IMAP'] . ':' . $_SERVER['PORT_IMAP'] . '/imap/ssl}' . $_SERVER['FOLDER_INBOX'],
$_SERVER['USERNAME'],
$_SERVER['PASSWORD'],
sys_get_temp_dir(),
'UTF-8'
);
}
private function initFolders(): void
{
$this->folders = [];
$folders = $this->mailbox->getMailboxes('*');
foreach ($folders as $folder) {
if ($folder['shortpath'] === $_SERVER['FOLDER_INBOX']) {
continue;
}
$this->folders[] = (object) $folder;
}
}
private function processFolders(): void
{
foreach ($this->folders as $folder) {
$this->mailbox->switchMailbox($folder->fullpath);
$mailIds = $this->mailbox->searchMailbox('ALL');
foreach ($mailIds as $mailId) {
$preparedMail = $this->prepareMailData($mailId, $folder->shortpath);
if (
$preparedMail->subject !== 'Dies ist Plain Text' &&
strtotime($preparedMail->time_to_send) > strtotime('now')
) {
continue;
}
try {
$this->sendMail($preparedMail);
echo 'Successfully sent mail #' . $preparedMail->id . '.' . PHP_EOL;
} catch (\Exception $e) {
echo 'Error in sending mail #' . $preparedMail->id . ': ' . $e->getMessage() . PHP_EOL;
}
}
}
echo 'All mails have been processed.' . PHP_EOL;
}
private function prepareMailData(int $id, string $folder): object
{
$mail = $this->mailbox->getMail($id, false); // don't mark as unread
return (object) [
'id' => (string) $mail->id,
'to' => $this->formatEmailAddresses($mail->to),
'cc' => $this->formatEmailAddresses($mail->cc),
'bcc' => $this->formatEmailAddresses($mail->bcc),
'subject' => (string) $mail->subject,
'content_html' => $this->convertEncoding($mail->textHtml),
'content_plain' => $this->convertEncoding($mail->textPlain),
'attachments' => $this->determineAttachments($mail->getAttachments()),
'time_to_send' => $this->determineTimeToSend(explode('/', $folder)[2], $mail->date)
];
}
private function formatEmailAddresses(?array $addresses): ?array
{
if (empty($addresses)) {
return null;
}
return array_map(
function ($key, $value) {
return [
'email' => $key,
'name' => $key === $value ? null : str_replace(' (' . $key . ')', '', $value)
];
},
array_keys($addresses),
$addresses
);
}
private function convertEncoding(string $text): string
{
return mb_detect_encoding($text, 'UTF-8, ISO-8859-1') !== 'UTF-8'
? \UConverter::transcode($text, 'UTF8', 'ISO-8859-1')
: $text;
}
private function determineAttachments(array $attachmentsImap): array
{
$attachments = [];
if (!empty($attachmentsImap)) {
foreach ($attachmentsImap as $attachment) {
$attachments[] = [
'name' => $attachment->name,
'file' => $attachment->filePath,
'disposition' => $attachment->disposition,
'inline_id' => $attachment->contentId
];
}
}
return $attachments;
}
private function determineTimeToSend(string $delayTime, string $date): ?string
{
$timeToSend = null;
if ($delayTime === 'THIS EVENING') {
$timeToSend = date('Y-m-d', strtotime($date)) . ' 18:00:00';
} elseif ($delayTime === 'THIS NIGHT') {
$timeToSend =
date('Y-m-d', strtotime($date . (date('H', strtotime($date)) >= 4 ? ' + 1 day' : ''))) . ' 03:42:00';
} elseif ($delayTime === 'NEXT MORNING') {
$timeToSend =
date('Y-m-d', strtotime($date . (date('H', strtotime($date)) >= 9 ? ' + 1 day' : ''))) . ' 09:00:00';
} elseif ($delayTime === 'NEXT WEEK') {
$date = new \DateTime(date('Y-m-d', strtotime($date)));
$date->modify('next monday');
$timeToSend = $date->format('Y-m-d') . ' 09:00:00';
}
return $timeToSend;
}
private function sendMail(object $preparedMail): void
{
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
$mail->isSMTP();
$mail->Host = $_SERVER['HOST_SMTP'];
$mail->Port = $_SERVER['PORT_SMTP'];
$mail->Username = $_SERVER['USERNAME'];
$mail->Password = $_SERVER['PASSWORD'];
$mail->SMTPSecure = $_SERVER['ENCRYPTION'];
$mail->setFrom($_SERVER['FROM_ADDRESS'], $_SERVER['FROM_NAME']);
$mail->SMTPAuth = true;
$mail->SMTPOptions = [
'tls' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true],
'ssl' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true]
];
$mail->CharSet = 'utf-8';
$this->addRecipients($mail, $preparedMail->to, 'addAddress');
$this->addRecipients($mail, $preparedMail->cc, 'addCC');
$this->addRecipients($mail, $preparedMail->bcc, 'addBCC');
$mail->isHTML(!empty($preparedMail->content_html));
$mail->Subject = $preparedMail->subject;
if (!empty($preparedMail->content_html)) {
$mail->Body = $preparedMail->content_html;
$mail->AltBody = !empty($preparedMail->content_plain)
? $preparedMail->content_plain
: strip_tags(str_replace(['<br>', '<br/>', '<br />'], "\r\n", $preparedMail->content_html));
} else {
$mail->Body = $preparedMail->content_plain;
}
$this->addAttachments($mail, $preparedMail->attachments);
$mail->send();
$this->mailbox->moveMail($preparedMail->id, $_SERVER['FOLDER_OUTBOX']);
}
private function addRecipients(\PHPMailer\PHPMailer\PHPMailer $mail, ?array $recipients, string $method): void
{
if (!empty($recipients)) {
foreach ($recipients as $recipient) {
$mail->$method($recipient['email'], $recipient['name']);
}
}
}
private function addAttachments(\PHPMailer\PHPMailer\PHPMailer $mail, array $attachments): void
{
if (!empty($attachments)) {
foreach ($attachments as $attachment) {
if (!empty($attachment['file']) && !empty($attachment['name']) && file_exists($attachment['file'])) {
if ($attachment['disposition'] === 'attachment') {
$mail->addAttachment($attachment['file'], $attachment['name']);
} elseif ($attachment['disposition'] === 'inline') {
$mail->AddEmbeddedImage(
$attachment['file'],
$attachment['inline_id'],
$attachment['name'],
'base64',
'image/png'
);
}
}
}
}
}
}
$md = new MailDelay();
$md->init();
Για να εκτελείται επανειλημμένα αυτό το σενάριο, δημιουργούμε ένα αρχείο bash:
#!/usr/bin/env bash
source $(dirname "$0")/.env
"$PHP_EXECUTABLE" $(dirname "$0")/maildelay.php
Στη συνέχεια, εκτελούμε αυτό το σενάριο κάθε 10 λεπτά μέσω cron job:
*/10 * * * * /path/to/maildelay/maildelay.sh 2>&1
Αυτή η λύση είναι ευέλικτα προσαρμόσιμη, φιλική προς το απόρρητο και δωρεάν. Λειτουργεί με οποιονδήποτε λογαριασμό (συμβατό με IMAP). Ωστόσο, ανεξάρτητα από το αν χρησιμοποιείτε την ενσωματωμένη λειτουργία στο Outlook ή στο Gmail, χρησιμοποιήστε προηγμένα εργαλεία όπως το Boomerang ή εφαρμόστε μια μεμονωμένη λύση - η αποστολή μηνυμάτων ηλεκτρονικού ταχυδρομείου σε χρονική βάση είναι ένα πολύτιμο εργαλείο για την αύξηση της παραγωγικότητάς σας.