在 Arduino 下的 slack bot 上找不到频道,但 Bash

Channel not found on slack bot under Arduino, but not Bash

我正在尝试使用 Arduino 在 Slack 上发送 post 消息,但它总是 returns "channel_not_found" 错误。 我尝试使用不同格式定义频道:

    client.println("POST " PATH " HTTP/1.1");
    client.println("Content-type: application/json");
    client.println("Authorization: Bearer " TOKEN);
    client.println("Host: " SERVER);
    client.println("Connection: close");
    client.println();  // Separate header from content. Important!
    client.println("{\"channel\":\"C01750LNGAU\", \"text\":\":tada:\"}");
    //OR: client.println("{\"channel\":\"#project-coffee\", \"text\":\":tada:\"}");
    //OR: client.println("{\"channel\":C01750LNGAU, \"text\":\":tada:\"}");

同样使用URL编码内容类型:

    client.println("POST " PATH " HTTP/1.1");
    client.println("Content-type: application/x-www-form-urlencoded");
    client.println("Authorization: Bearer " TOKEN);
    client.println("Host: " SERVER);
    client.println("Connection: close");
    client.println();
    client.println("channel=C01750LNGAU&text=:tada:");
    //OR client.println("channel=project-coffee&text=:tada:");
    //OR client.println("channel=#project-coffee&text=:tada:");
    //OR client.println("channel=\#project-coffee&text=:tada:");

为了比较,使用具有相同参数的Bash,它有效: curl -F token=xoxb-12... -F channel=project-coffee -F text="Blabla" https://slack.com/api/chat.postMessage,所以机器人的权限是正确的。 我怀疑我在做一些微妙的愚蠢的事情,但我看不到什么。

频道是public,机器人有权限

供参考,here is the documentation of postMessage and here是一个例子。

完整代码包含在这里:

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"


char ssid[] = SECRET_SSID; 
const char password[] = SECRET_PASS;
int status = WL_IDLE_STATUS;

// POST parameters
// curl -F token=xoxb-12... -F channel=project-coffee -F text="Blabla" https://slack.com/api/chat.postMessage

const char* serverName = "slack.com/api/chat.postMessage";
const char* post_channel="project-coffee";
const int port = 443;


#define SERVER "slack.com"
#define PATH   "/api/chat.postMessage"

WiFiSSLClient client;


void setup() {
  Serial.begin(115200);

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    Serial.flush();

    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, password);
  }

  // you're connected now, so print out the data:
  Serial.println("You are connected to the network");
  Serial.flush();

  if (client.connect(SERVER, 443)) {
    Serial.println("connected to Slack");

    client.println("POST " PATH " HTTP/1.1");
    client.println("Content-type: application/json");
    //client.println("Content-type: application/x-www-form-urlencoded");
    client.println("Authorization: Bearer " TOKEN);
    client.println("Host: " SERVER);
    client.println("Connection: close");
    client.println();  // Separate header from content. Important!
    //client.println("{\"channel\": \"#project-coffee\", \"text\": \":tada:\"}");
    client.println("{\"channel\": \"C01750LNGAU\", \"text\": \":tada:\"}");
    //client.println("{\"channel\": C01750LNGAU, \"text\": \":tada:\"}");
    //client.println("channel=C01750LNGAU&text=:tada:");
    //client.println("channel=project-coffee&text=:tada:");
    //client.println("channel=#project-coffee&text=:tada:");
    //client.println("channel=\#project-coffee&text=:tada:");
    Serial.println();

  }
}


uint32_t bytes = 0;
void loop() {

  while (client.available()) {
    char c = client.read();
    Serial.write(c);
    bytes++;
  }
  if (!client.connected()) {
  Serial.println();
  Serial.println("disconnecting from server.");
  client.stop();
  Serial.print("Read "); Serial.print(bytes); Serial.println(" bytes");

  // do nothing forevermore:
  while (true);
  }
}

完整的回复是:

date: Sun, 06 Sep 2020 13:46:30 GMT
server: Apache
x-slack-req-id: ****
x-oauth-scopes: chat:write,channels:read,groups:read,mpim:read,im:read
x-accepted-oauth-scopes: chat:write
access-control-expose-headers: x-slack-req-id, retry-after
x-slack-backend: r
x-content-type-options: nosniff
expires: Mon, 26 Jul 1997 05:00:00 GMT
cache-control: private, no-cache, no-store, must-revalidate
x-xss-protection: 0
vary: Accept-Encoding
pragma: no-cache
access-control-allow-headers: slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, x-b3-flags
strict-transport-security: max-age=31536000; includeSubDomains; preload
referrer-policy: no-referrer
access-control-allow-origin: *
connection: close
transfer-encoding: chunked
content-type: application/json; charset=utf-8
x-via: haproxy-www-3rug,haproxy-edge-fra-eynl

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

正在将 POST 发送到 postman-echo.com,这会响应您发送的请求,我可以看到 body 是空的。

原来我在 header、Content-Length 中遗漏了一个必填字段。缺失时,似乎 Slack 和邮递员默认为 0。 解决方案?在header中添加:

client.println("Content-Length: 42");