C# を書く環境として、Visual Studio や LinqPad、Visual Studio Code が良く話題になります。特にサクッとコード片を試す、インタラクティブにトライアンドエラーをしたいとなると、LinqPad (特に Premium) が素晴らしいです。
LinqPad に関しては、素晴らしいブログ記事があるのでぜひとも目を通されるといいと思います。
しかし、チャットでやり取りしていると LinqPad など他ツールを立ち上げること自体が億劫になります。ツールを切り替えるのは非常にコストが高く、ふとコード片を試したい、共有したい、あるいはチャット上でコードを実行したいとなると、チャット上でボットにお願いして評価してほしいでしょう。
そんな時に利用できるのが、Roslyn の Scripting API + AzureFunctions です。
とはいえ、Slack で Outgoing Webhooks を使ったチャットのコード評価ボットに関する素晴らしい記事がすでにあります。
今回はこの素晴らしい知見を基に、Line や 他チャットなど汎用的なWebhookをJSON経由で評価できるようにしてみましょう。
目次
Roslyn Scripting API の分離
Slack Outgoing Webhook と 汎用JSON Webhook の両方で C# Scripting を使うので、評価部分だけCSharpScripting.csx
としてコードを分離します。利用したい run.csx
は、#load
コマンドで呼び出せるようになり二重管理から解放されます。
元記事に加えて、外部を叩いたりできるように参照をごそっと追加します。
これで、評価したいコードを string
として渡せば Roslyn が実行してくれるようになりました。
Webhook 用にFunction を作成する
続いて、application/json
形式で入力されたWebhookを受け入れる Azure Functions として CSharpCompilerWebhookCSharp
を作成します。
function.json に注意です。Slack の slashcommand や Outgoing Webhook と違い、GenericJson としてください。
Roslynコード評価を外に出したので、run.csx がとてもシンプルになりました。
検証
サンプルとして、Azure Functions 画面上でテストしてみます。google.com ページのソース文字数を数えてみましょう。
うまくいきましたね。
new System.Net.Http.HttpClient().GetStringAsync("https://google.com").Result.Length
Slack Outgoing Webhook も修正してみる
とはいっても元記事そのままで、C# コード評価部分だけ外を参照するだけです。ただし、0.2 に上げた場合は、以下の設定に変わります。
こちらも問題なく実行されましたね。
@C#: Enumerable.Range(10, 20).Aggregate((x, y) => x + y)
まとめ
今回のものも、Github に載せておきました。
Roslyn Scripting による C#コード評価は非常に簡単ですが、既存の何かに載せるにはサンドボックスだったり色々考慮が必要です。
こういった環境を気にしないといけないものこそ AzureFunctions に寄せると、不用意なリークも防げるため安全がある程度担保されるかと思います。
素晴らしい記事の数々に感謝です。
グラニはC#怖い人によって 数年前からすでに Chatwork上でコード実行が出来ているのですが、Azure Functions に実行基盤を移譲できそうでよかったです。