最新のツイートをLCDに定期的に表示する人形を作ってみた

Maker Faire Tokyo 2021のブース出展用に『ミニチュアツイート人形』という作品を作成しました。この記事ではこの作品について紹介します。

# ミニチュアツイート人形とは
ミニチュアツイート人形はRaspberry Pi、グラフィックLCD、Power Automate、kintoneとTwitterを組み合わせた作品です。Twitter上で他人がつぶやかれたツイート情報を定期的にkintoneのアプリに記録させ、ツイートの内容をグラフィックLCDに表示をさせます。作品のガワはブロック玩具で作られています。

![IMG_2300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/b0291580-563f-554c-6964-8ec53bd52fc6.jpeg)




# 作り方

この作品の作り方について案内をします。

## 1. Raspberry Pi と LCDをつなげる
この作品では下記の機器を利用しました：
- Raspberry Pi 3
- [TG12864B-02WWBV LCD グラフィックディスプレイモジュール](https://akizukidenshi.com/catalog/g/gP-04167/)


詳細は省きますが、[こちらのサイト](https://sakura87.net/archives/2116)を参考にしながらRaspberry PiとLCDの配線を行いました。プログラム内では[WiringPi](http://wiringpi.com/)のライブラリを使用しているため、Raspberry PiのピンもWiring Piのピン配置に沿って配線をします。配線はこんな感じです。
![haisen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/612ee613-01c8-d5b9-b88d-6ba327a0b765.png)


TG12864Bは配線も多いので、最初はブレッドボードを間に挟んでプロトタイピングをすると良いです。
![5CC24F44-D390-4BCD-AEDC-22F1A3064F90.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/b7ab2f83-8c2d-7875-85cd-9abcfe78390a.jpeg)
ちなみに上の画像、めっちゃ配線間違ってるので真似しないでください。

Raspberry Pi のpythonでLCDに日本語の文字を表示させるには[こちらの記事](https://qiita.com/t114/items/c5e5690f7ca1a7d4731f)を参考にさせて頂きました。こちらのコードで指定した文字が表示出来ることを確認した後に、ブレッドボードからユニバーサル基板に乗り換えました。
![IMG_2325.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/7ed22b0f-1c15-ed06-1b1b-75b5682e0f8f.jpeg)

![haisendone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/42da2711-7c57-fc10-7e54-77418887eea6.png)

## 2. ツイートを溜めるkintoneアプリの作成をする
この作品では他人がつぶやかれたツイートの内容をLCDに表示をさせます。Raspberry Pi上でTwitter APIと連携するpythonのコードを書けば、自由度の高いプログラムを作成し、取得したツイートを即時にLCDに表示させることが出来ます。ですが、認証情報を扱う煩わしさや、どうしてもコードが長くなりそうと感じる人もいるでしょう。私みたいに。

その問題を解消するために、ツイートの情報は[Power Automate](https://powerautomate.microsoft.com/) で取得してkintoneに登録することにしました。そして、Raspberry Pi でpythonを使ってシンプルなREST APIのリクエストでkintoneに溜まったツイート情報を取得することにしました。

ツイートの情報を溜めるkintoneアプリは下記のように設計します。『ツイート内容』のフィールド以外は割と適当に設定して大丈夫です。
![kintonefields.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/a8a4c7db-bf63-175c-06be-ae90912385a0.png)

『ツイート内容』のフィールドコードは『TweetContents』に設定します。この文字列は後ほどpythonのスクリプトから指定する必要があります。

kintoneの環境が無い方は[開発者ライセンスの申し込み](https://developer.cybozu.io/hc/ja/articles/200720464)で無料で取得することが出来ます。アプリの作成方法がわからない場合は[こちらのヘルプサイトの記事](https://jp.cybozu.help/k/ja/user/create_app/tutorial.html)を参考にしてください。

アプリをkintoneの環境内で公開が出来た後に、次のステップに進みます。

## 3. Power Automateでツイートをkintoneに登録する
次に、Power Automateの設定をします。
Power Automateには1分に1回フローを実行させることが出来る有能な『Recurrence』という機能があるので、そちらを活用します。環境によっては『繰り返し』という名前になってます。Power Automateの画面から　**フロー** → **新しいフロー** → **スケジュール済みクラウドフロー** と選択すると、この機能を使うことが出来ます。
![Screen Shot 2021-10-02 at 0.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/e8360a8e-1577-7e6a-4fee-42bc65e06d67.png)


次のステップに、Twitterの『ツイートの検索』というアクションを設定します。オプションの『検索テキスト』にはTwitterの検索クエリを入れ、『結果の最大件数』には1と入力します。ここの設定はもちろん好きなように変更して良いのですが、今回はこれで進めます。これで1分に1回、検索クエリに該当した最新のツイートを1件取得してくれます。

![Screen Shot 2021-10-01 at 22.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/164c2ad0-4620-1e18-bd27-24e259cb3f13.png)

ちなみにこんなことしなくても、最新のツイート拾ってくれるTwitterのトリガーが存在するから、それを使えば良いんじゃないか？と思われるかもしれません。確かに存在はするのですが、こちらは試してみたところ、実行されるのが1時間に1回でした。ちょっと回数が少ないですね。

続けて、取得したツイートをkintoneに登録する必要があります。ステップを追加し、kintoneを検索し、『アプリにレコードを追加』というアクションを設定します。kintoneのアクションはプレミアムプランですが、[Power Appsの開発者向けプラン](https://powerapps.microsoft.com/ja-jp/developerplan/)を申し込めば、無料でプレミアムプランのコネクタを活用することが出来ます。

Power Automateの設定画面からkintoneを認証させる必要があります。自分が持ってるkintone環境の設定を変えずに、そのまま認証を進めようとするとほぼ確実にkintoneのエラー画面にが表示されます。
![Screen Shot 2021-10-02 at 0.17.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/45365d0d-686a-b4f4-9c1a-2c0119e4352c.png)


kintoneが外部サービスとの連携を許可しないといけないのですが、[こちらのヘルプサイトの記事](https://jp.cybozu.help/general/ja/admin/list_externalservices/oauth.html)通りに:
1. kintoneの『cybozu.com共通管理画面』からMicrosoft Power Automate の連携を有効にする
2. 連携利用ユーザの設定で自分のkintoneユーザアカウントにチェックが入るようにする
という設定が事前に必要になります。

これさえ設定が出来ていれば、Microsoft Flowの設定画面からkintoneの認証をすることが出来ます。

一度認証が終わり、アクションの設定にアプリIDやTwitterの情報を入れ始めたら、Power AutomateのUIが少し変わって kintoneのアクションが Apply to each という枠に囲まれます。これはTwitterから取得される情報が配列のため、Apply to eachが自動的に設定されるような仕様になってます。まぁ正直あまり気にしなくて良いです。下記のように、『アプリ ID』にはkintoneアプリのID(ブラウザでkintoneアプリを開いた時に、URLに `cybozu.com/k/` の後の数字がアプリID)を、『ツイート内容』にTwitterのツイート内容が入るようにし、他は適当に設定してOKです。

![Screen Shot 2021-10-01 at 22.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/0a4649d6-d15c-8ff7-02ff-42718ad3177f.png)


Power Automateの設定は保存し、次のステップに進みましょう。

## 4. LCDにツイート内容を表示する
次にLCDにツイートの内容を表示させます。
ツイートの内容はkintoneに登録されています。Raspberry Pi のpythonからkitnone アプリに対してREST APIを叩き、取得した情報をLCDに流すような感じで進めます。そしてその処理が一定間隔で繰り返すようにします。

[こちらの記事](https://qiita.com/t114/items/c5e5690f7ca1a7d4731f)で案内された[修正されたGist](https://gist.github.com/t114/157cab837411323153add1b125249ca5)を元に下記のコードの改変を行います。

まず、REST APIを叩くので、必要なモジュールをインポートします。

```python
import requests
import json
```


次に、リクエストに設定するkintone用のパラメータを設定します。

```python
URL = "https://{サブドメイン}.cybozu.com/k/v1/records.json?app={アプリID}&query=order by $id desc limit 1"
API_TOKEN = "{APIトークン}"
```

パラメータは自分のkintone環境によって入れる内容がことなります：
- **{サブドメイン}**: 情報を取得するアプリが所属する環境のサブドメイン名を入れてください。ブラウザでkintone環境にログインする時に、URLに表示されているはずです。
- **{アプリID}**: 情報を取得するアプリのIDを設定します。
- **{APIトークン}**: 情報を取得するアプリからAPIトークンを生成し、その文字列をここに設定して下さい。APIトークンの生成方法については[こちらのdeveloper networkの記事](https://developer.cybozu.io/hc/ja/articles/202463840-API%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)を参照してください。

次に、kintone API を叩く関数を作ります。引数として、REST APIのエンドポイントとAPIトークンの値を指定します。

```python
def get_kintone(url, api_token):
    headers = {"X-Cybozu-API-Token": api_token}
    resp = requests.get(url, headers=headers)
    return resp
```

次に、LCDに表す文字を決定する関数を作ります。複数のレコードを取得するREST APIを叩いているので、レスポンスは配列で返ってきます。一応今回叩くREST APIのクエリでレコードが1件しか返ってこないようにはしていますが、それでもレスポンスは配列で返ってきます。なので、配列の0番目にアクセスし、**TweetContents**というプロパティを参照します。こちらのプロパティの文字列はkintoneの『ツイート内容』フィールドのフィールドコードと一致してる必要があります。そのプロパティの**value**を参照すると、ツイート内容の文字列を引き出すことが出来ます。後は参考にしてたQiita記事の方で準備されてた関数を使って、文字列の画像化を行い、LCDにデータを渡します。

```python
def display_tweets():
    RESP = get_kintone(URL, API_TOKEN).json()
    RESP = RESP["records"][0]["TweetContents"]["value"]
    display_filename = make_textbmp(RESP)
    lcd_display(display_filename)
```

`if __name__ == '__main__'` 内でループ処理でkintoneのAPIを叩く関数を呼びます。どれくらいの間隔でREST APIを叩くかは、[kintoneのREST APIの制限事項](https://jp.cybozu.help/k/ja/admin/limitation/limit.html#limitation_limit_30)を確認しながら設定しましょう。下記の例では60秒に1回叩いています。

```python
if __name__ == '__main__':
    args = sys.argv
    if len(args) != 1:
        sys.exit
    while True:
        display_tweets()
        time.sleep(60)
```


## 5. ガワの作成
最後にガワの作成をしました。これはプログラミングとかは関係なく、ブロックを購入して好きなように組み合わせるだけの作業でした。今回の展示用ブースはvoxel風のテーマで進めていたので、ツイート人形もvoxel風に仕上げました。

kintoneのDevRel関係のキャラとして[出雲沙斗美ちゃん](https://twitter.com/satomi_izumo)というキャラが存在します。いずもさとみ、と読みます。
![kintonetutorial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/eddf03c8-94b5-e991-dcf2-7f44fcc0132f.png)


Maker Faire 用の動画ではゆっくりバージョンの沙斗美ちゃんが作品の紹介をします。
![Screen Shot 2021-10-01 at 13.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/b061d5ba-e045-3b5e-9f7b-7ef35595effa.png)


そんな沙斗美ちゃんを今回はvoxel風に仕上げました。
![mft1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/8432d1d6-403e-c569-b6f6-fc887d21815d.jpeg)


続けて、LCDが固定出来るように、テレビのようにまわりを固めました。
![TVpic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/c3e28b2e-0b7c-2e84-1dba-6d7404517d39.png)


そして最後に、沙斗美ちゃんとLCDのテレビを合体させました。
![fullpic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/0f409844-f280-4ece-6ee3-3c398b1b9dd3.png)


# 動作確認
Raspberry Pi のコンソールからpythonのスクリプトを引数無しで実行します。しばらくして、ツイート情報がkintoneアプリから取得され、LCDに表示されます。一分後、新しいツィート情報があれば、LCDの内容が書き換わります。
![dousakakunin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100542/db8fffb8-a777-4dc6-9173-3cb3a776b33c.jpeg)

## 最後に
今回はツイートを取得する方法はシンプルに設定しています。新しいツイートが無い場合、重複してkintoneにレコードが追加されます。また、1分の間に複数のツイートがあった場合、最新のツイートだけしか拾われません。Power Automate側で工夫を行えば、複数のツイートを一回で取得し、まだ登録してないツイート情報だけkintoneに登録することが出来ます。まだ、python側のスクリプトを工夫すれば最新のkintoneのレコード情報を表示するのではなく、まだLCDに表示していないレコード情報を順番に表示していく、ということも出来ます。

とりあえずこの記事では動くものの紹介をしているので、さらにこだわりを入れたい人は是非挑戦してみてください。