arckinteractive / mailgun
通过Mailgun进行双向电子邮件处理
Requires
- composer-plugin-api: ^1.0
- composer/installers: ^1.0.8
- fire015/flintstone: ^2.0
- mailgun/mailgun-php: ^2.1
- pelago/emogrifier: ~1.0
- php-http/guzzle6-adapter: ^1.0
- ramsey/uuid: ^3.4
Suggests
README
Mailgun 是 Rackspace 为开发者提供的事务性电子邮件 API 服务。它提供了一项完整的基于云的电子邮件服务,用于发送、接收和跟踪通过您的网站和应用程序发送的电子邮件。
访问 http://www.mailgun.com/ 了解有关 Mailgun 的更多信息,并注册免费账户。
功能
- 处理带有附件和内联图像的 HTML 电子邮件。
- 通过轮询存储的消息或接收直接消息帖子来处理传入的电子邮件。
- 自动检测并删除签名块和引用回复。
- 所有消息自动编码为 UTF-8。
- 强大的传入路由规则允许多个网站或开发人员共享单个域名。
配置
传出
如果您还没有免费账户,请访问 https://mailgun.com/signup 注册免费 Mailgun 账户。在您的 Mailgun 账户中,您需要首先创建并验证一个域名。有关该步骤的说明,请参阅 Mailgun 文档。
发送电子邮件所需的设置很简单。您只需要您的 API 密钥和域名。
在 views/default/mailgun/notification/body.php 中包含了一个示例电子邮件模板,您应该通过覆盖视图对其进行修改。您可以通过点击“查看电子邮件模板”按钮来查看模板的外观。此外,点击“发送测试电子邮件”按钮将向当前登录用户发送电子邮件。
网站电子邮件地址
网站电子邮件地址需要与您的配置域名匹配。在您的基本网站设置中,例如您可以使用 notifications@em.domain.com。
传入
处理传入的电子邮件需要配置存储或转发路由。如果您是一位在本地工作的开发人员,您的系统无法从公共互联网连接,您会配置一个路由以存储您的消息以供稍后检索。对于生产网站,您会配置一个路由将消息直接转发到网站。
在继续之前,请了解有关 Mailgun 路由 的信息。
转发路由
假设我们的配置域名为 em.domain.com,并且我们希望将发送到 notifications+TOKEN@em.domain.com
的所有电子邮件转发到我们的网站,我们会添加一个类似的路由
Priority: 0
Expression: match_recipient('^notifications\+.*@em.domain.com')
Action: forward('http://www.domain.com/mg/messages')
Description: Production notification replies
在收件人地址中,+ 符号之后的所有内容是插件用于识别消息的唯一令牌(或字符串)。当消息被 Mailgun 插件接收时,它将触发一个事件。注册了该事件的其他插件将检查令牌,如果它是它们的,它们将处理电子邮件并返回 false 以阻止进一步的事件传播。
存储路由
使用与转发路由示例相同的域名(em.domain.com),假设您是一位开发人员,需要能够测试传入的电子邮件处理,但您的本地开发环境无法从公共互联网接收网络钩子(帖子)。您的路由可能如下所示
Priority: 0
Expression: match_recipient('^testing\+.*@em.domain.com')
Action: store() | stop()
Description: Production notification replies
在本示例中,任何匹配 testing+TOKEN@em.domain.com
的电子邮件都将存储在 Mailgun 服务器上。对于免费账户,Mailgun 将保留存储的消息 2 天。
当向路由添加操作时,可以将多个操作串联起来。使用 | 符号分隔多个操作。在本示例中,stop() 操作将停止处理任何低优先级的路由。
接下来,配置您的存储消息以便检索。这需要启用轮询并配置一个 1 分钟的 cron 任务。
请注意,我们需要在此指定一个收件人。这是一个简单的字符串匹配,并且是必需的,因为您可能已经配置了多个存储路由。当轮询器运行时,我们希望它只检索为测试/开发网站存储的消息。就是这样!现在每 60 秒轮询器将检索发送到您的测试电子邮件地址的任何电子邮件。
开发者说明
Mailgun 插件提供了获取或接收传入电子邮件的设置和功能,但是如何处理这些电子邮件则取决于其他插件。例如,您的论坛可能允许用户通过在传出电子邮件中添加唯一令牌并注册接收来自 Mailgun 的传入电子邮件来回复通知。
我创建了一个额外的插件,可以作为进一步示例,称为 mailgun_messages。mailgun_messages 插件增强了核心消息插件,允许对站点消息进行电子邮件回复。
以下代码示例显示了如何向您的传出电子邮件添加唯一令牌以及如何注册并接收来自 Mailgun 插件的电子邮件。
令牌
Mailgun 令牌将自动添加到有关对象、用户和组的 订阅 通知中(例如,当发布新博客文章时)。
elgg_trigger_event('publish', 'object', $blog); // After subscription notifications are dispatched, // mailgun token can be accessed via metadata // as "mg:<action>:<entity_type>:<entity_subtype>" $mailgun_token = $blog->{"mg:publish:object:blog"}; // or $mailgun_token = mailgun_get_entity_notification_token($blog, 'publish:object:blog');
您可以使用 "prepare","notification:<action>:<entity_type>:<entity_subtype>"
钩子自定义添加到订阅通知中的令牌。
elgg_register_plugin_hook_handler('prepare', 'notification:publish:object:blog', function($hook, $type, $notification) { $notification->token = 'my-random-token'; return $notification; });
Mailgun 令牌将自动添加到已分配对象的 即时 通知中,例如。
notify_user($to, $from, $subject, $body, [ 'action' => 'my_action', 'object' => $entity, ]);
可以通过 params 添加 Mailgun 令牌到即时通知,例如。
notify_user($to, $from, $subject, $body, [ 'token' => mailgun_get_entity_notification_token($object, 'action'), ]);
您还可以将令牌作为 $params['token']
传递给 elgg_send_email()
。
对于自动生成的令牌,您可以使用 mailgun_get_entity_by_notification_token()
将令牌映射回实体。
自定义即时通知
在本示例中,我们有一个论坛插件,当发布新主题时,会通知已订阅的成员。
function send_new_topic_notification($topic) { // Notification options $options = array( 'subject" => $topic->title, 'body" => $topic->description ); // Get the topic subscribers $subscribers = $topic->getSubscribers(); // Get the site email address $site_email = elgg_get_site_entity()->email; // Add a token to the site email $token = ArckInteractive\Mailgun\Message::addToken($site_email); // Store the token on the topic so we can recognize replies $topic->reply_token = $token['token']; // Set the From address $options['from'] = $token['email']; // In production run this method in a batch and use Vroom foreach ($subscribers as $user) { $options['to'] = $user->email; mailgun_send_email($options); } }
接收回复
默认情况下,插件将尝试将传入电子邮件与通知事件匹配,并将其存储为通知事件对象的评论(或讨论主题的回复)。这适用于已注册对象类型的核心 create
、update
和 publish
事件。
如果传入的电子邮件与个人消息匹配,它将通过消息插件发送给收件人。
现在,要处理论坛主题的所有深入而有意义的回复,我们可以使用类似以下的方法
// Register for the receive message event elgg_register_event_handler('receive', 'mg_message', 'handle_topic_replies'); function handle_topic_replies($event, $type, $message) { // Get the token from the recipient email $token = $message->getRecipientToken(); // Query to see if this token belongs to this forum plugin. $results = elgg_get_entities_from_metadata(array( 'type' => 'object', 'subtype' => 'forum_topic', 'limit' => 1, 'metadata_name_value_pairs' => array( 'name' => 'reply_token', 'value' => $token, 'operator' => '=' ) )); // If this is not our token just return if (empty($results)) { return; } // Set the topic $topic = $results[0]; // Get the Elgg user from the sender $user = get_user_by_email($message->getSender()); // We verify the sending user by the senders email address. if (empty($user)) { return; } $topic->annotate( 'topic_reply', $message->getStrippedText(), $topic->access_id, $user[0]->guid ); // Stop event propagation return false; }
使用 StackEdit 编写。