SendGridの新しいテンプレート機能「Dynamic Templates」について

メール送信SaaSの[SendGrid](https://sendgrid.com/)から新しいテンプレート機能[**「Dynamic Templates」**](https://sendgrid.com/blog/how-to-use-sendgrids-dynamic-templates-for-your-transactional-emails/)がリリースされました！[日本語情報](https://sendgrid.kke.co.jp/)も出ると思いますが、個人的に試したことをまとめます。

サーバサイドのWeb開発経験がある方は、**「HTMLのテンプレートエンジンのメール版」**とイメージしてもらうのが一番しっくりくるのではないかと思います。

画面はこんな感じ。
![sendgrid.gif](https://qiita-image-store.s3.amazonaws.com/0/47737/6f8a74ea-f3e4-15af-5e5d-17e64cae2a60.gif)

従来のTemplatesとの違いは下図のイメージで、テンプレートの定義で色々書けるようになりました。
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/47737/f433a800-ee3e-425c-3caf-c724aafe8d23.png)

# Dynamic Templateの作成方法
## メニュー

SendGridのダッシュボードから**「Templates」**メニューを開きます。今までは**「Transactional」**と**「Marketing」**の2つのサブメニューのみ表示されていましたが、今回、真ん中に**「Legacy」**が増えました。

![2018-07-25_20h31_26.png](https://qiita-image-store.s3.amazonaws.com/0/47737/f3a4d4df-5b61-902b-4c09-c261b62c2f6c.png)

少しややこしいのですが、今まで使っていたTransactional TemplateがLegacyとなり、今回新たにリリースされた**「Dynamic Templates」**がTransactionalに該当します。

Transactionalを選ぶと以下の画面となり、パッと見**「あれっ、今まで作ったテンプレートが消えてる！？」**と一瞬焦るかもしれませんが、そこは先程の説明を思い出して**「あ、Legacyのほうにあるんだった」**と落ち着いていただければと。

![2018-07-25_20h31_58.png](https://qiita-image-store.s3.amazonaws.com/0/47737/7232fa3a-39a1-9635-7276-2935d5a88a56.png)

**「Create Template」**を押した後の流れは従来のテンプレートと全く同じです。

## エディタ

SendGridではWordやExcelのような感覚でメールを編集する**[デザインエディタ](https://sendgrid.kke.co.jp/docs/User_Manual_JP/Marketing_Campaigns/design_editor.html)**と以下キャプチャのようにHTMLを直接編集する**[コードエディタ](https://sendgrid.kke.co.jp/docs/User_Manual_JP/Marketing_Campaigns/code_editor.html)**の2種類を用意しています。どちらのエディタでもDynamic Templatesを作れます。

ここからはコードエディタを選択した例で進めていきます。
![2018-07-26_02h30_22.png](https://qiita-image-store.s3.amazonaws.com/0/47737/bcdf700e-4e02-8d59-f0eb-6c528f77601e.png)

Dynamic Templatesでは、画面の上部に**「TEST DATA」**というメニューが表示されています。

![2018-07-26_02h14_09.png](https://qiita-image-store.s3.amazonaws.com/0/47737/7294f361-ea25-a8a7-c5ff-db809ed9d4cd.png)

エディタでタグ **{{name}}** を定義してみます(下図左)。この時点での表示結果はタグのままです(下図右)。

![2018-07-25_20h37_40.png](https://qiita-image-store.s3.amazonaws.com/0/47737/2ed81a8f-d7b6-d0f6-2c44-da2a9d611df0.png)

では**「TEST DATA」**にJSONデータを入れてみましょう。

![2018-07-25_20h38_31.png](https://qiita-image-store.s3.amazonaws.com/0/47737/2dc686ed-23d8-07ce-599f-4696189e8a62.png)

名前が表示されました。

このように、エディタの定義に対して「TEST DATA」で具体的なJSONデータを指定することで、リアルタイムにレンダリング結果を確認できます。

今までのテンプレートは基本的にデザインメインのテンプレートでした。もちろん差し込みタグ(Substitution Tag)を使ってコンテンツを置き換えることはできましたが、条件分岐するような複雑なケースはアプリ側で制御する必要がありました。

それを解消して、テンプレート側で制御できるようにしたのがDynamic Templatesです。ここからは具体的な記述方法を例に紹介していきます。

## 記述方法
タグは[Handlebars.js](https://handlebarsjs.com/)のシンタックス（マスタッシュ記法）で記述します。[^1]

[^1]: ただし、Handlebarsのすべてのシンタックスに対応しているわけではないので注意が必要です。詳細はSendGridのドキュメントをご確認ください。（「We do not support full Handlebars.js functionality.」） https://sendgrid.com/docs/User_Guide/Transactional_Templates/Using_handlebars.html
### 単純な置換
さきほどの例のとおり、一番シンプルなパターンです。

HTML側でタグを定義します。

```mustache:HTML
<p>こんにちは {{name}} さん</p>
```

JSONでタグ名を属性にしてデータを渡すだけです。

```json:JSON
{"name":"白石麻衣"}
```

### オブジェクト
オブジェクトはドット(.)で属性を指定できます。バックエンドにDB取得するREST APIなどがあれば、その情報を使って簡単にパーソナライズできそうです。

```mustache:HTML
<p>こんにちは {{{nogizaka46.member.name}}} さん</p>
<p>誕生日は {{{nogizaka46.member.birthday}}} ですね</p>
```

```json:JSON
{  
   "nogizaka46":{  
      "member":{  
         "name":"白石麻衣",
         "birthday": "1998/8/20"
      }
   }
}
```

結果
![2018-07-25_20h48_00.png](https://qiita-image-store.s3.amazonaws.com/0/47737/c437f1c5-33f0-ad91-be8c-2262ba766737.png)


### イテレーション
個人的には一番嬉しい機能！繰り返し表示する項目などに使えます。

```mustache:HTML
<ol>
    {{#each nogizaka46.member}}
        <li>{{this.name}} : {{this.birthday}}</li>
    {{/each}}
</ol>
```

```json:JSON
{  
  "nogizaka46":{  
     "member":[
       {
         "name":"白石麻衣",
         "birthday": "1998/8/20"
       },
       {
         "name":"西野七瀬",
         "birthday": "1994/5/25"
       },
       {
         "name":"若月佑美",
         "birthday": "1994/6/27"
       }
     ]
   }
}
```


結果

![2018-07-26_16h17_58.png](https://qiita-image-store.s3.amazonaws.com/0/47737/14f8291d-352d-0e1b-321a-57e26e3edea6.png)

### 条件分岐
if文が書けるので、表示切替などに便利です。[SendGridのGitHubにある例は、多言語対応（英語・フランス語・スペイン語)したメール](https://github.com/sendgrid/email-templates/tree/master/dynamic-templates/different-languages)でした。

```mustache:HTML
{{#if member.profile.nogizaka46}}
  <p>乃木坂46</p>
{{else if member.profile.keyakizaka46}}
  <p>欅坂46</p>
{{else}}
  <p>けやき坂46(ひらがなけやき)</p>
{{/if}}
```

```json:JSON
{  
   "member":{  
      "profile":{  
         "nogizaka46":"true"
      }
   }
}
```

![2018-07-26_16h33_33.png](https://qiita-image-store.s3.amazonaws.com/0/47737/f9303591-934a-9855-4c2a-8bea15530ca5.png)

### HTML
ここまでのタグは中括弧が2つ( **{{ xx }}** )でしたが、これを3つ( **{{{ xx }}}** )にすると、HTMLの評価ができます。

```mustache:HTML
<p>こんにちは {{{name}}} さん</p>
```

JSONでHTMLタグを含む値を指定します。ボールドとリンクを入れてみました。

```json:JSON
{"name":"<a href='http://www.nogizaka46.com/member/detail/shiraishimai.php'><b>白石麻衣</b></a>"}
```

ちゃんと表示されますね。

![2018-07-27_02h24_15.png](https://qiita-image-store.s3.amazonaws.com/0/47737/d82f8d55-eb74-883d-1482-4f12911b510a.png)

### root

**「root」**という特殊な表現を利用することで、親オブジェクトの状態に合わせた切り替え表示が可能です。

```mustache
{{#if member.graduated}}
   <p>{{member.name}}が卒業した日は {{@root.graduateddate}}</p>
{{/if}}
```

graduatedをtrueにした場合

```json
{
  "member":{
    "name": "生駒里奈",
    "graduated": true
  }, 
  "graduateddate": "2018年5月6日"
}
```

![2018-07-27_13h46_33.png](https://qiita-image-store.s3.amazonaws.com/0/47737/eef65486-f6e6-204b-9071-3c6709f05c07.png)

graduatedをfalseにした場合

```json
{
  "member":{
    "name": "白石麻衣",
    "graduated": false
  }, 
  "graduateddate": "xxxx年x月x日"
}
```



![2018-07-27_13h47_06.png](https://qiita-image-store.s3.amazonaws.com/0/47737/52fa826f-474c-ff43-947b-3401a8143434.png)

# 送信方法
ここまでJSONの指定を画面で行ってきましたが、それはあくまでもビューの確認用でした。実際にメールを送信するときは、Web APIのパラメータで指定します。**「dynamic_template_data」**が新しく追加されたパラメータです。

柔軟性が高くて何でも差し込めるので、もはやsubjectやcontentのパラメータすら指定しなくても送れます。

```json
{
	"personalizations": [
		{
			"to": [
				{
					"email": "to@example.com"
				}
			],
			"dynamic_template_data": {
				"subject": "タイトルだよ",
				"name": "キクタロー"
			}
		}
	],
	"from": {
		"email": "from@example.com",
		"name": "キクタロー"
	},
	"template_id":"x-xxxxxxxxxxxxxxxxxxxxxxxxxxx",
}
```

# おまけ：Handlebarsについて

[Handlebars](https://handlebarsjs.com/)をメールに使う方法は、元々、[Mandrill](https://mandrill.zendesk.com/hc/en-us/articles/205582537-Using-Handlebars-for-Dynamic-Content)や[Sparkpost](https://www.sparkpost.com/features/email-templates/)が行っていて、（実際触ったことはなかったのですが）これがSendGridにあったら便利なのになぁと思っていました。

で、嬉しいことに入ってきまして、一気に柔軟性が増しました！

今後Dynamic Templatesで対応する記法が増えるかもしれないので、Handlebarsを学ぶチャンスかも。ちなみに、
Handlebarsについて調べたら、[大学の後輩で今はエンジニアをやっているsassyくんのQiitaエントリ](https://qiita.com/sassy_watson/items/f9947624876bf75a9eff)が出てきてびっくり！