うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】Unity から Slack にスクリーンショットを投稿する

探しても Unity から投稿してるサンプルが見つからなかったので、書いておきます

アプリは追加して、Bot Token Scopes に files:write を追加している前提で進めます

api.slack.com API とかパラメータは上記にあるので一読しておくとよきです

スクショの準備

スクリーンショットを撮影してテクスチャにするには ScreenCapture.CaptureScreenshotAsTexture を利用すればできます

WaitForEndOfFrame でフレームの終わりまでまたないと、Unityがクラッシュしてしまいます

UnityTestRunnerでUniTaskを使おう! - Qiita によると UniTask 2.3.1未満の場合 await UniTask.WaitForEndOfFrame() 正しく動作しないのでこちらを利用の場合も注意が必要です

こちらがスクリーンショットを撮影して投げるまでの処理、Token や ChannelID は適切なものを設定してください

    private IEnumerator Post()
    {
        yield return new WaitForEndOfFrame();

        var texture =  ScreenCapture.CaptureScreenshotAsTexture();

        var token = "xoxb-hoge-hoge-hoge";
        var channelId = "hoge";
        yield return SlackUtility.PostImage(token, channelId, texture, "test");
    }

Slack へ投稿

UnityWebRequest を利用して Slack へ投稿しています

Slack へのポスト結果は Json で返ってくるので、エラーしていた場合も Success になってしまうため

エラー内容が含まれていたらエラーとしています

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public static class SlackUtility
{
    public static IEnumerator PostImage(string token, string channelId, Texture2D texture, string comment = "", string title = "")
    {
        var form = new WWWForm();
        form.AddField("token", token);
        form.AddField("channels", channelId);
        form.AddBinaryData("file", texture.EncodeToPNG());
        form.AddField("filename", "screenshot.png");
        form.AddField("filetype", "png");
        
        if (!string.IsNullOrEmpty(title)) 
            form.AddField("title", "title");
        if (!string.IsNullOrEmpty(comment)) 
            form.AddField("initial_comment", comment);

        var url = "https://slack.com/api/files.upload";

        var request = UnityWebRequest.Post(url, form);
        request.SendWebRequest();
        
        yield return new WaitUntil(() => request.isDone);

        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError(request.error);
            yield break;
        }

        var text = request.downloadHandler.text;
        // エラーでもJsonが返ってくるので中身を確認する
        var index = text.IndexOf("\"error\":", StringComparison.Ordinal);
        if (index > 0)
        {
            Debug.LogError(text);    
            yield break;
        }
        
        Debug.Log(text);
    }
}

実行結果

こんな感じで投稿できます