【问题标题】:Sending JSON to Slack in a HTTP POST request在 HTTP POST 请求中将 JSON 发送到 Slack
【发布时间】:2015-08-09 14:27:22
【问题描述】:

我正在尝试使用Slack's chat.postMessage API 调用发送消息。我在 HTTP GET 中对测试消息进行编码没有问题,但我试图在 HTTP POST 请求中使用 JSON 实现相同的结果。

我一直在使用 curlPostman 进行测试,但 Slack 似乎根本不承认我的请求正文。

{
  "ok": false,
  "error": "not_authed"
}

curl,我的请求编码如下:

curl -H "Content-type: application/json" -X POST -d '{"token":"my-token-here","channel":"#channel-name-or-id","text":"Text here.","username":"otherusername"}'

在 Postman 中,这是原始的身体:

{
    "token":"my-token-here",
    "channel":"#channel-name-or-id",
    "text":"Text here.",
    "username":"otherusername"
}

我以前没有做过这样的事情,所以我不确定我是否遗漏了什么。谢谢!

【问题讨论】:

    标签: json api slack-api


    【解决方案1】:

    我有点晚了,但我希望这可以帮助像我一样偶然遇到这个问题的其他人。我刚刚与 Slack 取得联系,他们是这样告诉我的:

    Slack Web API 根本不接受 JSON 数据,因此除了更改 Content-Type 之外,还应使用标准 HTTP 表单属性发布这些变量。

    我们计划在未来支持 JSON 数据以保持未来的一致性。

    因此,您的 cURL 行应如下所示:

    curl -X POST -d 'token=my-token-here&channel=#channel-name-or-id&text=Text here.&username=otherusername'`
    

    我希望这会有所帮助! :)

    【讨论】:

    • 我喜欢他们实际上从未在文档中真正说明这一点,而是在 JSON 中给出每个示例,就好像 Web 开发人员会看着它并思考,当然我会形成编码我的 JSON 对象并将其插入查询字符串。这很有意义。
    • 这太烦人了。一些 api 调用甚至支持发送 curl -d 'payload={"json":"wtf"}'。文档对此太模棱两可了。
    • 所有这些 Json 示例简直太疯狂了,而且 api 实际上根本没有使用 Json 对象。他们甚至有一个消息构建器,您可以在其中在 Json 中构建复杂的消息,但实际上您必须将 Json 分割成一个查询字符串才能使其真正起作用。
    • 所以它不需要JSON,而是用JSON响应......这没有意义!
    • 这太愚蠢了,我再也回不来我浪费在这上面的三个小时了
    【解决方案2】:

    好的,在重新阅读文档后我找到了它:

    JSON 编码的正文

    对于这些写入方法,您也可以发送 HTTP POST 数据作为内容类型:application/json。

    有一些基本规则:

    • 您必须将 Content-type HTTP 标头显式设置为 application/json。没有它,我们不会解释您的 POST 正文。
    • 您必须在 Authorization HTTP 标头中将您的令牌作为不记名令牌传输。
    • 您不能将令牌作为查询字符串的一部分或作为已发布 JSON 中的属性发送。
    • 不要在查询字符串、URL 编码的 POST 正文和 JSON 属性之间混合使用参数。为每个请求选择一种方法。
    • 为属性提供显式空值将导致为其分配任何默认行为。

    还有curl 示例。注意 Authorization 标头。

    curl -X POST \
         -H 'Authorization: Bearer xoxb-1234-56789abcdefghijklmnop' \
         -H 'Content-type: application/json; charset=utf-8' \
        --data '{"channel":"C061EG9SL","text":""..."}' \
    https://slack.com/api/chat.postMessage
    

    【讨论】:

    • 谢谢,我错过了授权标头。
    • 这里没有说,但绝对需要,还包括字符集:-H 'Content-Type: application/json;字符集=utf-8' \
    【解决方案3】:

    这可能不符合完整答案,但如果目的是发送邮件附件,可以发送urlencoded JSON结构作为attachments参数的值,像这样(分成多行为清楚起见):

    https://slack.com/api/chat.postMessage?
    token=YOUR-TOKE-N000&
    channel=%23alerts&
    text=Hi&
    attachments=%5B%7B%22color%22%3A%22good%22%2C%22fallback%22%3A%22plain+text%22%2C%22text%22%3A%22colored+text%22%7D%5D
    

    attachments 的值是 URL 编码的 [{"color":"good","fallback":"plain text","text":"colored text"}]。您应该可以使用所有附件属性described here

    【讨论】:

      【解决方案4】:

      截至 2018 年 3 月Slack 现在支持带有 JSON 正文的 POST

      端点https://slack.com/api/chat.postMessage

      标题Authorization: Bearer xoxp-your-hardly-find-token-here

      正文{"channel":"CH9NN37","text":"something from me!"}

      注意 Bearer Authorization 标头。

      【讨论】:

      • 2017 年 11 月以来我一直在使用这个 API - 我在 1 月 9 日写了这个问题的答案:stackoverflow.com/a/48178295/1428679 - 据我所知,你的例子是完全一样的。我错过了什么,还是有一些文档混乱?
      【解决方案5】:

      Slack 已更新,现在可以使用。试试这个例子:

      curl -X POST -H 'Content-type: application/json' --data '{"text":"This is a line of text.\nAnd this is another one."}' https://hooks.slack.com/services/AAAAAA/BBBBBB/CCCCCC
      

      有关文档,请参阅 https://api.slack.com/incoming-webhooks

      【讨论】:

      • 这(还)似乎不适用于通用 Web API;仅适用于(传入的)webhook(我认为,它甚至不需要通过令牌进行身份验证,如问题示例中所示)。
      • 这个有限的例子按原样工作。我们在生产中使用它。
      【解决方案6】:

      尝试将每个属性放在自己的 -d 参数中,如下所示:

      curl https://slack.com/api/chat.postMessage -X POST -d "channel=#tehchannel" -d "text=teh text" -d "username=teh user" -d "token=teh-token-you-got-from-teh-page-that-machinehead115-linked-to" -d "icon_emoji=:simple_smile:"
      

      【讨论】:

        【解决方案7】:

        在邮递员上,您可以像这样构建您的请求:

        网址(POST):https://slack.com/api/chat.postMessage

        然后在Headers部分下放这两个标题:

        1. 键(Content-Type)值(application/json

        2. 键(Authorization)值(YOUR-TOKEN-NAME

        然后在Body 部分的raw 表单中输入您的数据:

            {"channel": "CHANNEL-NAME", "data": "You better post this to channel"}
        

        【讨论】:

        • 在正文部分使用“文本”而不​​是“数据”
        【解决方案8】:

        not_authed 表示未提供身份验证令牌。

        您在请求中传递了哪个令牌?您需要传递您的 OAuth 令牌,您可以从 here 获取。

        【讨论】:

        • 我设法在 GET 请求和 POST 表单正文中传递了我的令牌。 (那些返回 channel_not_found。)我怀疑 Slack 只是不接受 POST 正文中的 JSON。
        【解决方案9】:

        我在 powershell 中做了这个,它就像一个魅力。

        $url="https://slack.com/api/chat.postMessage"
            $messageContent= # your message here
            $token = # your token here
            $channel = # channel name
            $opt_username= # optional user name
        
            $body = @{token=$token;channel=$channel;username=$opt_username;text=$messageContent;pretty=1}
        
            try
            {
                Invoke-WebRequest -Uri $url -Method POST -Body $body
            }
            catch
            {
                Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
                Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription        
            }
        

        【讨论】:

          【解决方案10】:

          如果你使用 java 和 spring 这样的依赖,瞧!给你

               * Make a POST call to the chat.PostMessage.
               */
              public void chatPostMessage(Message message)
              {
                  RestTemplate restTemplate = new RestTemplate();
          
                  HttpHeaders headers = new HttpHeaders();
                  headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
          
                  MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
                  map.add("token", slackPostMessageToken); //Required
                  map.add("text", message.getText());//Required
                  map.add("channel", message.getChannelId());//Required
          
                  map.add("unfurl_links","true");
                  map.add("as_user","false");//Default false
                  map.add("icon_emoji",":chart_with_upwards_trend:");
                  map.add("attachments","[\n" +
                          "        {\n" +
                          "            \"fallback\": \"Required plain-text summary of the attachment.\",\n" +
                          "            \"color\": \"#36a64f\",\n" +
                          "            \"pretext\": \"Optional text that appears above the attachment block\",\n" +
                          "            \"author_name\": \"Bobby Tables\",\n" +
                          "            \"author_link\": \"http://flickr.com/bobby/\",\n" +
                          "            \"author_icon\": \"http://flickr.com/icons/bobby.jpg\",\n" +
                          "            \"title\": \"Slack API Documentation\",\n" +
                          "            \"title_link\": \"https://api.slack.com/\",\n" +
                          "            \"text\": \"Optional text that appears within the attachment\",\n" +
                          "            \"fields\": [\n" +
                          "                {\n" +
                          "                    \"title\": \"Priority\",\n" +
                          "                    \"value\": \"High\",\n" +
                          "                    \"short\": false\n" +
                          "                }\n" +
                          "            ],\n" +
                          "            \"image_url\": \"http://my-website.com/path/to/image.jpg\",\n" +
                          "            \"thumb_url\": \"http://example.com/path/to/thumb.png\",\n" +
                          "            \"footer\": \"Datoo ©\",\n" +
                          "            \"ts\": "+System.currentTimeMillis()+"" +
                          "        }\n" +
                          "    ]");
                  map.add("username","III");
          
          
                  HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
          
                  try {
                      ResponseEntity<String> response = restTemplate.postForEntity(slackPostMessageUrl, request, String.class);
                      System.out.println(response);
                  }
                  catch (RestClientException e) {
                      logger.error("Error :-( : ", e);
                  }
              }
          

          【讨论】:

          • 这对我有帮助... :-)
          【解决方案11】:

          以下 curl 命令对我有用。

          curl -X POST -H 'Authorization: Bearer xoxb-41234078565-14457098702432-ZLJj9UFOZKnOJtjNW4dv3ukG'  -H 'Content-type: application/json; charset=utf-8'  --data '{"channel":"#general","text":"I hope the tour went well, Mr. Wonka."}' https://slack.com/api/chat.postMessage
          
          

          【讨论】:

            猜你喜欢
            • 2012-12-04
            • 2013-02-27
            • 2018-08-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-20
            • 2013-11-13
            相关资源
            最近更新 更多