如何通过 Slack-App 从 C# 发布消息,作为用户而不是 App,在特定频道中带有附件

Fab*_*eld 5 c# slack-api slack

我一辈子都不能向另一个频道发布消息,而不是我通过网络连接的频道。我不能像我自己(在我的 slackID 下)那样做,就像应用程序一样。

问题是我必须为我的公司做这件事,所以我们可以将 slack 集成到我们自己的软件中。我只是不明白 JSON 的“有效负载”必须是什么样子(实际上我正在按照 Slack 网站上的说明进行操作,但它根本不起作用 - 它总是忽略诸如“令牌”之类的东西,“用户”、“频道”等)。

我也不明白如何使用像“ https://slack.com/api/chat.postMessage ”这样的 url-methods - 他们去哪里了?正如您在我的代码中可能看到的,我只有 webhookurl,如果我不使用它,我就无法发布任何内容。此外,我不明白如何使用诸如令牌、特定用户 ID、特定频道之类的参数...... - 如果我尝试将它们放入有效负载中,它们似乎会被忽略。

好吧,抱怨够了!现在我将向您展示我到目前为止所得到的。这是网上有人发的!但我改变并添加了一些东西:

public static void Main(string[] args)
        {
            Task.WaitAll(IntegrateWithSlackAsync());
        }

        private static async Task IntegrateWithSlackAsync()
        {
            var webhookUrl = new Uri("https://hooks.slack.com/services/TmyHook");  
            var slackClient = new SlackClient(webhookUrl);
            while (true)
            {
                Console.Write("Type a message: ");
                var message = Console.ReadLine();
                Payload testMessage = new Payload(message);
                var response = await slackClient.SendMessageAsync(testMessage);
                var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
                Console.WriteLine($"Received {isValid} response.");
                Console.WriteLine(response);
            }
        }
    }
}

public class SlackClient
{
        private readonly Uri _webhookUrl;
        private readonly HttpClient _httpClient = new HttpClient {};

        public SlackClient(Uri webhookUrl)
        {
            _webhookUrl = webhookUrl;
        }

        public async Task<HttpResponseMessage> SendMessageAsync(Payload payload)
        {

            var serializedPayload = JsonConvert.SerializeObject(payload);

            var stringCont = new StringContent(serializedPayload, Encoding.UTF8, "application/x-www-form-urlencoded");

            var response = await _httpClient.PostAsync(_webhookUrl, stringCont);

            return response;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了这个类,所以我可以将有效负载作为对象处理:

    public class Payload
{
    public string token = "my token stands here";
    public string user = "my userID";
    public string channel = "channelID";
    public string text = null;

    public bool as_user = true;


    public Payload(string message)
    {
        text = message;
    }
}
Run Code Online (Sandbox Code Playgroud)

我会非常感谢任何可以发布完整代码的人,这些代码真正展示了我将如何处理有效负载。和/或发送到 slack 的实际 URL 会是什么样子......所以我也许可以理解到底发生了什么:)

Eri*_*ken 6

1. 传入 webhook 与 chat.postMessage

Slack 应用程序的传入 webhook 始终固定到频道。传入 Webhook 的旧版本支持覆盖通道,但必须单独安装,并且不会成为您的 Slack 应用程序的一部分。(另请参阅此答案)。

因此,对于您的情况,您希望改用 Web API 方法chat.postMessage

2. 示例实现

这是一个非常基本的示例实现,用于chat.postMessage在 C# 中发送消息。它适用于不同的频道,消息将作为拥有令牌的用户(与安装应用程序相同)而不是应用程序发送。

using System;
using System.Net;
using System.Collections.Specialized;
using System.Text;

public class SlackExample
{    
    public static void SendMessageToSlack()
    {        
        var data = new NameValueCollection();
        data["token"] = "xoxp-YOUR-TOKEN";
        data["channel"] = "blueberry";        
        data["as_user"] = "true";           // to send this message as the user who owns the token, false by default
        data["text"] = "test message 2";
        data["attachments"] = "[{\"fallback\":\"dummy\", \"text\":\"this is an attachment\"}]";

        var client = new WebClient();
        var response = client.UploadValues("https://slack.com/api/chat.postMessage", "POST", data);
        string responseInString = Encoding.UTF8.GetString(response);
        Console.WriteLine(responseInString);        
    }

    public static void Main()
    {
        SendMessageToSlack();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是使用同步调用的非常基本的实现。查看this question如何使用更高级的异步方法。


Eri*_*ken 5

这是有关如何发送带有附件的 Slack 消息的改进示例。

此示例使用更好的异步方法发送请求和消息包括。附件是从 C# 对象构造的。

此外,请求作为现代 JSON Body POST 发送,这需要在标头中设置 TOKEN。

注意:需要Json.Net

using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace SlackExample
{
    class SendMessageExample
    {
        private static readonly HttpClient client = new HttpClient();

        // reponse from message methods
        public class SlackMessageResponse
        {
            public bool ok { get; set; }
            public string error { get; set; }
            public string channel { get; set; }
            public string ts { get; set; }
        }

        // a slack message
        public class SlackMessage
        {
            public string channel{ get; set; }
            public string text { get; set; }
            public bool as_user { get; set; }
            public SlackAttachment[] attachments { get; set; }
        }

        // a slack message attachment
        public class SlackAttachment
        {
            public string fallback { get; set; }
            public string text { get; set; }
            public string image_url { get; set; }
            public string color { get; set; }
        }

        // sends a slack message asynchronous
        // throws exception if message can not be sent
        public static async Task SendMessageAsync(string token, SlackMessage msg)
        {
            // serialize method parameters to JSON
            var content = JsonConvert.SerializeObject(msg);
            var httpContent = new StringContent(
                content,
                Encoding.UTF8,
                "application/json"
            );

            // set token in authorization header
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

            // send message to API
            var response = await client.PostAsync("https://slack.com/api/chat.postMessage", httpContent);

            // fetch response from API
            var responseJson = await response.Content.ReadAsStringAsync();

            // convert JSON response to object
            SlackMessageResponse messageResponse =
                JsonConvert.DeserializeObject<SlackMessageResponse>(responseJson);

            // throw exception if sending failed
            if (messageResponse.ok == false)
            {
                throw new Exception(
                    "failed to send message. error: " + messageResponse.error
                );
            }
        }

        static void Main(string[] args)
        {           
            var msg = new SlackMessage
            {
                channel = "test",
                text = "Hi there!",
                as_user = true,
                attachments = new SlackAttachment[] 
                {
                    new SlackAttachment
                    {
                        fallback = "this did not work",
                        text = "This is attachment 1",
                        color = "good"
                    },

                    new SlackAttachment
                    {
                        fallback = "this did not work",
                        text = "This is attachment 2",
                        color = "danger"
                    }
                }
            };

            SendMessageAsync(
                "xoxp-YOUR-TOKEN",                
                msg
            ).Wait();

            Console.WriteLine("Message has been sent");
            Console.ReadKey();

        }
    }

}
Run Code Online (Sandbox Code Playgroud)