Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I can not for the life of me post a message to another channel than the one I webhooked. And I can not do it as myself(under my slackID), just as the App.

Problem is I have to do this for my company, so we can integrate slack to our own Software. I just do not understand what the "payload" for JSON has to look like (actually I'm doing it exactly like it says on Slack's Website, but it doesn't work at all - it always ignores things like "token", "user", "channel" etc.).

I also do not understand how to use the url-methods like "https://slack.com/api/chat.postMessage" - where do they go? As you might see in my code I only have the webhookurl, and if I don't use that one I can not post to anything. Also I do not understand how to use arguments like a token, specific userId, a specific channel... - if I try to put them in the Payload they are just ignored, it seems.

Okay, enough whining! I'll show you now what I got so far. This is from someone who posted this online! But I changed and added a few things:

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

I made this class so I can handle the Payload as an Object:

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

I would be so appreciative for anyone who could post a complete bit of code that really shows how I would have to handle the payload. And/or what the actual URL would look like that gets send to slack... so I maybe can understand what the hell is going on :)

like image 955
Fabian Held Avatar asked Nov 07 '18 15:11

Fabian Held


People also ask

How do I post a message in Slack?

Open the channel or DM that you'd like to send a message to. Tap the message field.

How do I add a post to Slack mobile app?

Search for and select Create a post from the menu. Enter a title and begin typing. Your post will be saved automatically. To format your post, highlight a portion of text and select a formatting option from the menu.


1 Answers

Here is an improved example on how send a Slack message with attachments.

This example is using the better async approach for sending requests and the message incl. attachments is constructed from C# objects.

Also, the request is send as modern JSON Body POST, which requires the TOKEN to be set in the header.

Note: Requires 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();

        }
    }

}
like image 169
Erik Kalkoken Avatar answered Oct 13 '22 11:10

Erik Kalkoken