user32829: 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.

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);
    }
  }
}


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

32829: <p>I'm trying to connect an <a href="https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout" rel="nofollow noreferrer">Adafruit Huzzah ESP8266</a> with <a href="https://slack.com" rel="nofollow noreferrer">Slack</a>.</p>

<p>I'm facing an issue with the connection I'd like some help or tips on.  I'm able to get a connection <em>sometimes</em>, 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.</p>

<p>The error I get is usually this:</p>

<pre><code>ssl-&gt;need_bytes=16432 &gt; 6859
</code></pre>

<h1>My Troubleshooting So Far</h1>

<p>As per this github issue:
<a href="https://github.com/esp8266/Arduino/issues/1375" rel="nofollow noreferrer">https://github.com/esp8266/Arduino/issues/1375</a></p>

<p>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.</p>

<p>When it <em>does work</em>, 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.</p>

<p><a href="https://i.stack.imgur.com/QyAEo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QyAEo.png" alt="Slack command to ESP8266"></a></p>

<p>Does anyone have an idea why this sometimes works, and sometimes doesn't?</p>

<p>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?</p>

<p>Any help is greatly appreciated.</p>

<hr>

<h1>Errors in Serial Monitor</h1>

<p>Here's what I see in the Serial Monitor log:</p>

<pre><code>⸮scandone
f r0, scandone
f r0, scandone
state: 0 -&gt; 2 (b0)
state: 2 -&gt; 3 (0)
state: 3 -&gt; 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-&gt;need_bytes=16432 &gt; 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-&gt;need_bytes=16432 &gt; 6859
WebSocket Host=mpmulti-eavp.slack-msgs.com Path=/websocket/HjuUTJUL4ghmBCthwdFxOYNWD0wGjWbCgQZwnum546F5Nj8rrJ7LJgeyVOLqSv9sBHtkZBrCBLyxdM2oMB85-GXGwtIgg9anVYFL66vMB8yEN9Xout7OMmqlEewZsL7n2vqJyvx_qAnQ9M8UwOnZwETkNYJ51XrUvR6EjIAvAQE=
[WebSocket] Connected to: /websocket/HjuUTJUL4ghmBCthwdFxOYNWD0wGjWbCgQZwnum546F5Nj8rrJ7LJgeyVOLqSv9sBHtkZBrCBLyxdM2oMB85-GXGwtIgg9anVYFL66vMB8yEN9Xout7OMmqlEewZsL7n2vqJyvx_qAnQ9M8UwOnZwETkNYJ51XrUvR6EjIAvAQE=
[WebSocket] Disconnected :-( 
ssl-&gt;need_bytes=8496 &gt; 6859
</code></pre>

<h1>My Sketch Code</h1>

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

<pre class="lang-cpp prettyprint-override"><code>#include &lt;Arduino.h&gt;

#include &lt;ESP8266WiFi.h&gt;
#include &lt;time.h&gt;
#include &lt;ESP8266WiFiMulti.h&gt;
#include &lt;ESP8266HTTPClient.h&gt;

#include &lt;WebSocketsClient.h&gt;
#include &lt;ArduinoJson.h&gt;

#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 "., \"'()[]&lt;&gt;;:-+&amp;?!\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&amp; 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-&gt;find("wss:\\/\\/");
  String host = client-&gt;readStringUntil('\\');
  String path = client-&gt;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 &gt; 5000) {
      sendPing();
      lastPing = millis();
    }
  } else {
    // Try to connect / reconnect to slack
    connected = connectToSlack();
    if (!connected) {
      delay(500);
    }
  }
}
</code></pre>
 33070: <p>replace <code>rtm.start</code> with <code>rtm.connect</code> as per April 2017 Recent Updates log</p>
