ESP32からBOCCOのメッセージを取得しよう!

5 min read読了の目安(約4500字

はじめに

試しにzennに書いてみます。
ユカイ工学から開発した家族をつなぐコミュニケーションロボットのBOCCOです。
BOCCOに話しかけると、それが音声メッセージとして送信され、スマートフォンからはテキストか音声でメッセージを送信することができます。
子供、両親、祖父母などのスマートフォンの操作ができない家族とも簡単にコミュニケーションをとることができる、そんなコミュケーションロボットです。

BOCCOには開発者向けに、BOCCOに自由な言葉をしゃべらせたりデータを取得したりすることができるようにAPIが公開されています。
BOCCO API 概要 | BOCCO API Documentation

少し前にESP32からBOCCOを発話できるようにESP8266向けのAPIを改良してみました。
BOCCO APIをつかってみよう!-ESP32と定型文ボタン-
BOCCO APIをつかってみよう!-Web APIと国際宇宙ステーション-

そこで、今回はBOCCOとそのAPIをつかって、送信されたメッセージBOCCOからESP32で取得できるようにしてみました。このESP32用のAPIはこちらに公開しており、ダウンロードしたライブラリをArduino IDEに追加して使用してください。

ESP32でBOCCO APIからメッセージを取得するためにライブラリを改良

プログラムはこちらにあげてあります。
プログラムにはbocco_api.cppとbocco_api.hに下記をつけくわえました。
解説は下記のコードのコメントアウトに簡単に追加していきます。

bocco_api.cpp

/** 最新のメッセージを取得する **/
// 263 ~ 282行目
String BoccoAPI::getMessageText(){
  //GETパラメータを作る
  const String data = "access_token="+this->accessToken;
  const String url = BoccoAPI::API_ROOMS+"/"+this->firstRoomId+BoccoAPI::API_ROOMS_MESSAGES;

  //JSONを取得
  //https://api.bocco.me/alpha/rooms/{room_id}/messages?access_token={access_token}のURLでGETリクエストを送っている
  String json = this->get(url,data,BoccoAPI::RETRY_CNT);
  
  //30件のメッセージに関する情報がjsonでかえってくるので、大きめの容量を指定した。
  const size_t capacity = 50000;
  DynamicJsonDocument doc(capacity);
  deserializeJson(doc, json);
  //0番目の要素が一番古いメッセージ
  JsonObject root_29 = doc[0];
  // 30番目の要素が一番新しいメッセージ(0からのカウントなので、下記の番号は29となっている)
 // JsonObject root_29 = doc[29];
  // JSON形式のレスポンスでtextという項目にメッセージが格納されている
  const char* root_29_text = root_29["text"];
  //抽出したtextをString型に変換にして返り値に指定する
  String root_29_text_str = root_29_text;

  return root_29_text_str;
}

bocco_api.h
// 19 ~ 26行目
public:
  bool createSessions();
  void setAccessToken(const char* accessToken);
  bool getFirstRoom();
  // bool getSecondRoom();
  bool postMessageText(const char* text);
  // 追加
  String getMessageText();

ESP32からBOCCOのメッセージを取得するサンプル

雑なサンプルコードですが下記に示します。
APIを使用するのに必要な情報は各自で用意しましょう(xxxxxxxxxと書かれている部分に記載する)。
ESP32 dev moduleについているボタンを押すとBOCCOに送信されたメッセージをコンソール画面に表示してくれます。

sample2

#include <WiFiManager.h>
#include <WiFi.h>

#include "config.h"
#include "bocco_api.h"

//BOCCO API ライブラリ
//BOCCO アカウント情報
#define BOCCO_EMAIL     "xxxxxxxxx"
#define BOCCO_PASSWORD  "xxxxxxxxx"
#define BOCCO_API_KEY   "xxxxxxxxx"
//初期設定の為のアクセスポイント名
#define AP_NAME "test"

BoccoAPI boccoAPI(BOCCO_EMAIL, BOCCO_PASSWORD, BOCCO_API_KEY);


//プッシュスイッチ
#define SW 0
#define PIN 2
#define PIN2 4

//変数初期化
int valueSW = HIGH;
int valueSW2 = 1;
int valueSW3 = 1;

//ボタン割り込み
void clickSw(){
  Serial.println("clickSw");
  valueSW = digitalRead(SW);
  Serial.println(valueSW);
}

void greetingSw(){
  Serial.println("Sw");
  //valueSW2 = digitalRead(PIN);
  Serial.println(digitalRead(PIN));
  valueSW2 = digitalRead(PIN);
}

void greetingSw2(){
  Serial.println("Sw");
  //valueSW2 = digitalRead(PIN);
  Serial.println(digitalRead(PIN2));
  valueSW3 = digitalRead(PIN2);
}

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

  WiFiManager wifiManager;
  wifiManager.setTimeout(180);
  if(!wifiManager.autoConnect(AP_NAME)) {
    Serial.println("timeout");
    delay(3000);
    //初期設定が成功シない場合 reset して初期設定をリトライする
    ESP.restart();
    delay(5000);
    return;
  }
  //ルーターとの接続に成功
  Serial.println("connected...");
  delay(1000);

  //BOCCO アクセストークンを取得する
//  if(!boccoAPI.createSessions() ){
//    Serial.println("BOCCO アクセストークン取得に失敗");
//    return;
//  }

  //アクセストークンを設定
  boccoAPI.setAccessToken("xxxxxxxxxx");

  //BOCCO 1番目のルームを取得
  if(!boccoAPI.getFirstRoom()){
      Serial.println("BOCCO ルーム取得に失敗");
      return;
  }

  //boccoAPI.postMessageText("テストテスト");

  //ボタン割り込み設定
  pinMode(SW, INPUT_PULLUP);
  attachInterrupt(SW, clickSw, CHANGE );

}



void loop() {
  if(digitalRead(SW) == LOW){
    Serial.println("test");
    Serial.println(boccoAPI.getMessageText());
  }
  delay(500);
}

すると、このように動作することが確認できます。
部屋センサが明るくなったという意味の「Brighter」がかえってきました。
image.png

おわりに

BOCCO APIをつかうためのESP32用ライブラリを改良することでBOCCOからメッセージを取得することができることがわかりました。BOCCOの発話とメッセージの取得の両方を組み合わせると何か面白いものがつくれそうです。