3

I'm coding a simple console application in C# to communicate with Slack.com. I'm doing this via their WebApi. Currently I know how to post messages (with attachments, colored, links, users etc.) and send files to server.

If you send a file in a normal way ("Upload a file" on the left side of typing textbox) this file will be shown in the main conversation window. But how can you achieve the same thing via WebAPI ? Currently after sending the file, I can see it in the right side panel where all files are listed only.

Also there is a second question: is it possible to change to color of text in the message (no the "line" in attachment)?

This is the response after sending the file via https://slack.com/api/files.upload

{
    "ok": true,
    "file": {
        "id": "F04EX4***",
        "created": 1429279966,
        "timestamp": 1429279966,
        "name": "Testing.txt",
        "title": "Testing",
        "mimetype": "text\/plain",
        "filetype": "text",
        "pretty_type": "Plain Text",
        "user": "U*********",
        "editable": true,
        "size": 28,
        "mode": "snippet",
        "is_external": false,
        "external_type": "",
        "is_public": false,
        "public_url_shared": false,
        "url": "https:\/\/slack-files.com\/files-pub\/T*******\
/testing.txt",
        "url_download": "https:\/\/slack-files.com\/files-pub\/T************\
/download\/testing.txt",
        "url_private": "https:\/\/files.slack.com\/files-pri\/T*******\
/testing.txt",
        "url_private_download": "https:\/\/files.slack.com\/files-pri\/T**********\
 /download\/testing.txt",
        "permalink": "https:\/\/******.slack.com\/files\/******\
/F0******\/testing.txt",
        "permalink_public": "https:\/\/slack-files.com\/********",
        "edit_link": "https:\/\/******.slack.com\/files\/****\/F******\/testing.txt\/edit",
        "preview": "This is a test file number2.",
        "preview_highlight": "<div class=\
"sssh-code\"><div class=\"sssh-line\"><pre>This is a test file number2.<\/pre><\/div>\n
<\/div>",
        "lines": 1,
        "lines_more": 0,
        "channels": [],
        "groups": [],
        "ims": [],
        "comments_count": 0
    }
}

sorry, I don't know how to format this nicely.

The "is_external" and "is_public" are both false, maybe this is the reason - but how can I set them to "true" ?

->> Thank you for the edit! :) This is the whole function I'm using:

public static void SlackSendFile()
    {
        FileStream str = File.OpenRead(@"C:\Users\Eru\Desktop\Testing.txt");
        byte[] fBytes = new byte[str.Length];
        str.Read(fBytes, 0, fBytes.Length);
        str.Close();

        var webClient = new WebClient();
        string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
        webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
        var fileData = webClient.Encoding.GetString(fBytes);
        var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, "Testing.txt", "multipart/form-data", fileData);

        var nfile = webClient.Encoding.GetBytes(package);
        string url = "https://slack.com/api/files.upload?token=" + Token + "&content=" + nfile + "&channels=[" + Channel + "]";

        byte[] resp = webClient.UploadData(url, "POST", nfile);

        var k = System.Text.Encoding.Default.GetString(resp);
        Console.WriteLine(k);
        Console.ReadKey();
    }

EDIT1: In this line:

 byte[] resp = webClient.UploadData(url, "POST", nfile);

The URL is:

 https://slack.com/api/files.upload?token=*********&content=System.Byte[]&channels=[%23*****]

Then I'm passing the byte array.

EDIT:

