C# で Slack にメッセージを送信する方法

★★★ Live配信告知 ★★★ぜひお申込みください!
◆◇SIOS PS Live配信 第20回◆◇
9/28(水) 19:00~ 〜 Google Cloudで実現したクラウド型電子カルテサービス「INDIGO NOTE」の開発小話 〜 開発に携わった3人のエンジニアが「Indigo Note」の概要、フロント開発・API開発をお話しします。

こんにちは。サイオステクノロジーの木村です。
今回は、Slack API を使用して、C# にて Slack にメッセージを送信する方法をご紹介します。

Slackの設定(Incoming Webhook)

Slack APIには、外部からSlackに送信するための仕組みである Incoming Webhook があります。
以下の手順でアプリを作成し、 Incoming Webhook の設定を行います。

1. Slack API にアクセスし、「Create an app」をクリックします。

2. 「From scrach」をクリックします。

3. 「App Name」に任意のアプリ名を入力します。「Pick a workspace to develop your app in:」にてメッセージを送信したいworkspace名を選択し、「Create App」をクリックします。

4. 左側のメニューより「Incoming Webhooks」をクリックします。

5. Active Incoming Webhooksを「On」にします。

6. 下部にスクロールし、「Add New Webhook to Workspace」をクリックします。

7. 送信先のチャンネルを選択し「許可する」をクリックします。

8. Webhook URL の「Copy」をクリックし、コピーしたURLをメモしておきます。

Slackのへメッセージ送信

Slack へメッセージを送信するには、json形式で送信内容を作成し、先ほどメモした Webhook URL に POST送信するだけです。
コンソールアプリケーションを作成し、以下のように実装します。


using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Net.Http;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Webhook URL
            var webhookUrl = "<先ほどメモしたWebhook URL>";

            var payload = new Payload { Text = "こんにちは。" };
            var json = JsonSerializer.Serialize(payload);

            var client = new HttpClient();
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var result = client.PostAsync(webhookUrl, content).Result;
            Console.WriteLine(result);
        }
    }

    public class Payload
    {
        [JsonPropertyName("text")] public string Text { get; set; }
    }
}


実行すると、送信先に指定したチャンネルにメッセージが送信されます。

Slack API – Block Kit

Slack API には、Block Kit というメッセージUIフレームワークがあり、Block Kit の形式に則ったjsonを構築して送信することで、よりリッチな表現のメッセージを送信することができます。
また、Block Kit Builderという、ブラウザにて Block Kit の表示を確認できるツールも用意されています。
以下は Block Kit Builder の画面です。
左ペインのボタンをクリックすると、クリックした項目に対応するブロックのjsonを作成して表示してくれます。
また、上部の「Send to Slack」をクリックすると、Block Kit Builder 上で表示した内容を、Slack に送信することもできます。

例えば、以下は Block Kit の Section、Driver、Context を使用して作成したメッセージです。

このメッセージを送信するには、以下のように実装します。


