いっぺーちゃんの いろいろやってみよ~

Espruino on ESP32 で Twitter(その2)

以下がtwitterにアクセスするためのモジュールです。
さらっと書いてますが、血と汗と涙の結晶です。

====2017/08/03追記 ここから====

 Espruino on ESP32 で Twitter にも日本語を - いっぺーちゃんの いろいろやってみよ~で新しいバージョンを公開しました

====2017/08/03追記 ここまで====

 

====2017/08/03削除 ここから====

tiny_twitter.zip

zipファイルを解凍してオンボードストレージの /node_modules ディレクトリに格納してください。

 

====2017/07/30追記 ここから====

 Node.jsで実行するとエラーになりました。
Espruino用HMACSHA1モジュールの仕様を変更したのを忘れてました(^^ゞ
以下の修正で使用できるようになります。

--- tiny_twitter.js.old2	2017-07-30 11:37:47.540869675 +0900
+++ tiny_twitter.js	2017-07-30 11:40:36.641894478 +0900
@@ -113,7 +113,11 @@
     // make signature
     var signing_key = RFC3986_encode(this.consumer_secret) + '&' + RFC3986_encode(this.access_secret);
     // console.log("key:" + signing_key);
-    var sig = hmacsha1.b64(signing_key, sigbase_str);
+    if (platform == 'node') {
+        var sig = hmacsha1(signing_key, sigbase_str);
+    } else {
+        var sig = hmacsha1.b64(signing_key, sigbase_str);
+    }
     this.degug_print('sig: ' + sig);
 
     var oauth_head  = '        OAuth oauth_consumer_key="'    + RFC3986_encode(this.consumer_key) + '",\n' 

====2017/07/30追記 ここまで====

====2017/08/03削除 ここまで====

 

また、twitterにアクセスするにはアカウントのほか、4つのキーを取得する必要があります。
(Consumer key、Consumer secret、Access Token、Access Token Secret)
自分で手順書くのが面倒なので、先人の成果をパクり、、いやいや参照させて頂くことにします。
ここの手順に従ってキーを取得してください。

TwitterのAPIを使用するために必要なキーを取得する手順 - Hello API

これらのキー(特にsecretと付く方)はパスワードみたいなものなので、取り扱いには十分注意しましょう。
普段使っているアカウントでいきなり変なtweetをすると、フォロワーがびっくりするので、別のアカウントを用意するのが良いかもしれません。

 

 

まずはtweetしてみます。
以下のプログラムを実行してみましょう。

consumer_key    = '取得した Consumer key';
consumer_secret = '取得した Consumer secret';
access_token    = '取得した Access Token';
access_secret   = '取得した Access Token Secret';

if (typeof(ESP32) ==='function') {
    // platform is espruino on ESP32
    // Wi-Fi アクセスポイントへの接続
    var wifi = require('MyWifi');
}
if (typeof(E) ==='function') {
    // platform is espruino
    // set time zone  fixed to 'JST'
    E.setTimeZone(9);
}

// モジュール読み込み
var tiny_twitter = require("tiny_twitter");

// 初期化
var tw = new tiny_twitter(consumer_key, consumer_secret, access_token, access_secret, true);

tw.on("connect", function() {
    console.log("%%%% CONNECTED %%%%");
});
tw.on("response_header", function(data, code, msg) {
    if (code != 200) {
        console.log("%%%% RESPONSE ERROR!!!   " + code.toString() + " : " + msg);
    }
    console.log("%%%% RESPONSE_HEADER %%%%\n" + data + "\n%%%%%%%%%%%%%%%%%%%%%%%%%");
});
tw.on("data", function(data) {
    console.log("%%%% DATA %%%%");
    console.log(JSON.stringify(data,  null, '\t'));
    // エラー時はdata.errors.code data.errors.message に情報が入る
    console.log("%%%%%%%%%%%%%%%%%%%%%%%%%");
});
tw.on("end", function() {
    console.log("%%%% END %%%%");
});

// tweetする
var message = "test tweet";
var param   = {"trim_user":true,"include_entities":false};
tw.tweet(message, param);

 

成功すれば、「test tweet《改行》(Thu Jul 24 2017 12:29:46 GMT+0900)」のようにtweetされるはずです。

もちろん、ESP32がインターネットにアクセスできるWi-Fiルータにつながってなければ、失敗します。
もし、時刻があってないと(そんなに厳密でなくてもかまいません。何時間とか何日レベルでずれている場合)は、エラーになりますので、時刻合わせを行っておいてください。
tweetするメッセージに時刻を追加するようにしてあります。これは同じメッセージを短い時間内にtweetすると「それ、さっき呟いたやんけ~」とエラーになるため、それを回避するためにtweet処理の中で時刻を付加しています。

調子に乗って何回もtweetしてると、アカウントをロックされることがありますので、注意してください。

 

以下処理の説明です。

ESP32の場合はWi-Fiに接続します。
接続状態を維持しているならここはなくても構いません。前に書いたMyWifi.jsを使用しています。
ESP32上のEspruinoだと、「ESP32」というbuilt-in moduleが存在するので、それで判断しています。

if (typeof(ESP32) ==='function') {
    // platform is espruino on ESP32
    // Wi-Fi アクセスポイントへの接続
    var wifi = require('MyWifi');
}

 

 Espruinoの場合はタイムゾーンを設定します。
Espruinoだと、「E」というbuilt-in moduleが存在するので、それで判断しています。
ここはLinux版Espruinoの場合も実行されます。
Espruinoでしか使わないならいきなりタイムゾーン設定でも構いません。

if (typeof(E) ==='function') {
    // platform is espruino
    // set time zone  fixed to 'JST'
    E.setTimeZone(9);
}

 なぜ、こんなコードを入れているのか?
いい質問ですねぇ~。
このプログラム、実はnode.jsでも動くんです。
デバッグしやすいので、最初node.jsでデバッグしてた名残です。
せっかくなので、残しておきました。
node.js⇔Linux版Espruinoを行き来しながらデバッグして、最後にESP32で動作確認、な感じでデバッグしてました

 

 モジュールを読み込みます。
これをしないと始まりません。

var tiny_twitter = require("tiny_twitter");

 

 tiny_twitterインスタンスを生成します。
パラメータの最初の4つは↑で取得したキーです。最後のパラメータはモジュール内部のdegug_print (あ、typoだ。めんどいからそのままで)を表示するか否かを指定しています。
色々表示されてうっとうしい場合はfalseにしてください。

var tw = new tiny_twitter(consumer_key, consumer_secret, access_token, access_secret, true);

 

 サーバに接続されたときのイベントハンドラです。
特に処理はないので、接続した旨表示しているだけです。

tw.on("connect", function() {
    console.log("%%%% CONNECTED %%%%");
});

 

 受信データのうち、ヘッダ部分を受信したときのイベントハンドラです。
codeが200以外のときは、接続エラーなので、エラーと表示しています。
また、デバッグ用にヘッダ全体を表示しています。

tw.on("response_header", function(data, code, msg) {
    if (code != 200) {
        console.log("%%%% RESPONSE ERROR!!!   " + code.toString() + " : " + msg);
    }
    console.log("%%%% RESPONSE_HEADER %%%%\n" + data + "\n%%%%%%%%%%%%%%%%%%%%%%%%%");
});

 

 受信データのうち、データの中身を受け取ったときのイベントハンドラです。
データはJSON形式で送られてくるので、JSON.stringifyで文字列化して表示しています。

tw.on("data", function(data) {
    console.log("%%%% DATA %%%%");
    console.log(JSON.stringify(data,  null, '\t'));
    // エラー時はdata.errors.code data.errors.message に情報が入る
    console.log("%%%%%%%%%%%%%%%%%%%%%%%%%");
});

 

 サーバとの接続が切断されたときのイベントハンドラです。
特に処理はないので、切断した旨表示しているだけです。

tw.on("end", function() {
    console.log("%%%% END %%%%");
});

 

 実際にtweetする部分です。
paramは APIリファレンス を参照してください。指定しても動くかどうかわかりませんが。。。
この設定だと、受信するデータがちょっと小さくなります。

var message = "test tweet";
var param   = {"trim_user":true,"include_entities":false};
tw.tweet(message, param);

 

 今回はここまで。

 

次回に続く。。。