ESP32からLINE Notifyに通知を投げる手順の備忘録


先日、「ニューノーマルにカラオケをハックせよ Sponsored by JOYSOUND #protoout」というハッカソンが行われ、そこに参加してきました。
その際に作成したシステムを参考に、ESP32からLINE Notifyに通知を投げてみましたので、その備忘録を残しておきます。
(よくある仕組みなので、ほかの記事等Web上にやたら転がっている内容です)

当日作成したシステム

当日作成したのは、超音波距離センサーで距離を測り、一定値より近ければobnizからLINE Notifyに通知を飛ばすというものでした。
カラオケでもソーシャルディスタンス

こちらは一緒のチームの方のところにセンサー&マイコンがあったのですが、私のところには無かったので、あるもので作り変えてみました。

材料

  • 開発用PC
  • USBケーブル(PC-ESP32開発ボードの接続)
  • ESP32開発ボード
  • ブレッドボード
  • ケーブル(オス-オス、3本)
  • ボタン(Grove) ※4ピンケーブルも

obnizがESP32開発ボードに、超音波距離センサーがボタンに変更になっています。
また、ESP32開発ボードとボタンを無理やり接続しています。

接続

ESP32開発ボードをブレッドボードに刺し、ボタンと接続します。

  • 電圧:3.3Vか5V
  • GND
  • デジタル信号:IO4に接続

LINE側の設定

こちらの情報はそこらじゅうにありますが、画像が載っていてわかりやすいのはこちらかも。
※写真を撮るために新たに設定しなおすとトークンが変わっちゃうから、ここでは画像は無しです

  1. LINE Notifyにログイン
  2. 「マイページ」を選択
  3. 「トークンを発行する」を選択
  4. 「トークン名」を入力
    ここで入力した名前が、飛んでくるメッセージの先頭に[xxxx]と表示されます
  5. 通知の送信先を選択
    自分だけでよければ「1:1でLINE Notifyから通知を受け取る」を選択し、グループの場合はそのグループを選択(事前に作成する必要あり)
  6. 「発行する」ボタンを選択
  7. 発行されたトークンをメモっておく
    後で使いますので、絶対に忘れないように(後から確認できません)

Arduino側のプログラム

こちらはスケッチの「WiFiClientSecure」をベースにします。

CAの削除

今回は証明書を使わないため、ばっさり証明書関連のコードを削除します。
以下、削除する部分。

const char* test_root_ca= \
(省略)
     "-----END CERTIFICATE-----\n";
  client.setCACert(test_root_ca);

Wi-Fiの設定

アクセスポイントのSSIDとパスワードを設定します。
それぞれの環境に合わせて、修正してください。

const char* ssid     = "my-ssid";     // change
const char* password = "my-password"; // change

LINE Notify関連の設定

まず、LINE NotifY関連の変数を用意します。

const char* host = "notify-api.line.me";
const char* token = "my-line-notify-token"; // change

元のソースでは「server」となっているところを「host」に書き換えています。
また、トークンは、先ほどメモっておいたものに書き換えてください。

センサー関連の設定

今回は、ボタンを押したら通知が飛ぶようにします。
まずピン番号を指定します。今回は4ピンに接続しています。

#define BUTTON_PIN 4

さらに、ボタンを押したときに送られるメッセージを設定しておきます。

const char* message = "Push!";

また、1回ボタンを押すと大量に通知が飛んでしまうため、制御のためのフラグを用意しておきます。

static int Status = LOW;

そして初期化時に、PINの初期化を行います。

  pinMode(BUTTON_PIN, INPUT);

ループ内での処理

ループ内では、大きくは以下のような処理を行います。

  1. ボタンのステータスを取得
  2. 前回ボタンが押されていなかった、かつ、今回ボタンが押されたら、LINE Notifyに通知を送る
  3. ボタンのステータスを保存

LINE NotifyへはWeb APIで直接通知を送ります。
結果を受け取る際、ヘッダ部分を本体部分に分けて受け取っています。
受け取った内容は、シリアルモニタで確認できます。

  int buttonState = digitalRead(BUTTON_PIN);

  if ((Status == LOW) && (buttonState == HIGH)) {
    String query = String("message=") + String(message);
    String request = String("") +
                 "POST /api/notify HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Authorization: Bearer " + token + "\r\n" +
                 "Content-Length: " + String(query.length()) +  "\r\n" + 
                 "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                  query + "\r\n";
    client.print(request);

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      Serial.println(line);
      if (line == "\r") {
        break;
      }
    }

    String line = client.readStringUntil('\n');
    Serial.println(line);
  }

  Status = buttonState;
  delay(500);

LINE Notifyとの送受信処理はこちらを参考にさせていただきました。

通知画面

こんな感じに通知が飛びます。
※こちらは、トークン名が「sensor_user」、通知メッセージが「ソーシャルディスタンスを守ってください。」の場合

注意事項

  • トークンは1ユーザ1つしか作れません
  • 1トークンに結び付けられるグループ(または本人)は1つです

感想

CAの設定無しでつながるとは思ってませんでした。
LINE Notifyにつながってしまえば、後は簡単です。

なお、ソース全体はこちらです。