最近(2019/4ごろ) Azure Bot Service でチャットボットを作成してソースをダウンロードし、デバッグしても動かないということがあったのでちょっと調べてみました。
このエラーの対処もまた色々な変更ですぐに対処方法が変わるでしょうけど、メモしておきます。
エラーメモの前に、何が変わったかですが....
ダウンロードしたソースを Visual Studio で開くとすぐ気づきますが、Bot Framework の SDK のバージョンが V4.3.2になっていて、なんということでしょう、以前(v4.0.7~v4.2.2)からプロジェクトの構成が劇的ビフォーアフターです。
いくつかピックアップすると、
- .botファイルなくなった
- Controller が以前のように復活
Startup.cs
でやってることが変わった(以前は拡張メソッドでRoutingしてたので不要になりましたね)- v4.3 で ActivityHandler class 爆誕!!!!
- 以前は
IBot
インターフェースを継承したクラスのOnTurnAsync
メソッドが実行されていましたが、このバージョンからは、ActivityHandler
クラス(こいつはIBot
を実装してるけど)のOnMessageActivityAsync
メソッドが呼ばれるようになった - 以前の環境変数 "appId" / "appPassword" の名称かわった: MicrosoftAppId" / "MicrosoftAppPassword"
とかです。
ちなみに Visual Studio の拡張機能でインストールできる Bot Builder V4 SDK Template はまだ V4.2.2 なので、VSからプロジェクトを作成しても以前と変わりないです。
結論: 正常に動作させるには
SDK V4.3.2になってから、Bot Service で生成されるソースコードには、appsettings.json に MicrosoftAppId/MicrosoftAppPassword が書かれているので、このままデバッグすると、この関連で死にます。
解決策として、値を空にしましょう。
そうすると、Azure Bot Service へデプロイ時に動かなくなりそうですが、Azure Bot Service の AppsSettings には既に値がされているので問題ないです。
この方法以外にも、エミュレーター起動時に bot ファイル作って MicrosoftAppId/MicrosoftAppPassword をからに設定すればいけるのかな?
また、詳しく見てないんですが、csproj にもゴミが多いような?
考察
Web.config の謎
比較的どうでもよいことで気になったのは、
ダウンロードしてすぐに気になったのは、web.config
ファイルがあること。中を見てみると、arguments...???
ASP.NET Core 的にとりあえずデバッグするには不要なので、ディレクトリからどけました。
デバッグして Emulator からアクセスするとInternal Server Error
結論と解決方法は先に書いてしまいましたが、エラーについてちょっと書きます。
とりあえずデバッグして Emulator からアクセスすると、500(Internal Server Error)になりました。
Emulator からもエラーの内容は見れますが、見難いので Controller で try catch
してみてみます(というか最初からそうしてた...)。
Errorは、
Attempted to perform an unauthorized operation.
at Microsoft.Bot.Connector.Authentication.JwtTokenValidation.AuthenticateRequest......
あー認証系ね。ならどっかに MicrosoftAppId
と MicrosoftAppPassword
書かれてるなって想定で appsettings.json みると犯人を発見です。
空にすりゃ動くやろってのは以前のバージョンも一緒なので解決です。
ついでに、ここら辺の動作のソースは以前から追ったことがないので見てみました。
ここから自分のためのメモで他人に読まれることは想定してないさらに雑なメモになりますが、
そもそもエラーが発生しているメソッドは、IBotFrameworkHttpAdapter
の ProcessAsync
メソッド。
実体は、Microsoft.Bot.Builder.Integration.AspNet.Core
の BotFrameworkHttpAdapter
class の ProcessAsync
メソッド。
そこで JwtTokenValidation.AuthenticateRequest.... に行くんだけど、
あー、IsAuthenticationDisabledAsync が呼ばれるんだが、実装の実態は SimpleCredentialProvider
で、処理は以下。
public Task<bool> IsAuthenticationDisabledAsync() { return Task.FromResult(string.IsNullOrEmpty(AppId)); }
で全体的にあれかー。
ということで、調べた結果おもしろいことは何もなかったです。
その他
プロジェクトを編集してると、(さっきまで不通に動いてた)デプロイのタイミングで、フォルダパスが260文字超えててあかんでーってエラーがでました。
そして、この謎フォルダ&ファイルが...
このフォルダを削除すると、csproj にゴミが出るのでこのゴミ消すと...また**フォルダが出現というループに...
私のサイドエフェクトが「binとobj消せば直るかも?」と感じたので、プロジェクトのディレクトリー開いて bin と obj のフォルダ削除してリビルドしたら直りました。
詳しく原因とか見てないんですが、そこまで暇ないし、どうせそのうちアップデートされて改善されるだろうから、調査とかせず放置します。
4/17追記
かずきさんが正しい対処方法をアップしてくれています!
ブログにも書かれていますが、なんのためなのかわからんすねー。そして、そのうちSDKのアップデートで消えると思います。今回のアップデートの方向性はいいなと思いつつ、こういう面は悩ましいアップデートですね。