Twitter API から Arduino – ESP32 を使ってトレンドツイートを取得してみた

ESP32 ( ESP-WROOM-32 )

Twitter APIs からトレンドデータ取得するための HTTP リクエスト方法

Twitter API から Tweet を取得するために一番やりやすい方法は、HTTP リクエストを送ることです。
そうすれば、JSON形式のテキストファイルでツイートを取得できます。

その方法はTwitter Developer の以下のリンクに書かれていますので、合わせてご参照ください。

https://developer.twitter.com/en/docs/authentication/oauth-1-0a/authorizing-a-request

そこでは、ツイッターを投稿する場合として、メソッドをPOST として書かれていますが、ここではツイートを取得する場合ですので、GET を使います。

ESP32 などのマイコンから、HTTP GET リクエストをサーバーに送信するテキスト文字列の例は以下のようになります。

【あくまで例】

GET /1.1/trends/place.json?id=23424856 HTTP/1.1
Accept-Charset: UTF-8
Accept-Language: ja,en
Authorization: OAuth id="23424856", oauth_consumer_key="vz1evFS4wEEPTGEFPHBog",oauth_nonce="2623628452",oauth_signature="aLLAuWiwswZwpeigYYQQadIeoeR%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1512517341",oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb ",oauth_version="1.0"
Connection: close
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Host: api.twitter.com
※空行

ツイートを投稿するわけではないので、Content-Type や Content-Length は不要かも知れませんが、後々投稿するかも知れないので、このようにしておきます。

id は WOEID というもので、地域を示す数値です。
この例の id は「日本」を示しています。

「東京」ならば

id=1118370

です。

WOEID を調べるには、以下のリンクの WOEID チェッカーが便利です。

https://lab.syncer.jp/Tool/WOEID-Lookup/

そして、Authorization: 項目では、以下で紹介している署名キーを生成したものを使用します。
これさえ生成できれば、あとはどんなデバイスでも Twitter APIs からデータを取得できます。

Authentication ( 認証 ) 項目の作成、および signature ( 署名 )キー生成

HTTP ヘッダの Authorization 項目に OAuth 1.0 Protocol に沿った署名キーを作成する方法を説明します。

それは、以下のリンクに具体的に書かれていますので合わせて参照してください。

https://developer.twitter.com/en/docs/basics/authentication/guides/creating-a-signature

これを Google 翻訳で読み解きながら、作成方法を私なりに説明します。

このリンクでは、こちらからツイートを投稿する場合で、POST リクエストする例として書かれています。
ですが、今回は投稿されたツイートを取得する方が目的なので、GET リクエストに修正します。

1.parameter string の作成

まず、パラメーター文字列を作成します。
以下の記事に説明があります。
https://developer.twitter.com/en/docs/basics/authentication/guides/creating-a-signature

ただ、status やinclude_entities というパラメーターは、ツイートを投稿する場合には必要ですが、ツイートを取得するだけの場合は不要です。

では、以下の7つのパラメーターを用意してください。
イコール(=) の両隣のスペースは不要ですので注意してください
イコール(=)の左辺はパラメーターKey で、右辺はパラメーターvalue です。

WOEID

これは私自身も良く分からないのですが、ネットで検索すると沢山ヒットします。
要するに、地域の ID 番号です。
上記で述べたように、WOEID チェッカーで、取得したいトレンドデータの地域を予め調べておきます。
ここでは、日本としますので、ID は以下のようになります。

例:

id=23424856

oauth_consumer_key

これは、先ほどのapps.twitter.com で取得した、Consumer Key です。

例:

oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog

oauth_nonce

ランダムな数値です。
何でも良いのですが、GETリクエストを送る度に異なる乱数にします。
私の場合は、後で述べる、oauth_timestampの数値に1111111111 を加算したものにしました。
timestamp とは異なる数値になるので、ちょっとした乱数モドキです。

oauth_nonce=2623628452

oauth_signature_method

HMAC方式の SHA1 とします。

例:

oauth_signature_method=HMAC-SHA1

oauth_timestamp

