Espruino on ESP32 で Twitter(その2)
以下がtwitterにアクセスするためのモジュールです。
さらっと書いてますが、血と汗と涙の結晶です。
====2017/08/03追記 ここから====
Espruino on ESP32 で Twitter にも日本語を - いっぺーちゃんの いろいろやってみよ~で新しいバージョンを公開しました
====2017/08/03追記 ここまで====
====2017/08/03削除 ここから====
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);
今回はここまで。
次回に続く。。。