Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@yusukeyusuke

esp8266でSlackBotを作ってIFTTTからのメッセージを待ち受けする

esp8266のSlackBotをIFTTT経由で操作する

背景

GoogleHomeからesp8266を制御しようとしたときに、IFTTT-Slack経由が一番ラクにできそうだったのでトライしてみた。

用意するもの

esp8266(WROOM02)

参考サイトをみてSlackBotをつくる

Arduino(ESP8266)にSlack Botを乗せてみた

ちょっとだけトラブル発生

参考サイト通りにやると人間の投稿には反応できるけど、IFTTTからのメッセージには反応してくれない。
シリアルログをみるとIFTTTからのメッセージは添付扱いになっているため、すこし階層が深くなっている模様。

対策版

かなりやっつけだけど「root["attachments"][0]["pretext"]」でIFTTTからのメッセージを参照できた。
ソースコードは以下。

// https://github.com/urish/arduino-slack-bot

#include <Arduino.h>
#include <Hash.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include <Servo.h>

#define WIFI_SSID "あなたのSSID"
#define WIFI_PASSWORD "あなたのWIFIパスワード"

#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 "スラックボットのTOKEN"
#define DEFAULT_CHANNEL "チャンネルID?"

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;

long nextCmdId = 1;
bool connected = false;
bool helloSaid = false;

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

    case WStype_TEXT:
      Serial.printf("[WebSocket] Message: %s\n", payload);
      processSlackMessage((char*)payload);
      break;
  }
}

void processSlackMessage(char *payload) {
  StaticJsonBuffer<2000> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(payload);
  if (!root.success()) {
    Serial.println("[Json] Parse failed");
    return;
  }

  if(root.containsKey("type")) {
    if(strcmp("hello", root["type"]) == 0) {
      helloSaid = true;
    } else if (strcmp("message", root["type"]) == 0) {
      if(root.containsKey("attachments")) {
        if(strcmp("IFTTT経由メッセージのキーワード", root["attachments"][0]["pretext"]) == 0) {
          // キーワードを見つけたときの処理
        }
      }else if(root.containsKey("text")) {
        if(strcmp("通常メッセージのキーワード", root["text"]) == 0) {
          // キーワードを見つけたときの処理
        }
      }
    }
  }
}

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 sendPing() {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["type"] = "ping";
  root["id"] = nextCmdId++;
  String json;
  root.printTo(json);
  webSocket.sendTXT(json);
}

void sendMessage() {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["type"] = "message";
  root["channel"] = DEFAULT_CHANNEL;
  root["text"] = "fuga";
  String json;
  root.printTo(json);
  webSocket.sendTXT(json);
}

void setup() {
  servo.attach(servoPin);
  servo.write(angle);
  Serial.begin(9600);
  while (!Serial) {
    delay(100);
  }
  Serial.setDebugOutput(true);

  WiFiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
  while (WiFiMulti.run() != WL_CONNECTED) {
    delay(100);
  }

  configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
}

unsigned long lastPing = 0;

void loop() {
  webSocket.loop();

  if (connected) {
    // Send ping every 5 seconds, to keep the connection alive
    if (millis() - lastPing > 5000) {
      if(helloSaid) {
        sendPing();
      }
      lastPing = millis();
    }
  } else {
    // Try to connect / reconnect to slack
    connected = connectToSlack();
    if (!connected) {
      delay(3000);
    }
    lastPing = millis();
  }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What are the problem?