Unity Cloud Buildでビルドが終わったらSlackに通知する

# はじめに

[Unity Cloud Build](https://build.cloud.unity3d.com)はとても便利なのですが、ビルド完了時の通知方法が現在はメールしかありません。
今回はビルドが完了した時に、Slackに通知するようにしてみました。

(2016.9.8 追記)
WebHooks、Slack通知に対応したそうです。
https://blogs.unity3d.com/2016/09/07/webhooks-and-slack-notifications-in-unity-cloud-build/


# Slackの準備

SlackのWeb APIを使うので、以下のページで予めTokenを発行しておきます。
https://api.slack.com/web

次に投稿先のChannelのIDを調べます。該当のChannelの「Add a service integration ...」を開き、
URLの「channel_id=XXXXXXXXX」から取得するのが簡単なようです。


# Unity Cloud Build の準備

ビルド対象のプロジェクトの情報を取得しておきます。

* API Key
> Unity Cloud Buildにログインし、画面右上のメニューから、
 **Cloud Build Preference** を開くと下の方に **API Key** があります

* Organization ID
> 対象のプロジェクトを開き、URLの `orgs/XXXXXX` の部分をコピーします

* Project ID
> 対象のプロジェクトを開き、URLの `projects/XXXXXX` の部分をコピーします

* Target ID
> Historyの一覧に表示されている **Target** をコピーします。
`default-ios` `default-android` のような名称です。


# Unity Cloud Build のWebAPIで通知

最初はPostProcessBuildでSlackのWebAPIを叩いていたのですが、
これだとビルドが全て完了する前に投稿されてしまうため、正攻法に変えました。
Unity Cloud BuildのWebAPIをcronで叩き、ビルドが完了していたらSlackに投稿します。

Unity Cloud BuildのWebAPIは、現在はfreeプランでも利用可能になっています。
API Documentはこちら
https://build-api.cloud.unity3d.com/

最新のビルド結果を1件取得するには、以下のようなリクエストを投げます。

```bash:curlの例
curl --include 'https://build.cloud.unity3d.com/api/orgs/<orgid>/projects/<projectid>/buildtargets/<buildtargetid>/builds?per_page=1&page=1' -H 'Authorization:Basic <API KEY>'
```

cronで上記リクエストを投げて、最新のビルド結果に変更があればSlackに通知するようにします。

スクリプトをGitHubに公開しています。
https://github.com/tkyaji/UCB2Slack

なお、[PollingというAPI](https://build-api.cloud.unity3d.com/docs/1.0.0/index.html#operation--orgs--orgid--projects--projectid--buildtargets--buildtargetid--polling-post)があり、本当はcronで回すよりこれを使った方が正しいと思います。


## 投稿結果

```text
[ProjectName] build Succeeded : ios #1
[ChangeLogs]
    XXXXXXXXXXX
[INSTALL]
    https://build.cloud.unity3d.com/.......
```



# 以下は修正前のやり方

# ~~やり方~~
~~Unityプロジェクトの Assets/Editor 配下に以下のようなC#スクリプトを置いておきます。
`token`, `channel`は上で取得したものを設定します。~~

```csharp:PostBuildProcess.cs
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Net;


public class PostBuildProcess {

	[PostProcessBuild]
	public static void OnPostProcessBuild (BuildTarget buildTarget, string path) {
		#if UNITY_CLOUD_BUILD
			postToSlack (buildTarget);
		#endif
	}


	#if UNITY_CLOUD_BUILD
	private static void postToSlack(BuildTarget buildTarget) {

		string postMessage = "Unity Cloud Build : " + buildTarget.ToString () + " ビルド完了";
		Debug.Log ("Slack Post : " + postMessage);

		WWWForm form = new WWWForm();
		form.AddField("token", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
		form.AddField("channel", "XXXXXXXXX");
		form.AddField("text", postMessage);

		float start = Time.time;
		WWW w = new WWW("https://slack.com/api/chat.postMessage", form);

		// 5秒までレスポンスを待つ
		while (!w.isDone && Time.time - start < 5.0f) {}

		if (w.isDone) {
			Debug.Log (w.text);
		} else {
			Debug.LogError ("Slack Post Timeout.");
		}
	}
	#endif
}
```

~~見ての通り、`[PostProcessBuild]`でWeb APIを叩いているだけです。
そのため、ビルドエラー時は送られませんし、詳細なビルド結果が取れる訳でもありません。
単に「ビルド終わったよ」というのを教えてもらうだけです。
FreeやProプランの場合、ビルド完了まで結構時間がかかるので、無いよりはマシという感じです。~~

~~もっとちゃんと結果を受け取りたい場合は、現状はメールを監視するか、
WebAPIでチェックするのが正しいやり方だと思います。
※WebAPIはbeta版からはFreeプランでも使用可能になりました。~~

~~Unity Cloud Buildはまだ機能が色々増えている段階なので、
今後はSlack通知等も簡単にできるようになるかもしれません。~~

# ~~追記~~
~~後から気づいたんですが、PostProcessBuildが実行されるのはUnityのビルドが完了するタイミングですが、
その後にiOS、Androidのビルドが走るため、若干タイムラグが発生してしまいます。
Post-Export Method ならいけるかと思ったんですが、こちらも同様でした。
そのためやはりWebAPIでチェックするのが良さそうです。~~

~~WebAPIを使う場合、以下のような感じで最新のビルドを取得すれば良さそうです。~~

```bash:curlの例
curl --include 'https://build.cloud.unity3d.com/api/orgs/<orgid>/projects/<projectid>/buildtargets/<buildtargetid>/builds?per_page=1&page=1' -H 'Authorization:Basic <API KEY>'
```



以上