LINE Bot を BotBuilder SDK は使うが Bot Connector は使わないで開発する C# 編

# 概要

LINE Bot 開発に Microsoft Bot Framework を活用して、より高度なボットを容易に開発したい。

# これまでのソリューション

以前 [Microsoft Bot Framework と LINE を連携して賢いボットを開発](https://qiita.com/kenakamu/items/1618551645d979a7a70c) で Microsoft Bot Framework を使った LINE Bot の開発を紹介しましたが、いくつか課題がありました。

- 運用コストの課題 : LINE Bot 用の Web API とコネクター用の Web API がそれぞれある
- パフォーマンスの課題 : Bot Connector 経由のため、最低でも 3 つの Web API を経由する
- Push の課題 : 外部から　LINE に Push する場合の処理が複数個所に分かれる
- 機能の課題 : Web API が分かれているため LINE 固有の機能を使いずらい

上記の課題があっても、はやり Microsoft Bot Framework で開発するメリットは多いです。

# 何故 Microsoft Bot Framework がいいのか

いくつか理由があります。

- 自分が C# 開発者だから (Node.js もあるけどね)
- BotBuilder SDK というライブラリでコンテキストを理解する、賢いボットを簡単に作れるから
- BotBuilder SDK で自然言語処理サービスとのシームレスな連携ができるから
- 豊富な C# のライブラリが使えるから
- Bot Connector を経由することで、Facebook Messenger や Slack など複数チャネルをサポートできるから

でも LINE Bot 開発者としては、最後の複数チャネルサポートはどうでもいいです。

# ではどうすればいいか (今回のソリューション)

Microsoft Bot Framework を使いたい理由は上記にあげましたが、結局 BotBuilder SDK を使いたいだけ。よって以下の実現をします。

- Web API は 1 つだけ
- BotBuilder SDK は使うが Bot Connector を経由しない。つまり DirectLine を使わない

# 実現方法

簡単に言うと、LINE から来たメッセージを BotBuilder が分かる形式に変換し、BotBuilder から返す応答を、LINE が分かる形式にすれば良いだけです。開発したソリューションは [GitHub: LINEChannelConnector](https://github.com/kenakamu/LINEChannelConnector) にあります。また LINE Messaging API 部分は [こちらのライブラリ](https://github.com/pierre3/LineMessagingApi) を使っています。

以下に実装の概要を紹介します。

## 受信側の処理

LINE から自分の WebAPI に来たメッセージは OWIN ミドルウェアを開発して自分のコードに要求が渡る前に変換します。
このミドルウェアで署名の検証や LINE の Events を BotBuilder の Activity に変換します。

コードは [LINEMiddleware.cs](https://github.com/kenakamu/LINEChannelConnector/blob/master/LINEChannelConnector/LINEMiddleware.cs) 参照
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/be2b7182-1f32-1e36-e82a-a36cc59554da.png)

## 送信側の処理

Bot に対する応答は HTTP 要求に対する応答とは別に、自分の WebAPI から別途送り出すことになるため、OWIN ミドルウェアでの対処はできません。そこで BotBuilder の IConversation  を継承したクラスを作成して利用することで、送信の直前にデータを変換する仕組みを入れます。

コードは [LINEConversation.cs](https://github.com/kenakamu/LINEChannelConnector/blob/master/LINEChannelConnector/LINEConversation.cs) 参照
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/8ffe333d-c2d5-c38c-e853-0382dba2f010.png)

# 利用方法

そのうち Visual Studio 用のテンプレートを作るかもしれませんが、サンプルは以下にあります。あまり考えずにとりあえずこちら実行で OK です。

[GitHub: LINE Channel Connector Test Web アプリ](https://github.com/kenakamu/LINEChannelConnector/tree/master/LineChannelConnectorTest)

### OWIN ミドルウェアの指定

Startup.cs に通常の OWIN ミドルウェア同様に差し込みます。ここで自身の Bot のチャネルシークレットやトークンを渡します。値は Web.Config を変更してください。また以下のサンプルではローカルシミュレータを使う想定となっているため、lineConfig.Uri に値を別途渡しています。シミュレーターについては [ボット開発用 LINE クライアントシミュレーターで開発スピードを上げる](https://qiita.com/kenakamu/items/70555a055bdae99867b5) を参照してください。

```csharp
public void Configuration(IAppBuilder app)
{
    RegisterInMemoryBotStore();
    var lineConfig = new LINEConfig()
    {
        ChannelAccessToken = ConfigurationManager.AppSettings["ChannelAccessToken"].ToString(),
        ChannelSecret = ConfigurationManager.AppSettings["ChannelAccessSecret"].ToString()
    };

#if DEBUG
     lineConfig.Uri = ConfigurationManager.AppSettings["Uri"].ToString();
#endif

    app.UseLINEChannel(config: lineConfig);
    app.UseWebApi(configuration);
    WebApiConfig.Register(configuration);
}
```


### カスタム IConversation の利用

OWIN ミドルウェアの利用時に設定しているため、特にやることはありません。
コードは [LINEMiddlewareConfig.cs](https://github.com/kenakamu/LINEChannelConnector/blob/master/LINEChannelConnector/LINEMiddlewareConfig.cs) を参照。

# 動作を変えたい場合

## 受信方向の変換

受信した LINE Events から BotBuilder Activity の変換は LINEClient.cs の ConvertToActivity メソッドで行っています。必要に応じて変更してください。
[LINEClient.cs - ConvertToActivity メソッド](https://github.com/kenakamu/LINEChannelConnector/blob/68aa11330f506be120d0c5127ef25e661c9006c7/LINEChannelConnector/LINEClient.cs#L420)

## 送信方向の変換

BotBuilder Activity から LINE ISendMessage への変換は ConvertToLineMessages メソッドで行っています。
[LINEClient.cs - ConvertToLineMessages メソッド](https://github.com/kenakamu/LINEChannelConnector/blob/68aa11330f506be120d0c5127ef25e661c9006c7/LINEChannelConnector/LINEClient.cs#L104)


# 今後の予定

ある程度コードが固まったら Visual Studio テンプレートを作る予定です。

フィードバックお待ちしています。

# 参考
[C# SDK for LINE Messaging API](https://github.com/pierre3/LineMessagingApi)
[LINEChannelConnector](https://github.com/kenakamu/LINEChannelConnector/)
[ボット開発用 LINE クライアントシミュレーターで開発スピードを上げる](https://qiita.com/kenakamu/items/70555a055bdae99867b5)