Azure Bot Serviceのzip デプロイで日本語メッセージが正しく使用できない問題への対処

# TL;DR

- [Azure Bot Serviceのチュートリアル](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-tutorial-basic-deploy?view=azure-bot-service-4.0&tabs=csharp)では、Azure Bot Serviceのzip デプロイを利用したコマンドラインでのデプロイが示されています。しかし、Botから返却されるメッセージに日本語を使用、かつDebugビルドしていた場合に正しく処理されない場合があります。
    - デプロイできない
    - 日本語が文字化けする。
- 対処
    - Zip Deploy前にReleaseビルドする
    - Visual Studioから発行（既定がReleaseビルドであるため）

# 環境

- Visual Studio: 2019 Community 16.4.0
- Azure CLI: azure-cli-2.0.78

# 発行の基本的な手順

[チュートリアル:基本的なボットを作成してデプロイする](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-tutorial-basic-deploy?view=azure-bot-service-4.0&tabs=csharp)や、[ボットをデプロイする](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-tutorial-basic-deploy?view=azure-bot-service-4.0&tabs=csharp#deploy-your-bot)に示されているように、デプロイの基本的な手順は以下となっています。

1. Azure にログインする

    ```
    az login
    ```

2. Azure ADにアプリを登録する

    ```
    az ad app create --display-name "<Azure AD Applicationの表示名>" --password "<任意のパスワード>" --available-to-other-tenants
    ```

3. テンプレートを使用してデプロイする

    ```
    az deployment create --name "<新規作成するデプロイの名称>" --template-file "<template-with-new-rg.jsonのファイルパス>" --location "<デプロイを作成する場所（japaneast 等）>" --parameters appId="<2. で登録したアプリのApp-ID>" appSecret="<2. で登録したパスワード>" botId="新規作成するBotの名称" botSku=F0 newAppServicePlanName="<新規作成するサービスプランの名称>" newWebAppName="<新規作成するWebアプリの名称>" groupName="<新規作成するリソースグループの名称>" groupLocation="<リソースグループを作成する場所>" newAppServicePlanLocation="<サービスプランを作成する場所>"
    ```

4. 必要な IIS/Kudu ファイルを取得または作成

    ```
    az bot prepare-deploy --lang Csharp --code-dir "." --proj-file-path "<対象の .csproj ファイルのパス>"
    ```

5. ビルドする

6. コード ディレクトリを手動で zip 圧縮する

7. コードを Azure にデプロイする

    ```
    az webapp deployment source config-zip --resource-group "<3. で作成したリソースグループ名>" --name "<3. で作成したWebアプリ名>" --src "code.zip"
    ```


# 問題

問題は、Botから返すメッセージに日本語を使用した場合、かつDebugでビルドした場合に発生します。

## 問題1：デプロイできない

### コード

```cs:EchoBot.cs
        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in membersAdded)
            {
                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    await turnContext.SendActivityAsync(CreateActivityWithTextAndSpeak($"いらっしゃいませ。テストボットです。"), cancellationToken);
                }
            }
        }
```


### 事象

発行の基本的な手順の「7.」で以下のようなエラーが発生し、デプロイできません。（IDなどはマスクしています。）

```
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
Configuring default logging for the app, if not already enabled
Zip deployment failed. {'id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', 'status': 3, 'status_text': '', 'author_email': 'N/A', 'author': 'N/A', 'deployer': 'Push-Deployer', 'message': 'Created via a push deployment', 'progress': '', 'received_time': '2020-01-02T11:29:44.7315577Z', 'start_time': '2020-01-02T11:29:45.0816714Z', 'end_time': '2020-01-02T11:30:39.1000054Z', 'last_success_end_time': None, 'complete': True, 'active': False, 'is_temp': False, 'is_readonly': True, 'url': 'https://<name-of-web-app>.scm.azurewebsites.net/api/deployments/latest', 'log_url': 'https://<name-of-web-app>.scm.azurewebsites.net/api/deployments/latest/log', 'site_name': '<name-of-web-app>', 'provisioningState': None}. Please run the command az webapp log tail
```

## 問題2：文字化けする

### コード

```cs:EchoBot.cs
        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in membersAdded)
            {
                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    await turnContext.SendActivityAsync(CreateActivityWithTextAndSpeak($"こんにちは"), cancellationToken);
                }
            }
        }
```


### 事象

デプロイはできますが、実際に使用すると以下のように文字化けします。

また、ローカルでのテスト（Bot Emulatorを使用）では問題ないところが気づきにくいところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/7fc5195c-8e6a-8c37-122f-da771dcd12b2.png)

# 対処

[ここ](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-deploy-az-cli?view=azure-bot-service-4.0&tabs=csharp#52-zip-up-the-code-directory-manually)に記載があるように、Zip DeployではビルドおよびZip圧縮は手作業で行う必要があります。

> デプロイ中に npm install、dotnet restore/dotnet publish などの追加ビルド ステップが不要であることを既定で想定しています。

記載はありませんが、上記の記述、およびVisual Studioでの発行ではReleaseビルドされることから考えても、Releaseビルドしておくことが前提と思われます。


## 対処1：Zip Deploy前にReleaseビルドする

手順「6.」つまり、Zip Deploy前のビルドでReleaseビルドを行います。

## 対処2：Visual Studioから発行します

既定がReleaseビルドであるため、問題なく成功します。