Статьи

Использование Mailgun Store (): временный почтовый ящик для входящей электронной почты вашего приложения

Конечный продукт
Что вы будете создавать

Добро пожаловать в специальный выпуск нашей серии « Построение стартапа», спонсируемой Mailgun . В этой серии я проведу вас через запуск стартапа от концепции до реальности, используя мое приложение Meeting Planner в качестве примера из реальной жизни. На каждом этапе мы будем публиковать код Планировщика собраний в качестве примеров с открытым исходным кодом, из которых вы можете извлечь уроки. В сегодняшнем выпуске Mailgun присоединился к спонсору учебного пособия о том, как я интегрировал его API маршрутизации сообщений и Store () для обработки ответов пользователей.

Например, когда люди получают приглашения на собрания от других с помощью Планировщика собраний, они могут просто выбрать ответ и отправить заметку, как если бы они были в обычной ветке электронной почты. Однако я хотел автоматически обработать ответ, добавить его в качестве заметки на собрание и затем уведомить получателя о том, что обновление готово к просмотру. Звучит сложно, но одна из целей Meeting Planner — сократить количество переписок между людьми о планировании и объединить изменения в реальном времени в меньшее количество уведомлений.

Если вы еще не знакомы с Mailgun , это механизм автоматизации электронной почты, которому доверяют более 10 000 разработчиков веб-сайтов и приложений для отправки, получения и отслеживания электронной почты. Используя мощные почтовые API Mailgun, разработчики могут тратить больше времени на создание потрясающих веб-сайтов и меньше времени на борьбу с почтовыми серверами.

Он предлагает множество функций для быстрого и эффективного управления электронной почтой для вашего приложения:

API Mailgun поддерживает все самые популярные языки, включая PHP, Ruby, Python, C # и Java, и предлагает отличную, хорошо организованную документацию .

Это был выбор для меня во многих моих консультационных действиях, стартапах и обучающих программах.

Если вы хотите следовать сегодняшнему учебнику и еще не знакомы с Mailgun, вы можете проверить Изучение Mailgun: Механизм электронной почты для разработчиков или Как Geogram создала бесплатный групповой почтовый сервис с использованием Yii для PHP с MySQL . Вы также можете прочитать Store (): временный почтовый ящик для всей вашей входящей электронной почты для получения дополнительной технической информации.

Весь код для Meeting Planner написан на Yii2 Framework для PHP. Если вы хотите узнать больше о Yii2, ознакомьтесь с нашей параллельной серией Программирование с Yii2 на Envato Tuts +.

Если вы еще не опробовали Планировщик собраний, попробуйте назначить первую встречу прямо сейчас . Это действительно собирается и приближается к альфа-релизу.

Обратная связь приветствуется. Если у вас есть вопрос или предложение по теме, пожалуйста, оставьте комментарий ниже. Вы также можете связаться со мной в Twitter @reifman .

И спасибо, Mailgun, за спонсирование этого эпизода нашего стартапа!

Имейте в виду, что, поскольку это спонсируемое учебное пособие, оно может появиться раньше наших серий серий Startup. Таким образом, некоторый код может появиться дальше, чем в следующих эпизодах.

Я уже говорил об использовании SMTP-доставки Mailgun для исходящих писем в Meeting Planner, но как насчет ответа на электронные письма?

Например, приглашения в Meeting Planner имеют концепцию, называемую заметками. Заметки — это комментарии или сообщения, которыми обмениваются получатели. В настоящее время они могут быть опубликованы на странице просмотра собрания. Вот пример:

Mailgun Store - добавление заметки к собранию через веб-интерфейс

Однако я хотел, чтобы люди могли с легкостью отвечать на электронные письма о встрече, чтобы их сообщение легко добавлялось в качестве заметки к собранию, а затем группировать это обновление с другими уведомлениями об изменениях в собрании. Например, человек может принять места и время из своего электронного письма с приглашением, а затем также ответить на приглашение непосредственно из своего приложения электронной почты или электронной почты в облаке. Организатор собрания получит одно уведомление об обновлениях, а не несколько.

Вот краткое изложение того, что мы строим сегодня:

