如何通过 C# 的 Slack-App post 消息,作为用户而不是应用程序,在特定频道中带有附件
How to post a message via Slack-App from c#, as a user not App, with attachment, in a specific channel
我这辈子都无法 post 将消息发送到另一个频道而不是我 webhook 的频道。而且我不能像我自己一样(在我的 slackID 下),就像应用程序一样。
问题是我必须为我的公司做这件事,这样我们才能将 slack 集成到我们自己的软件中。我只是不明白 JSON 的 "payload" 应该是什么样子(实际上我做的和 Slack 网站上说的一模一样,但它根本不起作用——它总是忽略一些事情例如 "token"、"user"、"channel" 等)。
我也不明白如何使用像“https://slack.com/api/chat.postMessage”这样的url-方法-它们去哪儿了?正如您可能在我的代码中看到的那样,我只有 webhookurl,如果我不使用它,我将无法 post 进行任何操作。此外,我不明白如何使用诸如令牌、特定用户 ID、特定通道等参数... - 如果我尝试将它们放入有效负载中,它们似乎会被忽略。
好吧,抱怨够多了!我现在会告诉你我到目前为止得到了什么。这是来自 post 在线编辑此内容的人!但是我改变并添加了一些东西:
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;
}
}
}
我做了这个 class 所以我可以将有效载荷作为对象处理:
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;
}
}
如果有人能够 post 完整的代码,真正展示了我将如何处理负载,我将不胜感激。 And/or 实际的 URL 看起来像什么被发送到 slack...所以我也许可以理解到底发生了什么:)
1.传入 webhook 与 chat.postMessage
Slack 应用程序的传入 webhook 始终固定到一个频道。 Incoming Webhook that supports overriding the channel, but that has to be installed separately and will not be part of your Slack app. (see also ) 有遗留变体。
因此,对于您的情况,您想改用网络 API 方法 chat.postMessage
。
2。示例实现
这是一个非常基本的示例实现,用于在 C# 中使用 chat.postMessage
发送消息。它适用于不同的渠道,消息将作为拥有令牌的用户(与安装应用程序的用户相同)而不是应用程序发送。
using System;
using System.Net;
using System.Collections.Specialized;
using System.Text;
public class SlackExample
{
public static void SendMessageToSlack()
{
var data = new NameValueCollection();
data["token"] = "xoxp-YOUR-TOKEN";
data["channel"] = "blueberry";
data["as_user"] = "true"; // to send this message as the user who owns the token, false by default
data["text"] = "test message 2";
data["attachments"] = "[{\"fallback\":\"dummy\", \"text\":\"this is an attachment\"}]";
var client = new WebClient();
var response = client.UploadValues("https://slack.com/api/chat.postMessage", "POST", data);
string responseInString = Encoding.UTF8.GetString(response);
Console.WriteLine(responseInString);
}
public static void Main()
{
SendMessageToSlack();
}
}
这是一个使用同步调用的非常初级的实现。查看 this question
了解如何使用更高级的异步方法。
这是一个关于如何发送带附件的 Slack 消息的改进示例。
此示例使用更好的 async 方法发送请求和消息,包括。附件由 C# objects.
构建
此外,请求以现代方式发送 JSON Body POST,这需要在 header.
中设置令牌
注意:需要 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();
}
}
}
我这辈子都无法 post 将消息发送到另一个频道而不是我 webhook 的频道。而且我不能像我自己一样(在我的 slackID 下),就像应用程序一样。
问题是我必须为我的公司做这件事,这样我们才能将 slack 集成到我们自己的软件中。我只是不明白 JSON 的 "payload" 应该是什么样子(实际上我做的和 Slack 网站上说的一模一样,但它根本不起作用——它总是忽略一些事情例如 "token"、"user"、"channel" 等)。
我也不明白如何使用像“https://slack.com/api/chat.postMessage”这样的url-方法-它们去哪儿了?正如您可能在我的代码中看到的那样,我只有 webhookurl,如果我不使用它,我将无法 post 进行任何操作。此外,我不明白如何使用诸如令牌、特定用户 ID、特定通道等参数... - 如果我尝试将它们放入有效负载中,它们似乎会被忽略。
好吧,抱怨够多了!我现在会告诉你我到目前为止得到了什么。这是来自 post 在线编辑此内容的人!但是我改变并添加了一些东西:
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;
}
}
}
我做了这个 class 所以我可以将有效载荷作为对象处理:
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;
}
}
如果有人能够 post 完整的代码,真正展示了我将如何处理负载,我将不胜感激。 And/or 实际的 URL 看起来像什么被发送到 slack...所以我也许可以理解到底发生了什么:)
1.传入 webhook 与 chat.postMessage
Slack 应用程序的传入 webhook 始终固定到一个频道。 Incoming Webhook that supports overriding the channel, but that has to be installed separately and will not be part of your Slack app. (see also
因此,对于您的情况,您想改用网络 API 方法 chat.postMessage
。
2。示例实现
这是一个非常基本的示例实现,用于在 C# 中使用 chat.postMessage
发送消息。它适用于不同的渠道,消息将作为拥有令牌的用户(与安装应用程序的用户相同)而不是应用程序发送。
using System;
using System.Net;
using System.Collections.Specialized;
using System.Text;
public class SlackExample
{
public static void SendMessageToSlack()
{
var data = new NameValueCollection();
data["token"] = "xoxp-YOUR-TOKEN";
data["channel"] = "blueberry";
data["as_user"] = "true"; // to send this message as the user who owns the token, false by default
data["text"] = "test message 2";
data["attachments"] = "[{\"fallback\":\"dummy\", \"text\":\"this is an attachment\"}]";
var client = new WebClient();
var response = client.UploadValues("https://slack.com/api/chat.postMessage", "POST", data);
string responseInString = Encoding.UTF8.GetString(response);
Console.WriteLine(responseInString);
}
public static void Main()
{
SendMessageToSlack();
}
}
这是一个使用同步调用的非常初级的实现。查看 this question
了解如何使用更高级的异步方法。
这是一个关于如何发送带附件的 Slack 消息的改进示例。
此示例使用更好的 async 方法发送请求和消息,包括。附件由 C# objects.
构建此外,请求以现代方式发送 JSON Body POST,这需要在 header.
中设置令牌注意:需要 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();
}
}
}