如何通过 C# 的 Slack-App post 消息,作为用户而不是应用程序,在特定频道中带有附件

How to post a message via Slack-App from c#, as a user not App, with attachment, in a specific channel

我这辈子都无法 post 将消息发送到另一个频道而不是我 webhook 的频道。而且我不能像我自己一样(在我的 slackID 下),就像应用程序一样。

问题是我必须为我的公司做这件事,这样我们才能将 slack 集成到我们自己的软件中。我只是不明白 JSON 的 "payload" 应该是什么样子(实际上我做的和 Slack 网站上说的一模一样,但它根本不起作用——它总是忽略一些事情例如 "token"、"user"、"channel" 等)。

我也不明白如何使用像“https://slack.com/api/chat.postMessage”这样的url-方法-它们去哪儿了?正如您可能在我的代码中看到的那样,我只有 webhookurl,如果我不使用它,我将无法 post 进行任何操作。此外,我不明白如何使用诸如令牌、特定用户 ID、特定通道等参数... - 如果我尝试将它们放入有效负载中,它们似乎会被忽略。

好吧,抱怨够多了!我现在会告诉你我到目前为止得到了什么。这是来自 post 在线编辑此内容的人!但是我改变并添加了一些东西:

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;
        }
    }
}

我做了这个 class 所以我可以将有效载荷作为对象处理:

    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;
    }
}

如果有人能够 post 完整的代码,真正展示了我将如何处理负载,我将不胜感激。 And/or 实际的 URL 看起来像什么被发送到 slack...所以我也许可以理解到底发生了什么:)

1.传入 webhook 与 chat.postMessage

Slack 应用程序的传入 webhook 始终固定到一个频道。 Incoming Webhook that supports overriding the channel, but that has to be installed separately and will not be part of your Slack app. (see also ) 有遗留变体。

因此,对于您的情况,您想改用网络 API 方法 chat.postMessage

2。示例实现

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

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();
    }
}

这是一个使用同步调用的非常初级的实现。查看 this question 了解如何使用更高级的异步方法。

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

此示例使用更好的 async 方法发送请求和消息,包括。附件由 C# objects.

构建

此外,请求以现代方式发送 JSON Body POST,这需要在 header.

中设置令牌

注意:需要 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();

        }
    }

}