Во-первых, все письма с расписанием Планировщика собраний будут использовать адрес для ответа, чтобы направить все в почтовый ящик @ meetingplanner.io. Mailgun назначен обрабатывать все входящие электронные письма через наши записи MX. С помощью маршрутизации Mailgun мы можем попросить службу уведомлять наш сервер о поступлении новых сообщений. Затем в фоновом режиме мы можем их обработать.

Mailgun анализирует сообщения с помощью своих экспертных алгоритмов, поэтому нам не нужно это делать. Поэтому нам легко определить, кто ответил на сообщение, на какое собрание они отвечали, и какую заметку они написали в своем сообщении. Наконец, мы добавим заметку к встрече и проинформируем другого участника.

Следуйте, пока я расскажу вам, как это делается.

Mailgun Store - Отзывы клиентов о разборке Mailgun от Jonathan Novak Uservoice

Некоторое время назад я установил записи MX для MeetingPlanner.io, чтобы направлять всю входящую электронную почту непосредственно в Mailgun.

Магазин Mailgun - инфографика, показывающая маршрут входящей электронной почты в Mailgun MX

Вот пример записей MX для Mailgun :

Mailgun Store - Пример Mailgun MX Records

Используя простой пользовательский интерфейс маршрутизации Mailgun, я настроил пересылку почтовых ящиков jeff и support, чтобы заинтересованные люди могли связаться со мной или службой поддержки.

Mailgun Store - маршруты для исключений почтовых ящиков, таких как поддержка и Jeff

