الوقت غير مناسب؟ هل تم إرسال البريد الإلكتروني مبكرًا جدًا؟ يمكن أن يكون تأخير رسائل البريد الإلكتروني مفيدًا في العديد من المواقف: سواء كنت تمنح نفسك وقتًا للمراجعة أو لإدارة عبء العمل الخاص بك بشكل فعال - يمكن أن يكون التوقيت أمرًا بالغ الأهمية. فيما يلي ثلاث طرق يمكنك من خلالها تأخير إرسال رسائل البريد الإلكتروني وتحسين اتصالاتك الخاصة.
التوقعات
يقدم Microsoft Outlook ميزة مضمنة تسمح لك بتأخير رسائل البريد الإلكتروني. للقيام بذلك، يمكنك استخدام الدالة "خيارات > تأخير التسليم":
العيب الكبير لهذا الحل هو أنه (حتى في بيئات Exchange) يجب تشغيل Outlook على جانب العميل في وقت الإرسال.
جوجل
يقدم Gmail حلاً أفضل قليلاً هنا. للقيام بذلك، انتقل إلى "جدولة الإرسال" قبل إرسال البريد الإلكتروني.:
يمكن أيضًا "التراجع" عن رسائل البريد الإلكتروني التي تم إرسالها بالفعل خلال 30 ثانية. للقيام بذلك، عليك أولاً ضبط الإعداد المعني ضمن "استدعاء جميع الإعدادات".:
إذا قمت الآن بإرسال بريد إلكتروني، فيمكنك التراجع عنه خلال هذه الفترة الزمنية في أسفل اليسار:
يرتد
هناك موفرو خدمات مدفوعة مثل Boomerang for Outlook ، بالإضافة إلى التذكيرات أو المتابعات التلقائية، يقدمون أيضًا خدمة تأخير إرسال البريد الإلكتروني:
العيب هنا هو أن رسائل البريد الإلكتروني تنتهي في نهاية المطاف على خوادم الطرف الثالث وهناك رسوم مقابل استخدامها.
بي أتش بي
السبب الكافي لبناء شيء ما بنفسك: يمكنك أيضًا تحقيق ما تريد بمساعدة برنامج PHP صغير. أولاً، نقوم بإنشاء بنية مجلد في صندوق البريد الخاص بنا:
وهذا يعكس وقت الشحن المطلوب. يتكون سير العمل الآن من حفظ البريد الإلكتروني المكتوب كمسودة بدلاً من إرساله ونقله إلى المجلد ذي الصلة. نقوم بعد ذلك بتثبيت كافة حزم 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:
*/10 * * * * /path/to/maildelay/maildelay.sh 2>&1
هذا الحل قابل للتخصيص بمرونة وصديق للخصوصية ومجاني. إنه يعمل مع أي حساب (متوافق مع IMAP). ولكن بغض النظر عما إذا كنت تستخدم الوظيفة المدمجة في Outlook أو Gmail، استخدم أدوات متقدمة مثل Boomerang أو قم بتنفيذ حل فردي - يعد إرسال رسائل البريد الإلكتروني على أساس زمني أداة قيمة لزيادة إنتاجيتك.