XamarinアプリからAzure Mobile Apps経由でSendGridを利用する

この記事は「[Xamarin(その2) Advent Calendar 2016](http://qiita.com/advent-calendar/2016/xamarin2)」と「[SendGrid Advent Calendar 2016](http://qiita.com/advent-calendar/2016/sendgrid)」の19日目の記事です。

昨日は
Xamarin:@MasaakiYoshidaさんの[「Xamarin Test Recoderを触ってみた」](http://qiita.com/MasaakiYoshida/items/438ea41742326c693392)
SendGrid:@tmtyskさんの[「HerokuアドオンなSendGridを独自ドメインで使用するまでの3ステップ」](http://qiita.com/tmtysk/items/74e641864b095c6f89ee)
でした。

当初はXamarinとSendGridでそれぞれ別々のネタにするつもりだったのですが、色々と調べている中でUS Microsoft @JamesMontemagnoさんの**[Xamarin and Azure Mobile Services Challenge](https://github.com/jamesmontemagno/AzureXamarinVSChallenge)**なるものをみつけて、この中でSendGridが利用されていました。

![1.JPG](https://qiita-image-store.s3.amazonaws.com/0/47737/1468d8a3-d2dd-1fd3-dd38-f02cd6a5555c.jpeg)

**「おぉ！XamarinとSendGridを~~1つのAdventで済ませられる~~Mobile Appで繋いだ形の記事が書けそう！！」**と思って、1つのネタに統合させていただきました。元の記事は3年前くらいのものなので、画面キャプチャなど細かい情報を含めて最新の流れを書きたいと思います。内容的には簡単なチュートリアルもので初心者向けとなりますが、SendGridをご存知ない方、使ったことない方はそこの部分だけでも是非みていただければ嬉しいです。

ちなみに、このチャレンジって何かのイベントだったのですかね。CompleteしたらMobile ServicesのTシャツとかもらえたようです。こういうチャレンジイベントも面白そうです！

# 環境
必要となるのは次の3つです。SendGridのアカウントはAzureから取得します[^1]。

[^1]: 日本国内代理店の[構造計画研究所](https://sendgrid.kke.co.jp/)からアカウントを取得することもできます。こちらは審査があるためAzureに比べると準備に少し時間がかかります。

- Microsoft Azureのアカウント[^2]
- Xamarinの開発環境[^3]
- SendGridのアカウント

[^2]: 本記事はサブスクリプション Visual Studio Professional with MSDNを利用
[^3]: 本記事はVisual Studio Professional 2015を利用

Xamarin StudioやVisual Studio for Macは未確認ですが、多分同じことができると思います。

# Azure Mobile Appでアプリを作成
Azureにログイン後、まずは「Mobile App」を選択します。
![2016-12-16_18h18_45_0.png](https://qiita-image-store.s3.amazonaws.com/0/47737/584c680e-4934-bd57-5309-61254d90146a.png)

アプリの必要情報を入力します。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/47737/e3dcca73-dc85-40f7-c38a-1bb5de70a457.png)

「クイックスタート」->「Xamarin.Forms」を選択し、3ステップのうちの1つ目「Connect a database」を選択し、データべース環境を作成します。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/47737/19b1e669-ea6b-a76e-f0f4-9923f5757d63.png)

データベースおよびデータベースサーバを作成します。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/47737/7874c884-fd56-2a09-5046-5cd27381745d.png)

接続文字列も設定しました。
![6.png](https://qiita-image-store.s3.amazonaws.com/0/47737/11cb0352-dfd6-77cc-22c8-2336bfc1bee5.png)

1の「Connect a database」が完了状態となればOKです。
<img width="400" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/e56addeb-de67-0f3d-d20b-b4e3845509f4.png">

続いて2の「Create a table API」でテーブルのAPIを作成します。今回はNode.jsを選択して「Create TodoItem table」を実行します。
<img width="400" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/8aae2f8c-4b06-21cb-0fb1-32765a0f7c2d.png">

テーブルが作成できたら、3の「Configure your client application」で「新しいアプリの作成」で「ダウンロード」
<img width="400" alt="9.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/f5d841f1-67ca-acef-3a4d-8b0f2cbf3e07.png">

zipファイルがダウンロードされました
![10.png](https://qiita-image-store.s3.amazonaws.com/0/47737/d8de1fda-2d59-9b1b-a27f-492d7693f33e.png)

# Xamarinアプリのセットアップ

zipを解凍します。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/47737/236c50c0-35a1-e423-7419-daf55a0d087d.png)

Visual Studioでソリューションファイルを開きます。
<img width="250" alt="12.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/3eaf8b8e-cc12-3dec-8f07-01355b64408b.png">

packages.configはこんな感じでした。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/47737/15dfef07-ef18-db2b-cac0-5931ece9d23b.png)

ダウンロードされたソリューションのXamarin.Formsは2.0.1.6495だったので、最新の安定版(2.3.3.175)に更新、その他、Newtonsoft.Jsonなども同様に更新していきます。

「ソリューションのNugetパッケージの管理」を選択します。
<img width="400" alt="14.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/66140b24-a018-856c-3480-c3943c08692e.png">

更新プログラムでXamarin.Formsにチェック入れてインストールします。その他も更新してよいかと（今回はしなかったのですが）
![15.png](https://qiita-image-store.s3.amazonaws.com/0/47737/f810e63d-5b8e-0704-b08d-edef71da1f50.png)

あとはビルドして実行するだけです。

# Xamarinアプリの実行確認

実行すると次のような画面が表示されます。
![16.png](https://qiita-image-store.s3.amazonaws.com/0/47737/b4b16900-a378-24de-3250-e501c04ce453.png)

>余談ですが、最近AndroidエミュレータをVisual Studio Emulator for AndroidからAndroid SDK付属エミュレータ(HAXM対応)に変えました。以下、自分もとても助かった情報にて、Twitter引用させていただきます。

><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/tsubakimoto_s">@tsubakimoto_s</a> VS標準のエミュはHyper-V必須ですが、エミュは別にVSのものを使う必要はありません。Android SDK付属のHAXM対応エミュが早いしエミュレーション精度高いしGoogle Play Serviceがデフォで支えてお勧めです</p>&mdash; nuits.jp (@nuits_jp) <a href="https://twitter.com/nuits_jp/status/806106961141895168">2016年12月6日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/tsubakimoto_s">@tsubakimoto_s</a> どうぞ→ Xamarin でも使える高速 Android エミュレータを簡単に作る方法(Windows編) - Qiita <a href="https://t.co/DBSzQtAA6v">https://t.co/DBSzQtAA6v</a>  <a href="https://twitter.com/nuits_jp">@nuits_jp</a></p>&mdash; これがあめいの選択だよ (@amay077) <a href="https://twitter.com/amay077/status/806108485754572804">2016年12月6日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

>仕事でVagrant使った環境が必要にて、Hyper-Vを外せず…と悩んでた所でした。個人的にはSNS上でこういう手厚いサポートがあるのがXamarinすごいなーと思う1つでもあります(SNSだけじゃなく、[teratail](https://teratail.com/)の回答率の高さとか、勉強会なども含めて)。

本題に戻って、Todoを登録してみます。
<img width="300" alt="17.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/17fbbd3f-b6c2-35b9-d95b-522ae7ada7bb.png">

テーブルの中身はAzureからも確認できます。
![18.png](https://qiita-image-store.s3.amazonaws.com/0/47737/04638a8d-7529-9be5-be60-b44540434444.png)

便利ですね。
![19.png](https://qiita-image-store.s3.amazonaws.com/0/47737/64da02fd-8e6f-f939-84d5-981f8a524f20.png)

Todoをクリックするとダイアログが表示されます。長押しするとタスクが完了になるとのこと。
<img width="300" alt="20.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/147d1e5b-5864-908d-fa35-47bf9ef11398.png">

乃木坂クリスマスライブ（通称クリライ）はアリーナ席で前から5列目という二度とない席で堪能したので、長押ししてタスクを完了します。
<img width="300" alt="21.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/b2f65e0e-b159-3f15-3d8e-74e802c8b629.png">

タスクが完了となって消えました。(Azureでみると論理削除っぽい)
<img width="300" alt="22.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/c052f924-6059-a3ce-cba9-8c1f8f914dd8.png">

# SendGridの準備

Mobile AppとXamarinの連携でTodoアプリの動作まで確認できました。**[Xamarin and Azure Mobile Services Challenge](https://github.com/jamesmontemagno/AzureXamarinVSChallenge)**では、このアプリをベースに、Todoを登録した際、SendGridを利用してメール送信する機能を実装しています。

SendGridを既にご利用の方はAPI Key（またはID/Password)で実行できます。はじめてご利用される方は以下の手順でAzureからSendGridの準備ができます。

![23.png](https://qiita-image-store.s3.amazonaws.com/0/47737/19ae9bfe-0999-9775-2eb0-c41785b38e3f.png)

Freeプランで機能的にはほぼ有償プランと同じ（サブユーザ機能や固定IPアドレスが利用できない）で、1カ月25,000通までのメールを送ることができます。
![24.png](https://qiita-image-store.s3.amazonaws.com/0/47737/da7408a9-8b28-a068-bbcd-529a436234b2.png)

デプロイを待ちます。
![25.png](https://qiita-image-store.s3.amazonaws.com/0/47737/43112362-49c8-e63e-6300-ab1f3ddd5bd5.png)

デプロイされたら「Manage」メニューでSendGridの管理コンソールを開きます。
<img width="400" alt="26.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/5552ce3b-a400-b52f-f90d-73f89467e292.png">

管理コンソールを開くと、次のダイアログが表示されます。認証用のメールアドレスを入力して「Send Confirmation Emali」ボタンを押します。
<img width="500" alt="27.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/3d4fd3dd-1d3f-d0af-b03f-ffefe7217ac0.png">

<img width="500" alt="28.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/aa773719-5164-eb02-b26b-e9c7e0bb459e.png">

メールが届いていることを確認して、「Confirm Email Address」ボタンで認証します。
<img width="500" alt="29.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/d62520d9-db36-987b-c1e3-0d2d4be831c8.png">

認証が完了すると管理コンソールが表示されます。メール送信をしていくと、このダッシュボートで送信数などがグラフで確認できます。
![30.png](https://qiita-image-store.s3.amazonaws.com/0/47737/440cdca4-e61d-6b5c-60bb-d1d1c8a4b88a.png)

[元ネタ](https://github.com/jamesmontemagno/AzureXamarinVSChallenge)ではSendGridのAPIを利用する際、ユーザIDとパスワードを利用していますが、現在はAPI Keyを利用するほうが便利かつセキュアです。

>APIキー認証でセキュリティを強化しよう | SendGridブログ
>https://sendgrid.kke.co.jp/blog/?p=3659

メニューの「Setting」->「API Keys」を選択します。
<img width="100" alt="31.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/070039cd-580d-19b1-8716-79efc0c036eb.png">

「Create API Key」の「General API Key」を選びます。
![32.png](https://qiita-image-store.s3.amazonaws.com/0/47737/19754383-0fcc-2a93-fc3b-f5865894b0cd.png)

続けてAPI Keyのアクセス権限設定ですが、とりあえず今回はすべて「FULL ACCESS」とします。
<img width="400" alt="33.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/7cdb0836-97ec-e822-9d82-93e71c1d6cf0.png">

API Keyが発行されました。このKeyは一回きりしか表示されないので必ずコピーするようにしてください。
![34.png](https://qiita-image-store.s3.amazonaws.com/0/47737/57f80f68-19bb-71e2-e69e-7a26494e2ab5.png)

本来であれば、Domain Whitelabelを設定するなどしたほうが良いのですが、とりあえず今回はこのままにしてメール送信してみます。

# SendGridのAPIによるメール送信

今回、バックエンドはNode.jsを選んだので、メール送信はSendGridのNode.jsライブラリを利用します。App Serviceのコンソールからnpmでインストールします。

```bash:SendGridのNode.jsライブラリインストール
npm install sendgrid
```

![37.png](https://qiita-image-store.s3.amazonaws.com/0/47737/d040a84b-b98f-cb91-d3a4-f802085b8b19.png)

テーブルのレコード一覧の上にある「Edit script」をクリックすると、App Service Editorが起動します。
![35.png](https://qiita-image-store.s3.amazonaws.com/0/47737/e615c070-1435-3b97-413f-b41b3aca3214.png)

**[Xamarin and Azure Mobile Services Challenge](https://github.com/jamesmontemagno/AzureXamarinVSChallenge)**と同様にレコードのinsertをトリガーにメールを送るようにしてみます。

![38.png](https://qiita-image-store.s3.amazonaws.com/0/47737/58e5af6a-4b18-7d0d-dade-ce0c3dc1026a.png)

こんな感じでsendEmail()を入れてみました。

```js:TodoItem.js
// CREATE - add or overwrite the userId based on the authenticated user
table.insert(function (context) {
	sendEmail();
	return context.execute();
});

function sendEmail() {
    var helper = require('sendgrid').mail;
    var from_email = new helper.Email('kikutaro@kikutaro.xyz');
    var to_email = new helper.Email('宛先メールアドレス');
    var subject = 'Hello World from the Mobile Apps and SendGrid triggered by Xamarin!';
    var content = new helper.Content('text/plain', 'Xamarinはいいぞ! SendGridもいいぞ!');
    var mail = new helper.Mail(from_email, subject, to_email, content);
    
    var sg = require('sendgrid')('ここにAPI Keyをペースト');
    var request = sg.emptyRequest({
        method: 'POST',
        path: '/v3/mail/send',
        body: mail.toJSON(),
        });
        
    sg.API(request, function(error, response) {
        console.log(response.statusCode);
        console.log(response.body);
        console.log(response.headers);
    });
}
```

Node.js、今回はじめて触ったのですが、Azure上でこうやって簡単に編集できるので楽ですね。なお、SendGridのNode.jsライブラリは[GitHubで公開](https://github.com/sendgrid/sendgrid-nodejs)されています。

で、再びXamarinに戻って、アプリからTodoを追加します。
<img width="300" alt="39.png" src="https://qiita-image-store.s3.amazonaws.com/0/47737/18d6ff63-1762-a16e-35e2-d9f0314f73aa.png">

メールをチェックしてみると…届いてる！
![36.png](https://qiita-image-store.s3.amazonaws.com/0/47737/f04ab28e-21da-cb9f-f930-7e385a283af5.png)

手軽で簡単ですね。今回のサンプルはTodoアプリですが、何らかのWeb経由で会員登録するようなアプリであれば会員登録完了メールを送るなどが簡単にできます。

なお、発信元が「sendgrid.me」となっているのは、Whitelabelを設定していないためです。この辺りはちょうど[昨日](http://qiita.com/tmtysk/items/74e641864b095c6f89ee)、[一昨日](http://qiita.com/nakansuke/items/bd9988206987cc46bdd2)の[SendGrid Advent Calendar 2016](http://qiita.com/advent-calendar/2016/sendgrid)でも設定方法などが触れられているので、是非参考にしてください。個人でお名前.comのドメインなどお持ちの方は是非設定してみてください！

# おわりに

今回、細かいキャプチャを貼ったためボリュームがあるようにみえますが、実際には30分もかからない（参照元の**[Xamarin and Azure Mobile Services Challenge](https://github.com/jamesmontemagno/AzureXamarinVSChallenge)**みると15分らしいｗ）ので、是非Xamarinはじめて、という方も試してほしいなぁと思います！

所々に「**乃木坂46**」のキーワードを出してましたが、Xamarinで作ったAndroidアプリ[「坂道コレクション」](https://play.google.com/store/apps/details?id=com.sakamichi46.Sakamichi46Mobile)がもうすぐ10,000ダウンロードになります！！

今年の8月リリースで、グラフにすると見事に坂となっており、乃木坂46、欅坂46の人気ととも坂道を駆け上がっている感じが（勝手ながら）しています！

![no.JPG](https://qiita-image-store.s3.amazonaws.com/0/47737/262cb918-d4b5-f7ad-ab4f-92a99e1a0974.jpeg)

このアプリはXamarin Formsで作っているので、Macを買ってiPhone版もリリースしたいなぁと思ってます。Windows Phoneもですが(^^;

**JXUGC #17 お前の Xamarin アプリを見せてみろ！でのLT発表資料**
[Xamarin meets 乃木坂46 & 欅坂46](https://speakerdeck.com/kikutaro/xamarin-meets-nai-mu-ban-46-and-ju-ban-46)

---