Search code examples
c#slackslack-api

How to properly format attachment data for Slack chat.postMessage


I am trying to incorporate a slack notification using a Slack bot app API into my C# application. The code below is working fine but the format used for the attachments field makes it very difficult to edit and maintain... There must be an easier way to populate that json array?

I've tried multiple ways to write it but I can't get it to work properly other than with this unwieldy syntax.

var data = new NameValueCollection
        {
            ["token"] = "token", // Removed my actual token from here obviously
            ["channel"] = "channel", // Same with the channel
            ["as_user"] = "true",
            ["text"] = "test message 2",
            ["attachments"] = "[{\"fallback\":\"dummy\", \"text\":\"this is an attachment\", \"color\":\"#F35A00\", \"title\" : \"Title\", \"title_link\": \"http://www.google.com\"}]"
        };

var client = new WebClient();
var response = client.UploadValues("https://slack.com/api/chat.postMessage", "POST", data);

Solution

  • The "unwieldy" syntax is hand-crafted JSON and a much better approach would be to construct the attachments as C# objects and then convert them into JSON as the API requires.

    My example is using the external library Json.NET for the JSON conversion.

    Example for C# object:

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

    Example for creating a new attachments array:

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

    Finally, converting the attachments array to JSON for the API:

    var attachmentsJson = JsonConvert.SerializeObject(attachments);
    

    See also this answer for a complete example.