1

I'm trying to connect an Adafruit Huzzah ESP8266 with Slack.

I'm facing an issue with the connection I'd like some help or tips on. I'm able to get a connection sometimes, but sometimes during the initial step where I'm making the first connection, I get errors and it completely fails, repeating the connect/disconnect over and over again.

The error I get is usually this:

ssl->need_bytes=16432 > 6859

My Troubleshooting So Far

As per this github issue: https://github.com/esp8266/Arduino/issues/1375

My understanding is that the error is caused by Slack's SSL certificate being too large. This makes sense, but sometimes my code (see below) actually works which is why I'm confused.

When it does work, it usually fails a couple times at first, before maintaining a consistent ping with Slack. At that point, it works as expected, and I can send commands from Slack to the board without fail.

Slack command to ESP8266

Does anyone have an idea why this sometimes works, and sometimes doesn't?

I'm assuming it has something to do with the SSL certificate size being too large, but if that was the case why wouldn't it fail each time, but work sometimes?

Any help is greatly appreciated.


Errors in Serial Monitor

Here's what I see in the Serial Monitor log:

⸮scandone
f r0, scandone
f r0, scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 7
cnt 
connected with 2WIRE952, channel 3
dhcp client start...
ip:192.168.1.73,mask:255.255.255.0,gw:192.168.1.254
Waiting for time sync
please start sntp first !
.please start sntp first !
.Sun Apr 16 06:57:35 2017
Time is synced
ssl->need_bytes=16432 > 6859
WebSocket Host=mpmulti-4pcb.slack-msgs.com Path=/websocket/Z5ZDermv9h2Q7HL88ukG5ddIvY--zrBAVCN4423KOy5t_6wN3AW859grAYCYr6L-0l0leeXA3AhlO1VmIxcCopS1pJ-IkrVOdmel50tgcA7hBJwEIkpI-biYnraTFc88K4F6wqL3TE_gi1jU0SJHhR6_aD5435yE8FRALEflTkY=
[WebSocket] Connected to: /websocket/Z5ZDermv9h2Q7HL88ukG5ddIvY--zrBAVCN4423KOy5t_6wN3AW859grAYCYr6L-0l0leeXA3AhlO1VmIxcCopS1pJ-IkrVOdmel50tgcA7hBJwEIkpI-biYnraTFc88K4F6wqL3TE_gi1jU0SJHhR6_aD5435yE8FRALEflTkY=
[WebSocket] Disconnected :-( 
ssl->need_bytes=16432 > 6859
WebSocket Host=mpmulti-eavp.slack-msgs.com Path=/websocket/HjuUTJUL4ghmBCthwdFxOYNWD0wGjWbCgQZwnum546F5Nj8rrJ7LJgeyVOLqSv9sBHtkZBrCBLyxdM2oMB85-GXGwtIgg9anVYFL66vMB8yEN9Xout7OMmqlEewZsL7n2vqJyvx_qAnQ9M8UwOnZwETkNYJ51XrUvR6EjIAvAQE=
[WebSocket] Connected to: /websocket/HjuUTJUL4ghmBCthwdFxOYNWD0wGjWbCgQZwnum546F5Nj8rrJ7LJgeyVOLqSv9sBHtkZBrCBLyxdM2oMB85-GXGwtIgg9anVYFL66vMB8yEN9Xout7OMmqlEewZsL7n2vqJyvx_qAnQ9M8UwOnZwETkNYJ51XrUvR6EjIAvAQE=
[WebSocket] Disconnected :-( 
ssl->need_bytes=8496 > 6859

My Sketch Code

The Sketch file I'm compiling using the Arduino IDE.
Note: be sure to update Wifi + Slack Bot Token if testing 8-)

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <time.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#define SLACK_SSL_FINGERPRINT "AC 95 5A 58 B8 4E 0B CD B3 97 D2 88 68 F5 CA C1 0A 81 E3 6E" // If Slack changes their SSL fingerprint, you would need to update this
#define WIFI_SSID ""
#define WIFI_PASSWORD ""
String SLACK_BOT_TOKEN = ""; // Get token by creating new bot integration at https://my.slack.com/services/new/bot 
#define WORD_SEPERATORS "., \"'()[]<>;:-+&?!\n\t"
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
long nextCmdId = 1;
bool connected = false;
//Timezone Settings
const int timezone = 9; 
const int dst = 0; //daylight savings
/**
 Sends a ping message to Slack. Call this function immediately after establishing
 the WebSocket connection, and then every 5 seconds to keep the connection alive.
*/
void sendPing() {
 DynamicJsonBuffer jsonBuffer;
 JsonObject& root = jsonBuffer.createObject();
 root["type"] = "ping";
 root["id"] = nextCmdId++;
 String json;
 root.printTo(json);
 webSocket.sendTXT(json);
}
/**
 Looks for color names in the incoming slack messages and
 animates the ring accordingly. You can include several
 colors in a single message, e.g. `red blue zebra black yellow rainbow`
*/
void processSlackMessage(char *payload) {
 char *nextWord = NULL;
 bool zebra = false;
 for (nextWord = strtok(payload, WORD_SEPERATORS); nextWord; nextWord = strtok(NULL, WORD_SEPERATORS)) {
 if (strcasecmp(nextWord, "red") == 0) {
 Serial.printf("Yay! Its red.");
 }
 }
}
/**
 Called on each web socket event. Handles disconnection, and also
 incoming messages from slack.
*/
void webSocketEvent(WStype_t type, uint8_t *payload, size_t len) {
 switch (type) {
 case WStype_DISCONNECTED:
 Serial.printf("[WebSocket] Disconnected :-( \n");
 connected = false;
 break;
 case WStype_CONNECTED:
 Serial.printf("[WebSocket] Connected to: %s\n", payload);
 sendPing();
 break;
 case WStype_TEXT:
 Serial.printf("[WebSocket] Message: %s\n", payload);
 processSlackMessage((char*)payload);
 break;
 }
}
/**
 Establishes a bot connection to Slack:
 1. Performs a REST call to get the WebSocket URL
 2. Conencts the WebSocket
 Returns true if the connection was established successfully.
*/
bool connectToSlack() {
 // Step 1: Find WebSocket address via RTM API (https://api.slack.com/methods/rtm.start)
 HTTPClient http;
 http.begin("https://slack.com/api/rtm.start?token=" + SLACK_BOT_TOKEN, SLACK_SSL_FINGERPRINT);
 int httpCode = http.GET();
 if (httpCode != HTTP_CODE_OK) {
 Serial.printf("HTTP GET failed with code %d\n", httpCode);
 return false;
 }
 WiFiClient *client = http.getStreamPtr();
 client->find("wss:\\/\\/");
 String host = client->readStringUntil('\\');
 String path = client->readStringUntil('"');
 path.replace("\\/", "/");
 // Step 2: Open WebSocket connection and register event handler
 Serial.println("WebSocket Host=" + host + " Path=" + path);
 webSocket.beginSSL(host, 443, path, "", "");
 webSocket.onEvent(webSocketEvent);
 return true;
}
void setup() {
 Serial.begin(115200);
 Serial.setDebugOutput(true);
 WiFiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
 while (WiFiMulti.run() != WL_CONNECTED) {
 delay(500);
 }
 //setup network time protocol (ntp)
 configTime(timezone * 3600, dst, "pool.ntp.org", "time.nist.gov"); //configtime is esp8266 function
 Serial.println("\nWaiting for time sync");
 while (!time(nullptr)) {
 Serial.print(".");
 delay(1000);
 }
 Serial.println("Time is synced");
 delay(500);
}
unsigned long lastPing = 0;
/**
 Sends a ping every 5 seconds, and handles reconnections
*/
void loop() {
 webSocket.loop();
 if (connected) {
 // Send ping every 5 seconds, to keep the connection alive
 if (millis() - lastPing > 5000) {
 sendPing();
 lastPing = millis();
 }
 } else {
 // Try to connect / reconnect to slack
 connected = connectToSlack();
 if (!connected) {
 delay(500);
 }
 }
}
VE7JRO
2,51519 gold badges27 silver badges29 bronze badges
asked Apr 15, 2017 at 23:08
7
  • it probably works sometimes becuase you happen to have enough RAM at that moment. You can try reducing RAM usage with the F() macro on long stings, and removing any libs you don't need. The sure-fire way is to proxy the request to slack using something like a php server with a smaller SSL cert; you then talk to the PHP box instead of slack, and it relay's the request/response back to the ESP. Commented Apr 16, 2017 at 21:51
  • @dandavis - I think you're spot on. Reducing the amount of code in the Sketch and testing again makes it more reliable, but simply not enough still to ensure 100% bulletproof. The response back from Slack is simply too large to handle. I'm just going to use a Raspberry Pi to communicate with Slack, and then send the commands down to an Arduino. Commented Apr 19, 2017 at 23:00
  • @Axel, the PI actually also has GPIO pins (3.3V!) and should be able to handle basic I/O, so you might even consider letting out the Arduino. Commented Feb 19, 2018 at 18:12
  • @Paul - I actually ended up using a Raspberry PI Zero W which ended up having the memory requirements that could handle my API calls, and all the other functionality built such as WIFI and GPIO pins. Not bad for a 10ドル board. Commented Feb 20, 2018 at 20:44
  • @Axel Arduino's are development boards for microcontrollers which is a quite different thing. If you're going to mass produce, using microcontrollers (the chip on the Arduino itself) works very well (stable, reliable, cheap, small). Commented Feb 21, 2018 at 7:57

1 Answer 1

2

replace rtm.start with rtm.connect as per April 2017 Recent Updates log

jfpoilpret
9,1627 gold badges38 silver badges54 bronze badges
answered Apr 23, 2017 at 20:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.