Twitter上で勉強するためのBotをGASでつくった


# 概要
勉強になりそうなサイトをスクレイピングして、日常的にフォロワーにリプライしてくれる Twitter Bot を Google Apps Script を使って作った。

* GitHub: https://github.com/tiwanari/learn-on-twitter
* Bot: https://twitter.com/LearnOnTwit

[README](https://github.com/tiwanari/learn-on-twitter/blob/master/README.md) に従えば、比較的簡単に、サーバなどを用意しなくても自分だけの Bot を作って運用できる。現在は TED の Top にあるものを取ってくるだけだけど、拡張は簡単なので、あわよくば「PR が来ないかなぁ」と思って記事公開。[Issue #5](https://github.com/tiwanari/learn-on-twitter/issues/5) で良さそうなデータソースをリストアップ中。

同じような良いサービスがあればぜひ教えてください。


# 背景
「Twitter に時間使いすぎだなぁ…その時間を他の有意義なことに回そう…もうTwitterやめよ…」と思うことは頻繁にあるものの、まだいろいろあって Twitter をやっている。最近は職場で必要な英語力を上げたいなぁと特に思うけど、英語のために学習アプリを開くのがだんだん面倒になってくる。

そこで、「じゃあ、ほぼ毎日使ってる Twitter で勉強するようにすれば？」とふと思い立って、のんびり数時間かけて Twitter の Bot を作ってみた。今回はサーバを用意するのが面倒だなと思ったので、勉強兼ねて GAS で実装した。


# 大雑把な仕組みと仕様
[Google Apps Script](https://script.google.com/home) では、スクリプトを作り、`トリガー`を設定することで、そのスクリプトが自動で走るようになるので、スクリプトからツイートできるようにすれば、サーバを特別用意しなくても Twitter Bot を運用できる。今回はひとまずフォロワーにリプライするだけなので、時間でトリガーを設定すれば OK。一日一回学習トピックを受け取るようにしてみた（あまり多いとやる気が続かないので:;(∩´﹏`∩);:）。

学習ソースはいろいろ思いついたものの、ひとまずテストとして TED にしてみた。スクレイピングは複雑なことはしていなくて、Top ページを取得して、HTML の目的の箇所を切り出すだけ。これにはものすごく簡単に使えそうだった [この Paser](https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html) を利用。フォロワーを取得して全員にこれをリプライで送るようになってる。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr"><a href="https://twitter.com/iw_tatsu?ref_src=twsrc%5Etfw">@iw_tatsu</a> Sally Kohn: What we can do about the culture of hate <a href="https://t.co/Vrbdg5CuTA">https://t.co/Vrbdg5CuTA</a></p>&mdash; Learning Bot (@LearnOnTwit) <a href="https://twitter.com/LearnOnTwit/status/974931970076676096?ref_src=twsrc%5Etfw">2018年3月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# 実装のポイント
シンプルなのでコードを見ていただければと思うけど、ざっくりポイントだけ。コードを読むときの参考として、現在の構成を示すと以下のような形。

```sh
$ tree src
src
├── post.gs          # 実際にツイートをする （これにトリガーを設定する）
├── data_source.gs   # 学習用のデータを取ってくる関数群
└── twitter
    ├── api.gs       # Twitter の API をラップする (最小限)
    └── authorize.gs # Twitter の認証兼サービス
```

## Twitter 認証
[Google Apps Script で Twitter を使ってみる - Qiita](https://qiita.com/Ikanogo/items/1dce33c26559eac56a03) を参考（というかそのまま）に、認証部分を実装。この記事にある `Test.gs` の上部にある

```javascript
var API_KEY = '{API_KEY}';
var API_SECRET = '{API_SECRET}';
```
という部分は、スクリプトプロパティから読み取るように以下のように置き換えた。

```javascript
var API_KEY = PropertiesService.getScriptProperties().getProperty('API_KEY');
var API_SECRET = PropertiesService.getScriptProperties().getProperty('API_SECRET');
```
スクリプトプロパティは、`File > Project Properties > Script Properties`で設定できる。 

## 学習用ページの内容取得
この [Paser](https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html) を利用。`Resource > Library` から、`M1lugvAXKKtUxn_vdAG9JZleS6DrsjUUV` を入れることでこのライブラリが利用できるようになる。

この Parser は、入力として HTML 自体（文字列）を与え、 `from` と `to` に HTML の断片を指定することで、その間（最短マッチ）の HTML が取得できる。複数ある場合は iterate すれば良いよう。

以下のコードは、実際に今のレポジトリに含まれている、TED の Top にある動画を取ってくるスクリプトで、綺麗とは言えないけど実装が簡単なことを示すのには良いと思う。

```javascript:data_source.gs
function tedHomePageSpotlight() {
  // ターゲットのページを取得
  var html = UrlFetchApp.fetch('https://www.ted.com/').getContentText();

  // html から Top 動画の内容が含まれる HTML 断片を指定
  // 大抵取得したいものは特別な id か class を持っていると想定できると思うのでこれは十分機能するはず
  var spotlight = Parser.data(html).from("<a class='sa d:b pos:r ga-link'").to(">").build();

  // 取得した部分をさらに絞り込んで目的の URL と title を取得
  // NOTE: href omits the domain part
  var url = Parser.data(spotlight).from("data-ga-label='1 of 3-up | ").to("'").build();
  var title = Parser.data(spotlight).from("title='").to("'").build();
  
  return title + ' ' + url;
}
```


# 今後の発展
* 学習のためのデータソースをもっと用意する ([Issue #5](https://github.com/tiwanari/learn-on-twitter/issues/5))。
* Google Spreadsheet を設定ファイルのようにして、（ユーザ、ユーザが受け取りたい学習トピック）を紐付けられるようにする ([Issue #6](https://github.com/tiwanari/learn-on-twitter/issues/6))。
  * Google Form かなにかでユーザが内容を編集できるようにすると良いかな。
  * 投稿時間もトリガーに縛られないようにできるとよい。トリガーは毎時にして、シートを見て記入された時間帯ならリプライするとかでもいい。

# まとめ
何番煎じかわからないけど、GAS で Twitter Bot を作った話でした。毎日更新される良さそうなデータソースがあればぜひ教えてください。

# 参考
* [Google Apps Script 入門 - Qiita](https://qiita.com/t_imagawa/items/47fc130a419b9be0b447)
* [Google Apps Script で Twitter を使ってみる - Qiita](https://qiita.com/Ikanogo/items/1dce33c26559eac56a03)
* [手軽にGoogle Apps ScriptのコードをGithubで管理する | Recruit Jobs TECHBLOG](https://techblog.recruitjobs.net/development/maneged_google-apps-script_by_github)
* [How to define global variable in Google Apps Script - Stack Overflow](https://stackoverflow.com/a/24749707)
* [Easy data scraping with Google Apps Script in 5 minutes ~ kutil.org](https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html)