LoginSignup
15
11

More than 5 years have passed since last update.

SendGridのEventWebhookをAWS DynamoDBにいれるまで!

Last updated at Posted at 2015-12-17

はじめに

 SendGridのメールサービスを触ってみた。
 今回は、SendGridのSMTPリクエストとSendGrid EventWebhookを使いAWS側で受け取るところまでを紹介します。(ほんとは分析ようにKibanaまで行きたかったので、それは別で書こうと思います(*^_^*)

SendGridとは

 SendGridは月間200億通を超えるメール配信を行い、世界のメール業界を支えています。
 ただ大量の配信をするだけでなく、配信したメールのアナリティクス機能も提供しています。
トランザクションメールなんかも送れるので、利用の幅は広いですね。
 

フロー

1.png

実装

SendGrid SMTP APIを使ったリクエスト

SMTP APIではX-SMTPAPIヘッダを利用してメールのカスタム処理を指定できる。

composer.json
{
    "minimum-stability" : "dev",
    "require": {
        "sendgrid/smtpapi": "~0.5",
        "swiftmailer/swiftmailer": "@stable"
    }
}
sendMail.php
<?php
date_default_timezone_set('Asia/Tokyo');

require_once dirname( __FILE__ )."/lib/vendor/autoload.php";
use Smtpapi\Header;
// カスタムヘッダ例 名前の埋め込み
$to = array('kazuki.mitani+01@nijibox.co.jp', 'kazuki.mitani+02@nijibox.co.jp');
$from = "smtp-testmail@nijibox.co.jp";
$subject = "お久しぶり";
$body    = <<<EOF
%how%さんこんにちは! \r\n
最近元気ですか?
EOF;
$substitution = array('三谷', '伊藤', '吉田');

//
$message = new \Swift_Message();
$message->setTo($to);
$message->setFrom($from);
$message->setSubject($subject);
$message->setBody($body);

// SMTP サーバーとの接続設定
$transport = \Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 587);
$transport->setUsername('SENDGRID_USER');
$transport->setPassword('SENDGRID_PASS');
$mailer = \Swift_Mailer::newInstance($transport);

// ヘッダーの設定
$header = new Header();
$header->addSubstitution('%how%', $substitution);

$message_headers = $message->getHeaders();
$message_headers->addTextHeader(HEADER::NAME, $header->jsonString());

// 送信
try {
    $response = $mailer->send($message);
    print_r($response);
} catch(\Swift_TransportException $e) {
    print_r($e->getMessage());
}

DynamoDBの作成

DynamoDB

テーブル作成
テーブル名:SendGridEvents
プライマリーキー:sg_event_id 文字列

で作成。

Lambdaの設定

受け取ったWebhookのポストをパースしてDynamoDBに入れるためのLambda Functionを作ります
AWS Lambda

Create a Lambda function

元に使えそうなblueprintを選択。
今回は、microserice-http-endpointを選択しました

設定
name:SendGrid-EventWebhook
Description:ダイナモDBに入れる
Runtime:NodeJS

コードを書く

lambda.js
var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();

exports.handler = function(event, context) {
  function logArrayElements(element, index, array){
    var params = {
      TableName: 'SendGridEvents',
      Item:element
    };
    dynamo.putItem(params, function (err, data) {
      if (err) {
        console.log(err, err.stack);
      } else {
        console.log(data);
      }
    });
  }
event.forEach(logArrayElements);
};

API Gatewayの設定

SendGridから飛んでくるWebhookの受け場所を作ります。
AWS API Gateway

Create API

Create Method

POSTを選択
Integration type:Lambda Function
Lambda Region:ap-northeast-1(作製したLambdaのRegion)
Lambda Function:SendGrid-EventWebhook(作製したLambdaのFunction名)

EventWebhook到達確認

INTEGRATION TESTING TOOL

AWS側の設定はここまでで終了したので、疎通確認を行います。
SendGridでは実際にメールを送らず、受け取り側のテストだけ行える”INTEGRATION TESTING TOOL”を提供しています。
SendGrid

ログイン

ダッシュボード

Mail Settings

Event Notification

HTTP POST URL:API GatewayのURL

SELECT ACTIONSのすべてにチェックを付ける

保存してTestYourIntegrationをクリック。

DynamoDBの格納確認が出来たら成功!

SMTPAPIを使った疎通確認

先に作成したphpを実行して、メールリクエストを送ることで実際のWebhookを受け取れるか確認する。
$ php sendMail.php

メールが届く

でもWebhookは届かない!!!

状況確認
1.INTEGRATION TESTING TOOLでは動く。
↓AWSは悪くない。
2.SendGridのEventWebhookがそもそもAPIGatewayに到達していない。
↓SendGrid側が怪しい。
3.ngrokを使ってEventWebhookのPOSTをローカルで受け取れた。
↓Webhookは送られている。

結果:SendGridのWebhookの挙動が怪しい。

ここで天から舞い降りた鶴の一声でAWS API GatewayのCustom Domain Namesを使用してみることに。
※https通信するためにAWSにCertificate body, Certificate private key, Certificate chainを登録する必要がある。

AWS API Gateway

Custom Domain Names

Base path:api-gateway
API:SendGrid-EventWebhook
Stage:なし

https://使いたいドメイン/BasePath/Stage名/API名
例: https://DOMAINNAME/api-gateway/prod/SendGrid-EventWebhook

SMTPAPIテスト

メールが届く

DynamoDBにデータが入る!成功!!

まとめ

SendGridと、使ってみたかったAWSに触れてみました。
全く理解不能なところで詰まったり、悩んでた割にすんなりと設定出来たりといろいろ経験が出来ました。

おわり

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11