如何在不和谐的Webhook中发送文件?

时间:2020-03-30 13:27:48

标签: c# discord

所以我正在用c#编写一个应用程序,该应用程序应该通过Discord Webhooks发送消息。我希望它能够发送文件。有可能吗,我该怎么做?下面是我的代码,用于在不发送任何文件的情况下发送普通邮件。

sendWebHook ((webHook), string.Concat(new string[] {"test message", }), "webhook test");

如果有人可以帮助我,我会很高兴。 :)

3 个答案:

答案 0 :(得分:1)

您可以发送文件,您可以这样做!

https://github.com/MorganSkilly/Unity-Discord-Webhook-System/blob/main/Discord.cs

该脚本是为统一而设计的,但可以轻松更改并应用于其他地方:)

private static readonly Encoding encoding = Encoding.UTF8;
    public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
    {
        string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());

        string contentType = "multipart/form-data; boundary=" + formDataBoundary;

        byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

        return PostForm(postUrl, userAgent, contentType, formData);
    }

    private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
    {
        HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

        if (request == null)
        {
            Debug.LogWarning("request is not a http request");
            throw new NullReferenceException("request is not a http request");
        }

        // Set up the request properties.
        request.Method = "POST";
        request.ContentType = contentType;
        request.UserAgent = userAgent;
        request.CookieContainer = new CookieContainer();
        request.ContentLength = formData.Length;

        // Send the form data to the request.
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(formData, 0, formData.Length);
            requestStream.Close();
        }

        return request.GetResponse() as HttpWebResponse;
    }

    private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
    {
        Stream formDataStream = new System.IO.MemoryStream();
        bool needsCLRF = false;

        foreach (var param in postParameters)
        {
            if (needsCLRF)
                formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

            needsCLRF = true;

            if (param.Value is FileParameter)
            {
                FileParameter fileToUpload = (FileParameter)param.Value;

                string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                    boundary,
                    param.Key,
                    fileToUpload.FileName ?? param.Key,
                    fileToUpload.ContentType ?? "application/octet-stream");

                formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));

                formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
            }
            else
            {
                string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                    boundary,
                    param.Key,
                    param.Value);
                formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
            }
        }

        // Add the end of the request.  Start with a newline
        string footer = "\r\n--" + boundary + "--\r\n";
        formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

        // Dump the Stream into a byte[]
        formDataStream.Position = 0;
        byte[] formData = new byte[formDataStream.Length];
        formDataStream.Read(formData, 0, formData.Length);
        formDataStream.Close();

        return formData;
    }

    public class FileParameter
    {
        public byte[] File { get; set; }
        public string FileName { get; set; }
        public string ContentType { get; set; }
        public FileParameter(byte[] file) : this(file, null) { }
        public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
        public FileParameter(byte[] file, string filename, string contenttype)
        {
            File = file;
            FileName = filename;
            ContentType = contenttype;
        }
    }

答案 1 :(得分:0)

我检查了API,似乎可行。参见there

您需要调整标题:Content-Type: multipart/form-data

我认为您需要调整文件目录。 (请参阅文件对象参考)

信息: 我不知道如何使用C#进行编码,但是有一个带有sendFile()函数的nodejs包。因此绝对有可能。

答案 2 :(得分:0)

实际上,.net 4.5 及更高版本有更简单的方法。上面的示例使用 webhook url 发送文本文件。您可以根据需要进行更改。

    string Webhook_link = "your_webhook_link_here";
    string FilePath = @"C:\Users\sample.txt";
    
    using (HttpClient httpClient = new HttpClient())
    {
        MultipartFormDataContent form = new MultipartFormDataContent();
        var file_bytes = System.IO.File.ReadAllBytes(FilePath);
        form.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "Document", "file.txt");
        httpClient.PostAsync(Webhook_link, form).Wait();
        httpClient.Dispose();
    }

我使用 MultipartFormDataContent 来指定文件内容,包括字节、文件类型、显示文件名。

(new MultipartFormDataContent()).Add(
    ByteArrayContent,                        //fill it with byte array of your file
    File_Type,                               //Specify file type e.g Photo Document etc
    DisplayFilename                          //This name would be shown as your filename
);

请记住,您还需要引用 System.Net.Http.dll