現在時刻 UNIX epoch 値です。
1970 年1月1日 0:00:00 からの通算秒数です。
これは、NTPサーバーと時刻を同期して、Arduino Time ライブラリの now() 関数で取得できます。
これが現在時刻より1秒以上ズレてしまうと、認証できないようなので、NTPサーバーと時刻を正確に同期する必要があります。

例:

oauth_timestamp=1512517341

oauth_token

これは、先ほどのapps.twitter.com で取得した、Access Tokenです。

例:

oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb

oauth_version

これの値は
1.0
とします。

例:

oauth_version=1.0

以上の値のパラメーターkey をアルファベット順に並べ替え、下記の例のように ’&’ で連結します。
key が id と oauth_consumer_key ならば、id が先。
key が oauth_consumer と oauth_version ならば、oauth_consumer が先になります。

例:

id=23424856&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog&oauth_nonce=2623628452&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1512517341&oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb&oauth_version=1.0

次に、この文字列を URLエンコード ( %エンコード )します。
アルファベットと数値は変換しません。
この場合、日本語文字列は無いので、変換するのは、URL 上で使われる特殊文字の ‘=’ と ‘&’ です。

URLエンコードとは、’=’ という文字の場合、ASCIIコードが 0x3D なので、その前に ‘%’ を加えて、
%3D
とすることを言います。
‘&’ ならば、ASCIIコードは 0x26 なので、
%26
となります。
よって、先ほどの文字列を URLエンコードすると、以下のようになります。

例:

id%3D23424856%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3D2623628452%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1512517341%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0

signature base string の作成

次に、署名base 文字列を作成します。

トレンドデータを取得するサーバー URLは

https://api.twitter.com/1.1/trends/place.json

なので、この URL 自体を URLエンコード ( %エンコード )します。
すると、以下のようになります。

https%3A%2F%2Fapi.twitter.com%2F1.1%2Ftrends%2Fplace.json

これの前に、httpリクエストメソッドを大文字に変換した文字列 ”GET” を ‘&’ で連結し、さらに先ほど作成した parameter stringも ‘&’ で連結します。
すると以下のようになります。

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Ftrends%2Fplace.json&id%3D23424856%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3D2623628452%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1512517341%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0

signing key の作成

先ほどのapps.twitter.com で取得した Consumer Secret (API Secret) と Access Token Secret を ‘ &’ で連結します。
以下の場合、

Consumer Secret = 5atd83sld8ngAGDT83Dagdun7923snglA5G8anA8Ad8Ag00sUu
Access Token Secret = 7R8SGsd80gaTehowP83d9gUa9gAs9g9aBBg8amg90afan

下記のようになります。

例:

5atd83sld8ngAGDT83Dagdun7923snglA5G8anA8Ad8Ag00sUu&7R8SGsd80gaTehowP83d9gUa9gAs9g9aBBg8amg90afan

signature ( 署名 ) の生成

では、ようやく Twitter APIs の署名の生成です。

上記で作成した、signature base string と signing key を使って、HMAC-SHA1 方式で署名を生成します。
SHA1 や HMAC-SHA1 ライブラリを使って生成することになります。
これについては後述します。

HAC-SHA1 で生成したキーを BASE64 エンコードして、20桁の英数値に変換すれば、signature ( 署名 )の完成です。
BASE64 エンコードについては、私も以前取り組んだことがありますので、以下の記事を参照してみてください。

https://www.mgo-tec.com/blog-entry-websocket-handshake.html

これで、oauth_signature 項目の値が決まります。

例:

oauth_signature=aLLAuWiwswZwpeigYYQQadIeoeR%3D

HTTP ヘッダー Authorization: 項目の作成

では、上記のそれぞれのパラメーターを集めます。
そして、それぞれの値をダブルクォーテーションで囲み、keyをアルファベット順に並べ、カンマで連結します。
そして、先頭に OAuth と半角スペースを連結して、下記のような文字列を作成します。
※、OAuth の直後の半角スペース以外はスペースを一切入力しないように注意してください。

OAuth id="23424856", oauth_consumer_key="vz1evFS4wEEPTGEFPHBog",oauth_nonce="2623628452",oauth_signature="aLLAuWiwswZwpeigYYQQadIeoeR%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1512517341",oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb ",oauth_version="1.0"

