Azure ファンクションと C# によるクロスプラットフォーム LINE Bot 開発

サーバーレスやボットなどのキーワードがバズってますが、台湾や韓国、日本などアジアでボットというと LINE を思い浮かべる方が多いのではないでしょうか。

この記事では LINE ボットをマイクロソフトのサーバーレスサービスである Azure ファンクションで実装する方法を紹介します。また Azure ファンクションはクロスプラットフォームで開発できるので、Windows でも Mac でも Linux でも開発できるのが魅力です。

# 前提条件
>
- 好きな OS。この記事では Windows を使います。
- [LINE 開発者アカウント](https://developers.line.me/ja/)
- [Azure サブスクリプション](https://azure.microsoft.com/en-us/free/) 無い場合は無料体験を。
- [Visual Studio Code](https://code.visualstudio.com)
- [dotnet core ライブラリ](https://www.microsoft.com/net/learn/get-started/windows") Mac や Linux 用はリンクから左にあるダウンロードを選択。
- [Node.js](https://nodejs.org/en/)
- [Git](https://git-scm.com/) IDE と一緒にインストールされることが多いですが、必要な個別で。
- [ngrok](https://ngrok.com/)

<span style="color: #0000ff"><u><strong>LINE のセットアップ</strong></u></span>

既に LINE ボットアプリ作ったことある場合はスキップしてください。

1\. https://developers.line.me/ja/ で LINE 開発者アカウントを作成。

2\. "Messaging API(ボット)をはじめる” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image248.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb238.png" border="0" /></a>

3\. 既にプロバイダーがあれば選択、無ければプラスアイコンをクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image249.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb239.png" border="0" /></a>

4\. プロバイダー作る場合は名前を入力して、[追加] をクリック。その後、次のページをクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image250.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb240.png" border="0" /></a>

5\. アプリアイコンや名前、説明を指定。名前に ”LINE" と入れると失敗する模様。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image251.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb241.png" border="0" /></a>

6\. プランは"Developer Trial” を選択。業種は任意で選択し、メールアドレスを入力して ”確認” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image252.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb242.png" border="0" /></a>

7\. 利用規約に (自己責任で) 同意して、”作成” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image253.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb243.png" border="0" /></a>

8\. 画面が切り替わるので、"設定が完了していません” をクリックします。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image254.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb244.png" border="0" /></a>

9\. 構成ページに移動するので、メッセージ送受信設定を確認。アクセストークンで ”再発行” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image255.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb245.png" border="0" /></a>

10\. "再発行” をクリック。0 時間後を選択すると失効しない。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image256.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb246.png" border="0" /></a>

11\. "Webhook 送信” と "Bot のグループトーク参加” を有効に設定。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image257.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb247.png" border="0" /></a>

12\. "LINE@機能の利用” で "自動応答メッセージ” と "友だち追加時のあいさつ” を利用しないに設定します。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image258.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb248.png" border="0" /></a>

13\. 最後に一番下にある QR コードを LINE アプリケーションで読み取ってボットを追加します。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/IMG_1955.png"><img title="IMG_1955" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="IMG_1955" src="https://msdnshared.blob.core.windows.net/media/2017/12/IMG_1955_thumb.png" border="0" /></a>

まずはここまで。構成画面は開いておいてください。

# Azure の準備

1\. Azure ポータルにログイン https://portal.azure.com

2\. 作成するリソースをまとめるため、リソースグループを作ります。メニューより ”リソースグループ” を選択。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image259.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb249.png" border="0" /></a>

3\. ”追加” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image260.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb250.png" border="0" /></a>

4\. 名前とリージョンを選択して、作成。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image261.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb251.png" border="0" /></a>

5\. 作成が完了したら、リストを更新して作成したリソースグループを選択。

6\. ”追加” をクリックしてモジュールを追加。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image262.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb252.png" border="0" /></a>

7\. "function” で検索して、 Function App を選択。右側にブレードが開くので、”作成” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image263.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb253.png" border="0" /></a>

8\. 必須項目を埋めて作成。またストレージも自動作成を選択。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image264.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb254.png" border="0" /></a>

9\. 作成が完了したらリソースグループの画面から追加されたリソースを確認。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image265.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb255.png" border="0" /></a>

Azure の準備はこれで一旦終了。画面は開いておいてください。

# Azure Functions アプリのランタイムインストール

Azure ファンクションのランタイムとツールをインストールします。

1\. コマンドプロンプトかターミナルを開く。

2\. 以下のコマンドを実行してツールをインストール。

```shell
npm i -g azure-functions-core-tools@core
```
Mac の場合は sudo で実行。

```shell
sudo npm i -g azure-functions-core-tools@core --unsafe-perm
```

3\. func コマンドを実行してインストールできているか確認。
<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image266.png"><span style="color: #0000ff"><strong>
<img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb256.png" border="0" /></strong></span></a>

# Bot アプリケーションのコード

Azure Function 用のテンプレートは yeoman を使って作成できます。まず yeoman とジェネレーターをインストールします。

1\. コマンドプロンプトやターミナルで以下のコマンドを実行して yeoman をインストール

```shell
npm i -g yo
```

2\. 以下のコマンドで LINE ボット用のジェネレーターをインストール

```shell
npm i -g generator-line-bot
```

3\. フォルダを作成。作成したフォルダに移動。

4\. 以下のコマンドで C# Azure ファンクションのプロジェクトを作成。

```shell
yo line-bot mybot --csharp --function
```

5\. Channel Secret と Channel Access Token を聞かれるので、LINE 開発者ポータルより値をコピーして貼り付け。
※通常このキーは大事なものですので、外部には公開しないでください。ここで表示したものはブログ公開時には既に変更済です。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image267.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb257.png" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image268.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb258.png" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image269.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb259.png" border="0" /></a>

6\. mybot フォルダに移動して、code . でフォルダを Visual Studio Code で開く。

7\. Azure ポータルに戻り、ストレージアカウントを開く。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image270.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb260.png" border="0" /></a>

8\. ”アクセスキー” を選択。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image271.png"><img width="266" height="390" title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb261.png" border="0" /></a>

9\. ”接続文字列” のいずれかをコピー。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image272.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb262.png" border="0" /></a>

10\. local.settings.json の"AzureWebJobsStorage” に値を張り付け。LINE の設定は自動で入っていることを確認。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image273.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb263.png" border="0" /></a>

11\. "表示” メニューより "統合ターミナル” を起動。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image274.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb264.png" border="0" /></a>

12\. ''dotnet restore” コマンドで依存関係をダウンロード。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image275.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb265.png" border="0" /></a>

13\. "dotnet build” でコンパイルを実行。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image276.png"><img  title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb266.png" border="0" /></a>

14\. 全てのロジックは LineBotApp.cs  にあるので必要に応じて編集。

# ローカルでのテスト

まずローカルで検証します。そのためには ngrok で LINE プラットフォームからのリクエストをローカルにフォワード出来るようにします。

1\. コマンドプロンプトやターミナルを開いて、nrgok のインストールパスに移動。PATH を設定済みの場合はスキップ。

2\. 以下のコマンドを実行してローカルポート 7071 を指定。ポート 7071 はファンクションアプリの既定ポート

```shell
ngrok.exe http --host-header=localhost:7071 7071
```

3\. 結果の画面で ngrok サーバーのアドレスを確認。以下の場合は "0677b5d8.ngrok.io”

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image277.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb267.png" border="0" /></a>

4\. LINE 開発者ポータルに戻って ”Webhook URL" を更新 "/api/linebot” を最後につける。このアドレスでアプリが待ち受け。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image278.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb268.png" border="0" /></a>

5\. 準備が整ったので、Visual Studio Code の統合ターミナルで /bin/Debug/netstandard2.0 に移動。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image279.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb269.png" border="0" /></a>

6\. 以下のコマンドでアプリを実行。

```shell
func host start
```

7\. 結果として以下のように緑で待ち受けアドレスが出ていれば起動は完了。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image280.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb270.png" border="0" /></a>

8\. コードにアタッチするため、F5 キーを押下。リストより dotnet.exe を選択。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image281.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb271.png" border="0" /></a>

これで準備は完了です。

# デバッグ実行

1\. LINE アプリケーションより ”こんにちは” と送信。返信が来ることを確認。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/IMG_1956.png"><img title="IMG_1956" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="IMG_1956" src="https://msdnshared.blob.core.windows.net/media/2017/12/IMG_1956_thumb.png" border="0" /></a>

2\. 次に任意の場所にブレークポイントを設定。ここでは run.cs の Run メソッドに設定。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image66.png"><img title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb64.png" border="0" /></a>

3\. LINE クライアントよりメッセージを送ってデバッグできることを確認。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image67.png"><img title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb65.png" border="0" /></a>

# アプリケーションの発行

最後に開発したアプリケーションを Azure に公開します。

1\. Visual Studio Code でデバッグツールバーより切断ボタンをクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image282.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb272.png" border="0" /></a>

2\. 統合コンソールよりファンクションアプリの実行画面を選択して、Ctrl+C を押下してファンクションアプリを停止。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image283.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb273.png" border="0" /></a>

3\. 以下のコマンドを実行して Azure にログイン。

```shell
func azure login
```

4\. 指示に従ってログインを完了。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image284.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb274.png" border="0" /></a>

5\. 指定された URL を開いてコードを張り付け、”続行” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image285.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb275.png" border="0" /></a>

6\. ログインが完了したら以下コマンドでアプリを発行。publish の後にはファンクションアプリの名前を指定。

```shell
func azure functionapp publish lineserverlessbotja -i -y
```

7\. 発行が完了したら Azure ポータルに移動して、ファンクションアプリを開く。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image286.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb276.png" border="0" /></a>

8\. "アプリケーション設定” をクリック。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image287.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb277.png" border="0" /></a>

9\. LINE のチャネルトークンなどの変数が存在することを確認。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image288.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb278.png" border="0" /></a>

10\. 画面上部の ”概要” より "Function App の設定” を開き、”ランタイム バージョン” で "beta” を選択。これで v2 の機能が利用可能。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image289.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb279.png" border="0" /></a>

11\. LINEBOT を左のペインから選択。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image290.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb280.png" border="0" /></a>

12\. 右上にある "関数のURL の取得” をクリックして URL をコピー

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image291.png"><img  title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb281.png" border="0" /></a>

13\. LINE 開発者ポータルより Webhook URL を更新。

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/image292.png"><img title="image" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/12/image_thumb282.png" border="0" /></a>

公開はこれで完了です。LINE クライアントより動作を確認。

# まとめ

少し手順が長くなりましたが上手くいったでしょうか？次回は LINE ボット開発に使えるシミュレーターについて紹介します。

中村 憲一郎