首页 > 解决方案 > 如何通过 C# 中的 Slack-App 在 Slack 上上传任何文件

问题描述

我需要帮助将文件上传到 Slack。

到目前为止,我有一个 Slack-App 正在使用我的代码(如下)。但我能做的就是发消息。我无法将图像附加到消息中 - 因为我不明白如何使用所谓的“方法”并且 Slack 的语法在他们的 API 页面上“显示”。

这将创建我的“内容”,并且在其下方只是一个用于读取我可以上传的文件的流:

    public class PostMessage
    {


        public FormUrlEncodedContent Content(string message, string file)
        {
            var values = new Dictionary<string, string>
            {
                {"token", "xoxp-myToken"},
                { "username", "X"},         
                { "channel", "myChannel"},
                { "as_user", "false"},     
                {"text", message},
                { "content", file},
                { "attachments","[{ \"fallback\":\"dummy\", \"text\":\"this is a waste of time\"}]"}
            };

            var content = new FormUrlEncodedContent(values);

            return content;
        }
    }

    public class PostFile
    {
        String path = @"C:\Users\f.held\Desktop\Held-Docs\dagged.jpg";

        public string ReadImageFile()
        {            
            FileInfo fileInfo = new FileInfo(path);
            long imageFileLength = fileInfo.Length;
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);
            byte[] imageData = br.ReadBytes((int)imageFileLength);
            var str = Encoding.Default.GetString(imageData);
            return str;
        }
    }
}  

通信的客户端:

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

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

        public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
        {
            var response = await _httpClient.PostAsync(_webhookUrl, content);

            return response;
        }    
     }
}

主要的:

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

private static async Task IntegrateWithSlackAsync()
{
    var webhookUrl = new Uri("https://slack.com/api/files.upload");
    var slackClient = new SlackClient(webhookUrl);
    PostMessage PM = new PostMessage();
    PostFile PF = new PostFile();


    while (true)
    {
        Console.Write("Type a message: ");
        var message = Console.ReadLine();
        var testFile = PF.ReadImageFile();
        FormUrlEncodedContent payload = PM.Content(message, testFile);
        var response = await slackClient.SendMessageAsync(payload);
        var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
        Console.WriteLine($"Received {isValid} response.");
        Console.WriteLine(response);
        response.Dispose();
    }
}

} }

如果有人有上传必须是什么样子的示例。甚至更好,

如果有人真的可以解释这些 Slack-Messages 必须具有的语法。

那太好了!我仍然不知道应该在哪里以及如何将所谓的 “接受的内容类型:multipart/form-data, application/x-www-form-urlencoded”放到我的上传文件中。我只是找不到这方面的例子......

编辑:

让我感到困惑的是,Slack 声明他们有一个额外的方法叫做file.upload- 但我们不应该再使用它了,我们应该只使用postMessage.

但是我将如何在消息中“打包”文件?我的语法似乎总是关闭。尤其是在“内容”方面......我只是无法弄清楚 c# 代码的外观。我在哪里声明上述“内容类型”?

另一个问题是,它总是通过它发送我的消息 - 意味着我从服务器获得 200 响应。但它从不显示文件(这可能意味着语法已关闭)或者我得到 200 响应但该消息从未在 Slack 中显示。

标签: c#slackslack-api

解决方案


消息中的图像

如果您想在消息中包含图像(以及一些文本),您可以通过将图像作为消息附件添加到使用chat.postMessage.

为此,您需要图像的公共 URL 以及该image_url属性与附件的链接。该附件还可以包含文本,您可以在邮件中添加多个附件。

这是它的样子:

在此处输入图像描述

以下是此消息在 JSON 中的外观:

{
    "channel": "test",
    "text": "This is a message example with images in the attachment",
    "attachments": [
        {
            "fallback": "game over",
            "text": "This is some text in the attachement",
            "image_url": "https://i.imgur.com/jO9N3eJ.jpg"

        }
    ]
}

上传图片

图像 URL 需要可在 Internet 上公开访问。因此,您需要将您的图像文件托管在公共网络服务器上或将其上传到图像云服务(例如 imgur.com)。

您还可以将 Slack 用作图像的云服务。以下是它的工作原理:

  1. 上传到 Slack:将您的图像上传到您的 Slack 工作区files.upload

  2. 获取公共 URL:使用files.sharedPublicURL. 通常 Slack 上的所有文件都是私有的,但您只能将公共 URL 用于消息附件。

  3. 发送消息:将您的图像作为附件包含在消息中:使用permalink_public图像文件的属性作为值image_url

示例代码

这是 C# 中的完整工作示例,用于首先将图像上传到 Slack,然后在消息中使用它。

注意:此示例需要Newtonsoft.Json

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

public class SlackExample
{
    // classes for converting JSON respones from API method into objects
    // note that only those properties are defind that are needed for this example

    // reponse from file methods
    class SlackFileResponse
    {
        public bool ok { get; set; }
        public String error { get; set; }
        public SlackFile file { get; set; }
    }

    // a slack file
    class SlackFile
    {
        public String id { get; set; }        
        public String name { get; set; }
        public String permalink_public { get; set; }
    }

    // reponse from message methods
    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 attachment
    class SlackAttachment
    {
        public String fallback { get; set; }
        public String text { get; set; }
        public String image_url { get; set; }
    }

    // main method with logic
    public static void Main()
    {
        String token = "xoxp-YOUR-TOKEN";


        /////////////////////
        // Step 1: Upload file to Slack

        var parameters = new NameValueCollection();

        // put your token here
        parameters["token"] = token;

        var client1 = new WebClient();
        client1.QueryString = parameters;
        byte[] responseBytes1 = client1.UploadFile(
                "https://slack.com/api/files.upload",
                "C:\\Temp\\Stratios_down.jpg"
        );

        String responseString1 = Encoding.UTF8.GetString(responseBytes1);

        SlackFileResponse fileResponse1 = 
            JsonConvert.DeserializeObject<SlackFileResponse>(responseString1);

        String fileId = fileResponse1.file.id;


        /////////////////////
        // Step 2: Make file public and get the URL

        var parameters2 = new NameValueCollection();
        parameters2["token"] = token;
        parameters2["file"] = fileId;

        var client2 = new WebClient();
        byte[] responseBytes2 = client2.UploadValues("https://slack.com/api/files.sharedPublicURL", "POST", parameters2);

        String responseString2 = Encoding.UTF8.GetString(responseBytes2);

        SlackFileResponse fileResponse2 =
            JsonConvert.DeserializeObject<SlackFileResponse>(responseString2);

        String imageUrl = fileResponse2.file.permalink_public;


        /////////////////////
        // Step 3: Send message including freshly uploaded image as attachment

        var parameters3 = new NameValueCollection();
        parameters3["token"] = token;
        parameters3["channel"] = "test_new";        
        parameters3["text"] = "test message 2";

        // create attachment
        SlackAttachment attachment = new SlackAttachment();
        attachment.fallback = "this did not work";
        attachment.text = "this is anattachment";
        attachment.image_url = imageUrl;
        SlackAttachment[] attachments = { attachment };        
        parameters3["attachments"] = JsonConvert.SerializeObject(attachments);

        var client3 = new WebClient();
        byte[] responseBytes3 = client3.UploadValues("https://slack.com/api/chat.postMessage", "POST", parameters3);

        String responseString3 = Encoding.UTF8.GetString(responseBytes3);

        SlackMessageResponse messageResponse =
            JsonConvert.DeserializeObject<SlackMessageResponse>(responseString3);

    }
}

推荐阅读