I have solved the problem. The thing was that the channel should be the ID of channel, not the name of the channel... stupid mistake :(

Eru
  • 332
  • 3
  • 17
  • Try reading through this: https://api.slack.com/methods/files.upload – maccettura Apr 17 '15 at 13:46
  • Yes, this is how I'm sending the files. But this doesn't show the file in the main conversation window. – Eru Apr 17 '15 at 14:02
  • Try debugging your application to see what http response comes back, also make sure the trust level of your application is set to full. – maccettura Apr 17 '15 at 14:10
  • Can you show us the JSON you are posting too? – maccettura Apr 17 '15 at 14:56
  • Are you sure the Slack API integration is currently active? Also, have you tried seeing the value of the string 'url' after its been concatenated (to see if it looks like a proper URL)? – maccettura Apr 17 '15 at 15:10
  • I've edited the post adding the URL. what do you mean is "ACTIVE" ? how to check this? I think yes as I can send messages and files also but they don't show up in the main conversation window. – Eru Apr 20 '15 at 08:27
  • Do you have the integration configured and enabled on Slack? It might be a dumb question but it seems like you are doing everything right, its the only thing I can think of. – maccettura Apr 20 '15 at 15:24
  • All I have in my "Configured integrations" is the "Incoming Webhooks" (apart from other things which are irrelevant now). I have one function which uses the URL: https://hooks.slack.com/services/..... and the file I'm sending to the API... maybe I should configure something more there? :( – Eru Apr 21 '15 at 07:40
  • 1
    problem solved -> see the post, last "edit" – Eru Apr 21 '15 at 09:30
  • Wow thats really strange, I have always just used the name. Glad you got it working! – maccettura Apr 21 '15 at 13:12
  • Great article. BTW, if you are testing local webhooks, I recommend a program called ngrok from http://ngrok.com. Once you get it setup. You can do a command line on your dev machine to test your local API with "ngrok http -host-header=localhost:9000 9000" If your api port was on 9000 for example – Rudy Hinojosa Jun 21 '16 at 13:46

3 Answers3

3

Hi here a clean example with RestSharp

public void UploadFile(string token, string filePath, string channel)
{
    var client = new RestClient("https://slack.com");

    var request = new RestRequest("api/files.upload", Method.POST);
    request.AddParameter("token", token);
    request.AddParameter("channels", channel);

    var fileInfo = new FileInfo(filePath);
    request.AddFile("file", File.ReadAllBytes(filePath), fileInfo.Name, contentType:"multipart/form-data");

    //Execute the request
    var response = client.Execute(request);
    var content = response.Content;
}
live2
  • 3,771
  • 2
  • 37
  • 46
  • First of all thank you for the answer. It works pretty well. I need a few additions and unfortunately I couldn't figure it out. First of all, I want to send it with the information of the sender. I add user as a parameter, but I did not get successful results. Secondly, I want to upload a message along with the file upload. I added the text parameter, this parameter is not functional, can you guide me? – Ozgur Saklanmaz May 11 '22 at 06:37
2

If you add pretty=1 after channel property, it will work better.

Example:

string url = "https://slack.com/api/files.upload?token=" + token + "&content=" + nfile + "&channels=[" + Channel + "]&pretty=1"
slfan
  • 8,950
  • 115
  • 65
  • 78
CurseZzZzz
  • 21
  • 2
1

I had to change your code a little bit to get it working for anyone still looking for this. I needed to convert the file array to an ASCII encoded string, and then pulled the details into parameters.

    public static void SlackSendFile(string token, string channelId, string filepath)
    {
        FileStream str = File.OpenRead(filepath);
        byte[] fBytes = new byte[str.Length];
        str.Read(fBytes, 0, fBytes.Length);
        str.Close();

        var webClient = new WebClient();
        string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
        webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
        var fileData = webClient.Encoding.GetString(fBytes);
        var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, "Testing.txt", "multipart/form-data", fileData);

        var nfile = webClient.Encoding.GetBytes(package);
        var encodedfile = System.Text.Encoding.ASCII.GetString(nfile);
        string url = "https://slack.com/api/files.upload?token=" + token + "&content=" + encodedfile + "&channels=" + channelId + "";

        byte[] resp = webClient.UploadData(url, "POST", nfile);

        var k = System.Text.Encoding.Default.GetString(resp);
        Console.WriteLine(k);
    }
SumGuy
  • 602
  • 7
  • 18