0

I'm trying to use Uri Shaked Slackbot code using an Adafruit Feather Huzzah ESP8266 WiFi.

I have created the Slackbot integration and copied the API key. The code connects to the WiFi and does the time configuration but then hangs when connecting to slack with the error message in the serial monitor.

ssl-need_bytes=16432> 6859

/**
 Arduino Real-Time Slack Bot
 Copyright (C) 2016, Uri Shaked.
 Licensed under the MIT License
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.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 SLACK_BOT_TOKEN "https://slack.com/api/rtm.start?token=[MY TOKEN]" // Get token by creating new bot integration at https://my.slack.com/services/new/bot 
#define WIFI_SSID "[My WIFI]"
#define WIFI_PASSWORD "[WiFi Password]"
#define LEDS_PIN 2
#define LEDS_NUMPIXELS 8
#define WORD_SEPERATORS "., \"'()[]<>;:-+&?!\n\t"
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
Adafruit_NeoPixel pixels(LEDS_NUMPIXELS, LEDS_PIN, NEO_GRB + NEO_KHZ800);
long nextCmdId = 1;
bool connected = false;
/**
 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);
}
/**
 Input a value 0 to 255 to get a color value.
 The colors are a transition r - g - b - back to r.
*/
uint32_t wheel(byte wheelPos) {
 wheelPos = 255 - wheelPos;
 if (wheelPos < 85) {
 return pixels.Color(255 - wheelPos * 3, 0, wheelPos * 3);
 }
 if (wheelPos < 170) {
 wheelPos -= 85;
 return pixels.Color(0, wheelPos * 3, 255 - wheelPos * 3);
 }
 wheelPos -= 170;
 return pixels.Color(wheelPos * 3, 255 - wheelPos * 3, 0);
}
/**
 Animate a NeoPixel ring color change.
 Setting `zebra` to true skips every other led.
*/
void drawColor(uint32_t color, bool zebra) {
 int step = zebra ? 2 : 1;
 for (int i = 0; i < LEDS_NUMPIXELS; i += step) {
 pixels.setPixelColor(i, color);
 pixels.show();
 delay(30 * step);
 }
}
/**
 Draws a rainbow :-)
*/
void drawRainbow(bool zebra) {
 int step = zebra ? 2 : 1;
 for (int i = 0; i < LEDS_NUMPIXELS; i += step) {
 pixels.setPixelColor(i, wheel(i * 256 / LEDS_NUMPIXELS));
 pixels.show();
 delay(30 * step);
 }
}
/**
 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, "zebra") == 0) {
 zebra = true;
 }
 if (strcasecmp(nextWord, "red") == 0) {
 drawColor(pixels.Color(255, 0, 0), zebra);
 }
 if (strcasecmp(nextWord, "green") == 0) {
 drawColor(pixels.Color(0, 255, 0), zebra);
 }
 if (strcasecmp(nextWord, "blue") == 0) {
 drawColor(pixels.Color(0, 0, 255), zebra);
 }
 if (strcasecmp(nextWord, "yellow") == 0) {
 drawColor(pixels.Color(255, 160, 0), zebra);
 }
 if (strcasecmp(nextWord, "white") == 0) {
 drawColor(pixels.Color(255, 255, 255), zebra);
 }
 if (strcasecmp(nextWord, "purple") == 0) {
 drawColor(pixels.Color(128, 0, 128), zebra);
 }
 if (strcasecmp(nextWord, "pink") == 0) {
 drawColor(pixels.Color(255, 0, 96), zebra);
 }
 if (strcasecmp(nextWord, "orange") == 0) {
 drawColor(pixels.Color(255, 64, 0), zebra);
 }
 if (strcasecmp(nextWord, "black") == 0) {
 drawColor(pixels.Color(0, 0, 0), zebra);
 }
 if (strcasecmp(nextWord, "rainbow") == 0) {
 drawRainbow(zebra);
 }
 if (nextWord[0] == '#') {
 int color = strtol(&nextWord[1], NULL, 16);
 Serial.println("Color");
 Serial.print(color);
 if (color) {
 drawColor(color, zebra);
 }
 }
 }
}
/**
 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;
 Serial.printf("Connecting to\n");
 Serial.printf(SLACK_BOT_TOKEN);
 Serial.printf("\n");
 http.begin(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;
 }
 pixels.setPixelColor(3, pixels.Color(0, 2, 0));
 pixels.show();
 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);
 pixels.setPixelColor(4, pixels.Color(0, 2, 0));
 pixels.show();
 return true;
}
void setup() {
 Serial.begin(115200);
 Serial.setDebugOutput(true);
 pixels.begin();
 drawColor(pixels.Color(2, 0, 0), false);
 pixels.setPixelColor(0, pixels.Color(0, 2, 0));
 pixels.show();
 WiFiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
 while (WiFiMulti.run() != WL_CONNECTED) {
 delay(100);
 }
 pixels.setPixelColor(1, pixels.Color(0, 2, 0));
 pixels.show();
 configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
 pixels.setPixelColor(2, pixels.Color(0, 2, 0));
 pixels.show();
}
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);
 }
 }
}
dda
1,5951 gold badge12 silver badges17 bronze badges
asked Mar 1, 2017 at 21:07
3
  • they probably use "too strong" of a cert, according to github.com/esp8266/Arduino/issues/1375. you can use a server-side proxy to talk to both the ESP and the API, using a shorter key cert on the "proxy" Commented Mar 1, 2017 at 22:45
  • Yep, I read igrr's comment. I've downloaded the axTLS library and are trying to tweak it to get it working but no luck so far. Commented Mar 3, 2017 at 7:47
  • @mach I have this exact same issue. I do get mine to connect sometimes, but it's very inconsistent (sometimes it works, sometimes it fails). Once it connects and I get to the repeated pings it works perfectly. Did you find a solution for the ssl-need_bytes error? Commented Apr 15, 2017 at 22:27

1 Answer 1

1

@mach @Axel

I replaced use rtm.start with rtm.connect as per April 2017 Slack Recent Updates https://api.slack.com/changelog and this got rid of the error on my Wemos.

http.begin("https://slack.com/api/rtm.connect?token=" + SLACK_BOT_TOKEN, SLACK_SSL_FINGERPRINT);
sa_leinad
3,2182 gold badges23 silver badges51 bronze badges
answered Apr 22, 2017 at 23:01
1
  • OMG, going to test this tonight! Commented Apr 25, 2017 at 8:21

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.