これでようやく、HTTP リクエストの Authorization ヘッダーが出来上がりました。

やっぱり、インターネットの SSL 通信や OAuth 認証の複雑さには改めて感心させられてしまいますね。
上記は OAuth 認証 1.0 ですが、2.0 というバージョンもあります。
暗号化技術や認証技術っていうのは、私の様な素人電子工作家にとっては、とっても難しい、ハードルの高い技術ですね。

次では、HMAC-SHA1 や mbedtls そして実際のソースコードを説明します。

コメント

  1. けんにぃ より:

    雑誌掲載おめでとうございます☆
    すごいですね!
    これからもご活躍楽しみにしています。

    • mgo-tec mgo-tec より:

      けんにぃさん

      ご無沙汰しております。
      うれしいコメントありがとうございます。
      m(_ _)m
      記事を寄稿したわけではなく、転載ですが、それでも雑誌になるというのは嬉しいものがありますね。

      ところで、今、ESP32 の SSID セレクターライブラリを作成中です。
      近日中に公開予定です。
      これには、パスワード送信が絡んでいるため、SSL通信が必須です。
      そのため、ESP8266ではメモリが少ない為、動作しない可能性があり、ESP8266用の公開は未定です。
      とりあえず、お知らせでした・・・。

  2. けんにぃ より:

    お久しぶりです☆
    転載されるというのは、魅力的な記事だからだと思います☆
    ESP32のライブラリーは興味津々です♪楽しみにしています。まだESP32買ったままで使えてないですが、何か始めたいと思っていますので。
    ESP8266でなんとか粘ってましたが、策尽き果てました(笑)
    希望としてはESP32で大きめドットのディスプレイをSSIDやpasswordをスマホから取得して駆動(一度取得したら繋がらなくならない限りROMから読み出し)し、外部からのコメントも表示(これは元気8266で外部サーバーに書き込みしたファイルの読み出しで出来ています)をしたいと思っています。(ヤフーのニュースは最悪見れなくてもOK)
    元々ヤフーのメッセージを切替していた感じで、ガスの炎監視やコンセントの電流センサーで消し忘れ監視をディスプレイで表示(これも8266ではある程度可能)を考えてます。
    なので、記事を参考にさせてもらいながら色々やってみたいと思いますので楽しみにしています♪

    • mgo-tec mgo-tec より:

      なるほど。
      けんにぃさんのやろうとしていることは、これからの高齢化社会に必須のアイテムになりそうですね。
      スバラシイです。
      そうなると、益々セキュリティの高い通信が重要になってきますね。

      ESP-WROOM-02(ESP8266) は何故かフラッシュが2MB版が販売されていて、凝ったものを作ろうとすると明らかにメモリが足りないですね。
      外付けSRAM や SDカードを追加すればある程度のことはできますが、それならばESP-WROOM-32を使った方が圧倒的に安上がりで、幅広いプログラミングができますね。
      これからは ESP32 を中心に工作していった方が良いと思います。

      ということで、今年度末で多忙ですので、SSIDセレクターはもうちょいお待ちください。

    • mgo-tec mgo-tec より:

      ということで、Arduino – ESP32 で SSLサーバーを構築して、スマホブラウザでセキュアな Wi-Fi アクセスポイントセレクターライブラリ作ってみました。
      以下の記事をアップしましたのでご覧ください。
      Arduino – ESP32 で SSLサーバーを構築し、セキュアな Wi-Fi アクセスポイントセレクターを作ってみました

  3. けんにぃ より:

    ありがとうございます☆
    ついに完成したのですね♪
    是非とも参考にさせてもらいESP32使ってみたいと思います☆
    自分は、ESP8266でスマートコンフィグではとりあえず使えるようになりましたので、これを32でやっていけるように頑張ります♪

    • mgo-tec mgo-tec より:

      OpenSSL で証明書発行が最初の壁ですが、1回作ることが出来れば、あとは簡単です。
      素人コードなので無駄が多いと思いますが、機会があったら使ってみてくださいませ。
      m(_ _)m

タイトルとURLをコピーしました