フォロワーのおもしろツイートをまとめたwebアプリを作って怒られよう

##はじめに
[みそまんじ氏](https://twitter.com/unquitable)というおもしろツイートを供給し続けている方がいらっしゃるので魚拓と拡散を兼ねて勝手にツイートをまとめたものをつくりました。ノリと勢いで作ったので備忘録として残しておきたいと思います。

##完成したもの
[みそまんじおもしろツイート大全](https://h0l1c.github.io/misomanji_joke/)
[![Image from Gyazo](https://i.gyazo.com/fa4692d7f6bd6447bbb192f532221151.png)](https://gyazo.com/fa4692d7f6bd6447bbb192f532221151)

##作り方
###材料
- おもしろツイートをするフォロワー
- IFTTT
- GoogleSpreadSheet
- GoogleAppScript
- Vue.js


###手順1：ツイートを取得してスプレッドシートにまとめる
それでは早速作っていきます。
今回は特定のアカウントのとある条件のツイートを取得したいのですが、お手軽に[IFTTT](https://ifttt.com/)を使用することにします。ただしIFTTTは15分ごとに実行されるためラグが生じます。GASとかをバリバリかける人はそっちで取得する方がいいかもしれません。

[IFTTT](https://ifttt.com/)に飛んでCreateからツイートを取得するAppletsをつくります。
If +This Then That の +ThisをクリックしてTwitterを選択します。
トリガーは特定の検索結果をまとめたいので「New tweet from serch」（画像右下）を選びます。
[![Image from Gyazo](https://i.gyazo.com/b71486313aa7e31b36f7d33c7d73d3a1.png)](https://gyazo.com/b71486313aa7e31b36f7d33c7d73d3a1)
検索内容は自分が取得したい内容を入力しましょう。
ちなみに今回私が使った検索ワードは以下です。
```...w from:unquitable exclude:retweets　-filter:replies ```
```exclude:retweets　-filter:replies ```の部分でリツイートとリプライを除外しています。ここは普通のTwitter検索と同じなので省略します。

次に+ThatをクリックしてGoogleSheetsを選択します。
トリガーは「Add row to spreadsheet」を選びます。（画像左側）
[![Image from Gyazo](https://i.gyazo.com/689c876b9677036e6cf0dc65bca37f16.png)](https://gyazo.com/689c876b9677036e6cf0dc65bca37f16)

以下の情報を入力します。
Spreadsheet name：スプレッドシートの名前
Formatted row：取得するツイート情報
Drive folder path：スプレッドシートの保存先

Formatted rowはデフォルトで

- CreatedAt：スプレッドシートに追加された時間
- UserName：TwitterアカウントID
- Text：ツイート本文
- LinkToTweet：ツイートへのリンク
- FirstLinkUrl：他のアプリと連携する用のリンク？（未検証）

が設定されています。取得したい情報以外は削除してしまいましょう。
また、```UserImageUrl```を追加することでTwitterアカウントのアイコン画像を取得できます。

[![Image from Gyazo](https://i.gyazo.com/d47e2c002dc0b3e777315c8437c4cf88.png)](https://gyazo.com/d47e2c002dc0b3e777315c8437c4cf88)

こんな感じに設定しました。
作成完了すると新しいAppletsが追加されていると思います。
ちゃんと設定できているか確認するためには右上のSettingsからApplet Settingsを開きCheck nowを押せば即時実行させることが可能です。

しかし、問題点が1つあり**IFTTTを設定した後にツイートされた内容しか取得できません。**1つでも取得するツイートがないとうまく実行されないため注意が必要です。
つまり収集したいアカウントの持ち主に取得条件のツイートをしてくれるように頼むかツイートしてくれるまで待つ必要があります。
私は頼みました
[![Image from Gyazo](https://i.gyazo.com/9b25955bd86784bff7d95615ab5f1172.png)](https://gyazo.com/9b25955bd86784bff7d95615ab5f1172)

正常に動いていれば設定した保存場所にスプレッドシートが作成され、記録されている内容はともかくこんな感じで追加されているはずです。
[![Image from Gyazo](https://i.gyazo.com/f3e01405f0865ea1e0fd61ee21faae38.png)](https://gyazo.com/f3e01405f0865ea1e0fd61ee21faae38)
ちなみに今回使用させていただいたコードでは一行目をkeyとして使用できるので自分でスプレッドシートを編集して追加しています。
下準備が整いましたので次の作業をしていきましょう。

###手順2：スプレッドシートをAPI化する
さて、次はこのスプレッドシートに手を加えていきましょう。
上部メニューから```ツール > スクリプトエディター```を選びます。
別タブでエディターが開くので以下のGASを入力します。

```js:GoogleAppScript
function getData(id, sheetName) {
  let sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
  let rows = sheet.getDataRange().getValues();
  let keys = rows.splice(0, 1)[0];
  return rows.map(function(row) {
    let obj = {}
    row.map(function(item, index) {
      obj[keys[index]] = item;
    });
    return obj;
  });
}

function doGet(e) {

  let data = getData('SpreadSheetID', 'SheetName');
  let output = ContentService.createTextOutput(JSON.stringify(data, null, 2));
  output.setMimeType(ContentService.MimeType.TEXT);
  return output;
}
```

私はGASを触ったことがなかったので以下の記事中のコードをお借りしました。

[コピペでスプレッドシートをJSON形式のAPIにする方法] (https://qiita.com/YukiIchika/items/778856a7ea92e5a2383c)

コード内の```let data = getData('SpreadSheetID', 'SheetName');```に先ほどIFTTTで作成されたシートの情報を入力します。

「SpreadSheetID」はシートのURLの/edit#gid=0以前の文字列です。
例：``` https://docs.google.com/spreadsheets/d/スプレッドシートID/edit#gid=0 ```

「SpreadSheetName」には**シートの名前**を入力します。
間違えてスプレッドシート自体の名前を入力すると正常に情報を取得できないので注意しましょう。
今回の例で言えば``` Sheet01 ```が入ります。

コードを追加したら名前を付けて保存した後公開を行います。
メニューから```公開 > ウェブアプリケーションとして導入```を選びます。
一番下のWho has access to the appが公開範囲設定なのですが```Anyone,even anonymous```を選択しておかないと取得できないようです。
ただし```Anyone,even anonymous```にしてしまうと誰でも使用できてしまうので、他人に見られたら困るような情報を扱う場合は注意しましょう。
![c3908d28551b5c13d8b3d566c20812e6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561409/91628b1c-9755-4daa-32e3-08620449f6b5.png)
導入をクリックすれば「現在のウェブアプリケーションのURL」が表示されると思います。後で使うのでどこかに置いておきましょう。
ちなみにTest web app for your latest code.をクリックすると以下のように確認することができます。
[![Image from Gyazo](https://i.gyazo.com/bfacc32a693d95df17e87ad889cdaab1.png)](https://gyazo.com/bfacc32a693d95df17e87ad889cdaab1)

###手順3：ウェブアプリにする
Vue.jsとaxiosを使って表示していきましょう。
サンプル用にスプレッドシートを書き換えて以下のようにします。
[![Image from Gyazo](https://i.gyazo.com/5f19658ed16c705c94e13cc61b4082fe.png)](https://gyazo.com/5f19658ed16c705c94e13cc61b4082fe)
続いてこんなHTMLを作成します。

```html:index.html
<body>
    <div id="app">
        <div v-for="item in items" v-bind:key=item.tweet>
            <a v-bind:href="item.link" target="blank" rel="noopener noreferrer" class="itemList">
                <img v-bind:src="item.icon" alt="アイコン画像" loading="lazy">
                <div class="name">
                    <p class="id">{{ item.id }}</p>
                </div>
                <div class="text">
                    <p class="tweet">{{ item.tweet }}</p>
                    <p class="date">{{ item.date }}</p>
                </div>
            </a>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        const baseURL = '手順2の現在のウェブアプリケーションのURL';
        const app = new Vue({
            el: '#app',
            data: {
                items: null,
            },
            mounted() {
                this.getData();
            },
            methods: {
                getData() {
                    axios.get(baseURL)
                        .then(res => {
                            this.items = res.data.reverse()
                        })
                        .catch(err => {
                            console.log("error")
                        });
                },
            }
        });
    </script>
</body>
```
あとはいい感じにcssを書いてあげるとこんな風になると思います。
[![Image from Gyazo](https://i.gyazo.com/94ca0ce1b4b2339d454c7e1774a5b9b4.png)](https://gyazo.com/94ca0ce1b4b2339d454c7e1774a5b9b4)
ポイントとしてはIFTTTで取得したツイートはスプレッドシートの一番下に追加されていくためそのままだと最新のツイートを見るには一番下までスクロールしないといけません。
そこでjsで```this.items = res.data.reverse()```とすることで逆順にし最新のツイートが先頭に来るようにしています。
これを公開してあげれば完成です。
サンプルとして最初にも貼りましたが完成したものをもう一度貼っておきます。

[みそまんじおもしろツイート大全](https://h0l1c.github.io/misomanji_joke/)

##おわりに
果たして需要があるのかどうかわからない記事になってしまいました。
そもそもTweetDeckのカラムに検索キーワードぶち込んでおけばいいのでは？という話なのですが作っていて楽しかったのでヨシとしましょう。
また一度作ってしまえば取得するツイートのキーワードを変えるだけでいくらでも量産できるので、魚拓だけではなく推しのツイートを取集するとかなんかいろいろできると思います。（多分）
最後になりますがおもしろツイートをするフォロワーこと[みそまんじ氏](https://twitter.com/unquitable)のフォローをよろしくお願いいたします。





***

この投稿を読んでいるかはわかりませんが、みそまんじさんへ
勝手に作ったこと、記事にして公開したこと大変申し訳ございませんでした。~~快く~~投稿許可をいただきありがとうございます。今後ともおもしろツイートの供給をよろしくお願いいたします。