Функции маршрутизации Mailgun также предоставляют следующие возможности:

  • При желании получить необработанное сообщение MIME
  • Все сообщения, закодированные в UTF-8 автоматически
  • Бесплатная фильтрация спама
  • Простое тестирование конечных точек webhook
  • Генерация текстовой части из электронных писем только в формате HTML
  • Соответствует всем заголовкам электронной почты (например, теме, от :, cc 🙂 и получателям
  • Возможность связать воедино несколько фильтров, чтобы обеспечить сложные выражения

Когда я был готов интегрировать входящую маршрутизацию для планирования собраний, я решил использовать API хранилища Mailgun’s store (). Хотя Mailgun может доставлять проанализированные электронные письма на ваш веб-сервер в режиме реального времени, временные скачки или сбои в работе вашей собственной службы могут привести к пропуску сообщений. Основываясь на отзывах клиентов, Mailgun решил расширить возможности хранения сообщений в своем облаке и позволить вашему приложению обрабатывать их в течение трех дней.

Вот Mailgun, описывающий некоторые возможные случаи, которые помогает решить облачное хранилище:

В некоторых случаях вложения имеют большой размер и вызывают тайм-ауты, когда мы пытаемся отправить данные на их серверы. В других случаях существует большой объем входящей электронной почты, и клиенты предпочитают просто выполнять запрос GET через некоторый интервал, а не обрабатывать несколько POST от нас. Наконец, это служит избыточностью в случае, если их веб-служба выходит из строя и они не могут принять наши POST.

Поэтому я настроил маршрутизацию Mailgun так, чтобы он просто уведомлял сервер Планировщика собраний при получении нового сообщения. Обратите внимание на третью конфигурацию ниже:

Mailgun Store - URL-адрес для отправки уведомлений на наш сервер

Всякий раз, когда подстановочные сообщения поступают в Meeting Planner, Mailgun сохраняет их () и уведомляет http://meetingplanner.io/mailgun-notification/store, что есть новое сообщение, а затем останавливает () обработку.

Расширение использования API с помощью Mailgun снова оказалось простым, поскольку их документация на высшем уровне. Он обеспечивает поддержку различных языков, например, Ruby, Python, PHP, Java, C # и Go. Он предлагает рабочие примеры реализации функциональности Mailgun в своих сервисах — будь то широковещательная рассылка, отслеживание или маршрутизация.

Итак, используя Yii2 и его автоматический генератор кода скаффолдинга Gii, я создал миграции, модели и контроллеры для модели MailgunNotification.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
class m160514_010650_create_mailgun_notification_table extends Migration
{
  public function up()
  {
      $tableOptions = null;
      if ($this->db->driverName === ‘mysql’) {
          $tableOptions = ‘CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB’;
      }
 
      $this->createTable(‘{{%mailgun_notification}}’, [
          ‘id’ => Schema::TYPE_PK,
          ‘url’ => Schema::TYPE_STRING.’
          ‘status’ => Schema::TYPE_SMALLINT.’
          ‘created_at’ => Schema::TYPE_INTEGER .
          ‘updated_at’ => Schema::TYPE_INTEGER .
      ], $tableOptions);
  }

Он хранит URL-адрес уведомления от Mailgun, который мы можем получить позже. Например:

1
https://api.mailgun.net/v2/domains/meetingplanner.io/messages/eyJw2UsICJrIjogImUyQ5LTk1NmItNGIwOCLWZmZTFjMDU3ZiIsICJzIjogIjNGUiLCAiYyIcyJ9

Вот код, который добавляет необработанные уведомления с STATUS_PENDING :

1
2
3
4
5
6
7
8
9
public function store($message_url) {
     // store the url from mailgun notification
       $mn = new MailgunNotification();
       $mn->status = MailgunNotification::STATUS_PENDING;
       $temp = str_ireplace(‘https://api.mailgun.net/v2/’,»,$message_url);
       $temp = str_ireplace(‘https://api.mailgun.net/v3/’,»,$temp);
       $mn->url = $temp;
       $mn->save();
   }

В этом сценарии вы должны написать производственный код для обработки, а затем реагировать на уведомления и сообщения, о которых вам уведомляет Mailgun. Mailgun предоставляет полезную форму для тестирования вашего сервера в нижней части страницы конфигурации маршрутизации.

Поскольку рабочие серверы труднее отлаживать, потребовалось некоторое время, чтобы сделать это правильно. Сначала я столкнулся с ошибками.

Mailgun Store - Ошибка при разработке обработки уведомлений Mailgun

Но потом, в конце концов, я получил входящие уведомления:

Магазин Mailgun - Успешный Тест Уведомления

По сути, я проанализировал message-url и сохранил его в базе данных:

1
2
3
4
5
6
7
public function actionStore()
   {
     // stores inbound post notification from Mailgun
     if (isset($_POST[‘message-url’])) {
       MailgunNotification::store($_POST[‘message-url’]);
     }
   }

В этом примере представьте, что я ответил на приглашение Тома на собрание, чтобы напомнить ему принести книгу для нашего обсуждения кофе:

Mailgun Store - сценарий пользователя, когда я отправляю записку о встрече по электронной почте

В ответ Mailgun уведомляет нас о сообщении, и безопасный URL-адрес для доступа к его содержимому хранится в таблице MailgunNotification :

Магазин Mailgun - Таблица уведомлений MailgunNotification

Затем я расширил фоновую обработку Meeting Planner, чтобы получать новые сообщения из Mailgun и обрабатывать их. Парсинг электронной почты с помощью Mailgun прост, поскольку они выполнили всю работу, которая в противном случае заняла бы месяцы (и месяцы … и месяцы … и месяцы).

По сути, Mailgun принимает неструктурированную входящую электронную почту (показана слева) и отправляет вашему приложению проанализированные структурированные данные (показаны справа):

Mailgun Store - инфографика мощного анализа API Mailgun

Независимые независимые разработчики тратят месяцы на самостоятельное написание кода, задача, которая так и не была выполнена. Mailgun управляет этим для вас.

Давайте пройдемся по MailgunNotification::Process . Сначала мы ищем ожидающие уведомления в таблице MailgunNotification и вызываем мой компонент Yiigun.php, который делает запрос get() для Mailgun по URL-адресу, который мы получили для уведомления:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
public static function process() {
     $items = MailgunNotification::find()->where([‘status’=>MailgunNotification::STATUS_PENDING])->all();
     if (count($items)==0) {
       return false;
     }
     $yg = new Yiigun();
     foreach ($items as $m) {
       $error = false;
       // echo $m->id.'<br />’;
       $raw_response = $yg->get($m->url);
       if (is_null($raw_response)) {
         $m->status = MailgunNotification::STATUS_NOT_FOUND;
         $m->update();
         continue;
       }
       $response = $raw_response->http_response_body;

Mailgun возвращает подробные данные из сообщения. Таким образом, мы анализируем meeting_id из поля получателя, основного текста и электронного письма отправителя. Опять же, Mailgun делает это легко:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$stripped_text = \yii\helpers\HtmlPurifier::process($response->{‘stripped-text’});
       // parse the meeting id
       if (isset($response->To)) {
         $to_address = $response->To;
       } else {
         $to_address = $response->to;
       }
       $to_address = str_ireplace(‘@meetingplanner.io’,»,$to_address);
       $to_address = str_ireplace(‘mp_’,»,$to_address);
       $meeting_id = intval($to_address);
       if (!is_numeric($meeting_id)) {
         $error = true;
         $m->status = MailgunNotification::STATUS_INVALID_MEETING_ID;
         $m->update();
         continue;
       }
       // echo ‘mid: ‘.$meeting_id.'<br>’;
       // verify meeting id is valid
       if (isset($response->Sender)) {
         $sender = $response->Sender;
       } else {
         $sender = $response->sender;
       }
       // clean sender
       // echo ‘ pre clean sender: ‘.$sender.'<br>’;
       $sender = \yii\helpers\HtmlPurifier::process($sender);
       // echo ‘sender: ‘.$sender.'<br>’;
       $user_id = User::findByEmail($sender);
       if ($user_id===false) {
         $error = true;
         // do nothing
         // to do — reply with do not recognize email address
         $m->status = MailgunNotification::STATUS_UNRECOGNIZED_SENDER;
         $m->update();
         continue;

Я особенно ценю, что Mailgun предоставляет раздетый текст, который берет подпись отправителя и ветку ответа. Я также использую HtmlPurifier чтобы предотвратить попадание потенциально опасного неэкранированного текста на наш сервер.

В ходе этой работы я вновь узнал, что для доступа к свойству дефиса объекта в PHP необходимо заключить его в фигурные скобки:

1
$stripped_text = \yii\helpers\HtmlPurifier::process($response->{‘stripped-text’});

И, наконец, как только мы определили, что встреча и отправитель существуют и что последний является участником, мы добавляем stripped_text в качестве примечания:

1
2
3
4
5
6
7
// echo ‘check attendee’;
         // verify sender is a participant or organizer to this meeting
         $is_attendee = Meeting::isAttendee($meeting_id,$user_id);
         if ($is_attendee) {
           // add meeting note, automatically its logged and meeting touch stamp updated
           MeetingNote::add($meeting_id,$user_id,$stripped_text);
         } else {

Новая заметка появится на странице событий Встречи, когда участник вернется:

Mailgun Store - приглашение на встречу с заметкой из электронной почты, добавленной автоматически

Yii поддерживает события ActiveRecord, поэтому при добавлении MeetingLog автоматически создается запись MeetingLog :

1
2
3
4
5
6
7
8
public function afterSave($insert,$changedAttributes)
   {
       parent::afterSave($insert,$changedAttributes);
       if ($insert) {
         // if MeetingNote
         MeetingLog::add($this->meeting_id,MeetingLog::ACTION_ADD_NOTE,$this->posted_by,$this->id);
       }
   }

В следующем эпизоде ​​я объясню, как это событие вызовет другое событие, которое помогает планировщику собраний координировать действия, когда лучше всего уведомлять участников собрания о том, что произошла новая заметка или другое изменение.

Попробуйте отправить приглашение организатора собрания и попросите получателя ответить на электронное письмо с сообщением. Вы должны получить уведомление вскоре после того, как они это сделали, и затем сможете просмотреть его на странице события.

Надеюсь, вам понравился этот прикладной взгляд на использование API маршрутизации и store () Mailgun. Это довольно забавный и сложный API для работы. Mailgun действительно предлагает широкий спектр почтовых сервисов, которые имеют отношение ко всем видам кодирования и развития бизнеса. И, что впечатляюще, они отлично справляются со всем, что предлагают.

Конечно, это спонсируемый пост, но, как опытный пользователь, я предлагаю вам подлинную рекомендацию попробовать этот сервис сегодня . Я использовал их для всех своих проектов.

И, очевидно, есть много других сценариев, которые мы могли бы построить при обработке сообщений. Например, мы могли бы позволить пользователям отвечать с помощью команд, таких как «поздно», и мы будем знать, чтобы напечатать другому человеку, что их коллега опаздывает.

Пожалуйста, дайте нам знать, какие функции Mailgun вы бы хотели видеть в будущем. Вы можете оставить их в комментариях ниже или связаться со мной напрямую в Twitter @reifman .