using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Net.Http;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Webhook URL
            var webhookUrl = "<先ほどメモしたWebhook URL>";

            List blocks = new List();

            // section block
            blocks.Add(new Section { Type = "section", TypeText = new TypeText{ 
                Type = "mrkdwn",  
                Text = "*サイオステクノロジー技術ブログ* \nC# に関する記事"
            } });
            // divider
            blocks.Add(new Divider { Type = "divider" });

            // section block with an accessory image
            blocks.Add(GetSectionA(
                "**\nTips\n*Last Update:* July 10, 2020",
                "https://tech-lab.sios.jp/wp-content/uploads/2020/07/Screen-Shot-2020-07-10-at-0.30.54-326x245.png",
                "image1"));
            // divider
            blocks.Add(new Divider { Type = "divider" });
            // section block with an accessory image
            blocks.Add(GetSectionA(
                "**\nTips\n*Last Update:* July 1, 2020",
                "https://tech-lab.sios.jp/wp-content/uploads/2020/07/EFL_jellybeanshana_TP_V-326x245.jpg",
                "image2"));
            // divider
            blocks.Add(new Divider { Type = "divider" });
            // section block with an accessory image
            blocks.Add(GetSectionA(
                "**\nTips\n*Last Update:* June 10, 2019",
                "https://tech-lab.sios.jp/wp-content/uploads/2019/06/Screen-Shot-2019-06-10-at-8.16.52.png",
                "image3"));
            // divider
            blocks.Add(new Divider { Type = "divider" });

            // context block
            blocks.Add(new Context {
                Type = "context",
                Elements = new List { new TypeText { 
                    Type = "mrkdwn", 
                    Text = ":pushpin:上記は記事の一部です。他にもたくさん記事がありますので、是非  へアクセスしてください。" } } 
            });

            var payload = new Payload { Blocks = blocks };
            var json = JsonSerializer.Serialize(payload);
            var client = new HttpClient();
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var result = client.PostAsync(webhookUrl, content).Result;
            Console.WriteLine(result);

        }

        private static SectionA GetSectionA(string text, string imageUrl, string imageName)
        {
            var sectionA = new SectionA
            {
                Type = "section",
                TypeText = new TypeText{ Type = "mrkdwn", Text = text},
                Accessory = new Accessory { Type = "image", ImageUrl = imageUrl, AltText = imageName}
            };
            return sectionA;
        }
    }

    public class Payload
    {
        [JsonPropertyName("blocks")] public List Blocks { get; set; }
    }

    public class TypeText
    {
        [JsonPropertyName("type")] public string Type { get; set; }
        [JsonPropertyName("text")] public string Text { get; set; }
    }

    public class Section
    {
        [JsonPropertyName("type")] public string Type { get; set; }
        [JsonPropertyName("text")] public TypeText TypeText { get; set; }
    }

    public class SectionA
    {
        [JsonPropertyName("type")] public string Type { get; set; }
        [JsonPropertyName("text")] public TypeText TypeText { get; set; }
        [JsonPropertyName("accessory")] public Accessory Accessory { get; set; }
    }

    public class Divider 
    { 
        [JsonPropertyName("type")] public string Type { get; set; }
    }

    public class Accessory
    {
        [JsonPropertyName("type")] public string Type { get; set; }
        [JsonPropertyName("image_url")] public string ImageUrl { get; set; }
        [JsonPropertyName("alt_text")] public string AltText { get; set; }
    }

    public class Context
    {
        [JsonPropertyName("type")] public string Type { get; set; }
        [JsonPropertyName("elements")] public List Elements { get; set; }
    }

}



ちなみに、上記実装により送信されるjsonは以下のようになります。


{
	"blocks": [
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*サイオステクノロジー技術ブログ* \nC# に関する記事"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "**\nTips\n*Last Update:* July 10, 2020"
			},
			"accessory": {
				"type": "image",
				"image_url": "https://tech-lab.sios.jp/wp-content/uploads/2020/07/Screen-Shot-2020-07-10-at-0.30.54-326x245.png",
				"alt_text": "image1"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "**\nTips\n*Last Update:* July 1, 2020"
			},
			"accessory": {
				"type": "image",
				"image_url": "https://tech-lab.sios.jp/wp-content/uploads/2020/07/EFL_jellybeanshana_TP_V-326x245.jpg",
				"alt_text": "image2"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "**\nTips\n*Last Update:* June 10, 2019"
			},
			"accessory": {
				"type": "image",
				"image_url": "https://tech-lab.sios.jp/wp-content/uploads/2019/06/Screen-Shot-2019-06-10-at-8.16.52.png",
				"alt_text": "image3"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "context",
			"elements": [
				{
					"type": "mrkdwn",
					"text": ":pushpin:上記は記事の一部です。他にもたくさん記事がありますので、是非  へアクセスしてください。"
				}
			]
		}
	]
}






ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!


ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

Be the first to comment

Leave a Reply

Your email address will not be published.


*