Azure Function で Slash Commands -  Visual Studio を使い、C# プリコンパイル Function として実装の巻

# はじめに - 今日時点での Azure Function 開発

[「Azure Function で Slash Commands 作ってみた」](https://qiita.com/naokiss/items/24f6fc7bf4388688914d) という記事にありますとおり、Microsoft のクラウドサービス "Microsoft Azure" が提供するサービスのひとつ、"Azure Functions" を利用することで、サーバーレスアーキテクチャのもと、Slack の Slash Command を実装・稼働させることができます。

上記記事[「Azure Function で Slash Commands 作ってみた」](https://qiita.com/naokiss/items/24f6fc7bf4388688914d)では、Web ブラウザで開いた Azure ポータルサイトから C# コードを入力しています。

しかし当時と異なり、今や Windows OS では、Visual Studio 2017 v.15.3 以降 + Tools for Azure Functions の環境で C# による Azure Function をローカル環境で開発し、コンパイル (ビルド) してビルド済みのアセンブリ (.dll ファイル) すなわち "プリコンパイル Function" を Azure にデプロイすることができるようになっています。

詳しくは下記ブログ記事を参照ください。

[**.NET Web Development and Tools Blog** - Visual Studio 2017 Tools for Azure Functions](https://blogs.msdn.microsoft.com/webdev/2017/05/10/azure-function-tools-for-visual-studio-2017/)

この方式であれば、Visual Studio による**インテリセンスやコードレンズなどといった IDE 支援**が得られ、大変快適に Azure Function 開発が行えます。
もちろん、(プリコンパイル Function がサポートされるより以前からそうでしたが) ローカル環境での実行や、Visual Studio 上でのデバッグもできます。

ということで、Visual Studio によるプリコンパイル Function 開発で[「Azure Function で Slash Commands 作ってみた」](https://qiita.com/naokiss/items/24f6fc7bf4388688914d)を再現してみました。

# 手順

## デプロイ先の Azure Function App を Azure 上に作成

まずは、記事[「Azure Function で Slash Commands 作ってみた」](https://qiita.com/naokiss/items/24f6fc7bf4388688914d)の "Function App を作成する" の節のとおり、Visual Studio で開発した Function App のデプロイ先を、Azure ポータルから作っておきます。

## Visual Studio 上での新規プロジェクトの作成

続けて Visual Studio を起動し、新規プロジェクト作成を実行して、新規プロジェクトテンプレートから "Azure Functions" を選択して、プロジェクトを作成します。

![fig-01-001.png](https://qiita-image-store.s3.amazonaws.com/0/58450/d8744881-ac81-0ec8-f28b-73d873452424.png)

今回は元記事になるべく倣うべく、途中のダイアログでは、「Azure Functions **v1 (.NET Framewrok)**」(v2 の .NET Core ではなく) を選択します。
(※もちろん、.NET Core でも実装できますが、ソースコードが若干元記事と変わったりしそうだったので。)

![fig-01-002.png](https://qiita-image-store.s3.amazonaws.com/0/58450/af40df3f-b462-905d-451e-e395d31c25de.png)

同ダイアログの [StorageAccount] には、今回の実装内容ではローカル実行時に Azure Storage を使用しないこともあり、開発用エミュレータ (Storage Emulator) を選んでおくことにします。

そしてこのダイアログにて早速にどんな Function を実装するかの選択肢がありますが、今回は順を追って進めるべく、"Empty" を選択し、最後に OK をクリックしてプロジェクトの新規作成を完遂します。

## Function の追加

作成した Azure Function App プロジェクトに、Function を新規追加します。
すなわち、Function の実体をコーディングする、C# ソースファイル (.cs) を作成します。
新規アイテムの追加から、"Azure Function" テンプレートを選んで作成しても、あるいは単純な "クラス" テンプレートを選んで作成しても構いません。

![fig-01-003.png](https://qiita-image-store.s3.amazonaws.com/0/58450/fe02e8e6-8e2d-c049-ac1b-477073b7524e.png)

"Azure Function" テンプレートを選んで作成する場合は、途中、バインディングを選択するダイアログになりますので、"Http Trigger" を選んでおくのがよいでしょう。

![fig-01-004.png](https://qiita-image-store.s3.amazonaws.com/0/58450/21265fde-4824-e57f-31d2-36be26ae2fb3.png)

先の記事に倣ってここでは "SlashCommands" という名前で Function を新規追加します。

## Function の内容を実装

こうして新規追加した C# ソースファイルに対し、下記のとおりコーディングします。

```csharp
using System;
using System.Net;
using System.Net.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

public static class SlashCommands
{
  [FunctionName("SlashCommands")]
  public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Function, "POST")]HttpRequestMessage req, TraceWriter log)
  {
      return req.CreateResponse(HttpStatusCode.OK, new
      {
          text = DateTime.Now.ToString(),
          response_type = "in_channel",
      });
  }
}
```

実装の本質的な部分は元記事と変わりありません。

ただしバインディングの設定については、元記事のように Azure ポータル上で行うのではなく、**C# ソースコード中の属性 (Attribute) で記述**するところが、プリコンパイル Function ならではのポイントです。

今回は Slack の Slash Commands からの HTTP 要求をハンドルするということで、バインディングの設定を `HttpTrigger` 属性にて、

- 承認レベルは Function
- 受付可能な HTTP 動詞は "POST" のみ

と設定しています。
なお、元記事ではバインディングを "Generic WebHook" で実装開始していますが、結局そのあと Azure ポータル上でバインディング設定をみたときにモードを "Standard" に "降格" していますので、上記手順で実装した場合と等価となります。

## 発行 (デプロイ)

ここまでできたら、Visual Studio のソリューションエクスプローラからプロジェクトのノードを右クリックして [発行...] を選択し、

![fig-01-005.png](https://qiita-image-store.s3.amazonaws.com/0/58450/72dbb7e5-89e9-3859-cee1-091f58f166c8.png)

先に作成しておいた Azure Function App を指定してデプロイします。

![fig-01-006.png](https://qiita-image-store.s3.amazonaws.com/0/58450/291a948a-2598-ed8c-34fa-1726a98e3a1b.png)

## Slash Commands の設定

以降の手順は元記事の "Slash Commands の設定" 以降と同じです。
Azure ポータルサイト経由で HTTP トリガのエンドポイント URL を手に入れ、Slack の設定画面に移って、Slash Commands にそのエンドポイント URL を設定するといった手順となります。

![fig-01-007.png](https://qiita-image-store.s3.amazonaws.com/0/58450/351338e9-6853-4b8e-3f81-34ad55f4f206.png)

# まとめ

Slack の Slash Command 応答を、Microsoft Azure Functions を使って、C# で実装・稼働させることができます。

Windows OS 上の話になりますが、Visual Studio 2017 v15.3 以降 + Tools for Azure Functions を用いれば、C# によるプリコンパイル Azure Function 開発を容易におこなうことができます。

このやり方だと、Visual Studio によって提供される、数々の開発支援機能の恩恵にあずかることができ、とても快適です。

なお、C# によるプリコンパイル Azure Function 実装においては、バインディングの指定は、C# ソースコード中に属性 (Attribute) で記述するところにご注意ください。

実際に実装した結果を GitHub にあげておきます。

https://github.com/sample-by-jsakamoto/SlackSlashCmdByAzureFunc

Happy Coding :)