にゃーんツイートを感知してDiscordに猫を派遣するbotを作る

ふざけたタイトルですが下記の事をそれなりに丁寧にやります。

- IFTTT でツイートを取得、情報をスプレッドシートに書き込み
- GoogleAppsScript をTypeScriptで開発(+ 環境整備)
- DiscordのWebHookを利用し、botにメッセージを送らせる

ってことでやっていこう。
全文はかなり長いので、適宜必要な情報だけ拾ってください。

## 目次
1. [GASの準備](#gasReady "")
 - [セットアップ](#gasReady_setUp "")
 - [GASのテスト](#gasReady_test "")
2. [IFTTTとやり取りをするための準備](#ToIFTTReady "")
3. [IFTTTを設定](#IFTTSetting "")
 - [IFTTTってなんやねん](#IFTTSetting_nannyanen "")
 - [レシピを作成](#IFTTSetting_createRecipi "")
 - [動作テスト](#IFTTSetting_test "")
4. [DiscordのBot準備](#discordReady "")
 - [サーバーの準備](#serverOnedari "")
 - [Webhookの作成](#discordReady_createWebhook "")
5. [GASでDiscordへメッセージを送る](#sendDiscord "")
 - [ログ出力を実装](#sendDiscord_logREady "")
 - [Discordのメッセージ型を実装](#sendDiscord_sendMSGReady "")
 - [DiscordのWebhookにPostリクエストを送る](#sendDiscord_sendPost "")
6. [IFTTTとDiscordをつなげる](#connectBoth "")
 - [スプレッドシートに書き込まれたツイートを読み込む機能を実装](#connectBoth_read "")
 - ["にゃーん"かどうか判別して、猫を派遣する](#connectBoth_sentCat "")
 - [IFTTTからの書き込みを検知して自動で実行する](#connectBoth_autoExe "")
7. [鳴く！](#mew "")

## 使ったもの
- node.js 12.16.0
- Visual Sutudio Code 1.42.1

VSCodeとnode.jsはインストール済みのものとして進めていきます。~~丁寧とは~~
上記に関しては調べれば簡単にインストールができるので、ない場合はそうしてください。

## 具体的に何をするの?
初めに大体書きましたが、具体的には

IFTTTでTwitterのツイートを取得し、スプレッドシートに書き込み、
それをGASが検知して、ツイート内容を解析。
ツイート内容が "にゃーん" だったらDiscordへ猫の絵文字を流させる

という流れです。
ざっくり言うと、Twitterで社会性フィルターを感知するとDiscordに猫が駆けつけてくれるbotを作ります
<a id="gasReady"></a>
# GASの準備 
#### GASってなんやねん
GoogleAppsScriptの略です。Googleアカウントさえあれば無料で使えます。
Googleのサーバー上で動作するスクリプトで、スプレッドシートやGmailなどGoogleの各種サービスを叩けます。
詳しくは調べればたくさん出てくるので、興味があればぜひ。

今回は無料で建てられるサーバーとしてIFTTTとDiscordの仲介役になってもらいます。

#### やっていき<a id="gasReady_yatteiki"></a>
GASを動かすためのいろいろを準備します。

### セットアップ<a id="gasReady_setUp"></a>
今回はTypeScriptとClasp(GASをVSCodeで使うためのパッケージ)を用いて開発するので、[clasp が Typescript をサポートした！](https://qiita.com/HeRo/items/4e65dcc82783b2766c03 "clasp が Typescript をサポートした！")を参考に必要なパッケージをインストールしていきます。
VSCode上で`ctrl+@`するとターミナルが開くので、そちらにコマンドを入れていきましょう。

```:cmd
$ mkdir nyan-bot
$ cd nyan-bot
$ npm init -y
$ npm install @google/clasp -D 
$ npm install @types/google-apps-script -S
```

Typescriptはこちらでインストールしなくても@google/claspが依存しているので勝手にインストールされます。
トランスパイルはpushの際にclaspが勝手にやってくれるので、特にTypeScriptの諸々を設定する必要はありません。

#### ログイン<a id="gasReady_login"></a>
とりあえずgoogleアカウントへログインを済ませましょう
以下を実行するとブラウザが開き、必要情報を入力するとログインできます。

```:cmd
$ clasp login
```
#### GASを有効化<a id="gasReady_GASEnable"></a>
GoogleのフォームでGASを有効化しておかないと一部コマンドが使えないので、GASを過去に一回も使ったことがない人は
https://script.google.com/home/usersettings
にアクセスしてGoogleAppsScriptAPIをオンにしてきてください。
![bandicam 2020-02-18 01-37-37-239.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/ee285b55-8973-8b17-f2f0-81d3c9ddd99f.jpeg)


#### スクリプトとスプレッドシートを作成<a id="gasReady_GAScreate"></a>
ログインを済ませたらGASのスクリプトを作成します。
今回はスプレッドシートを使うので、以下のコマンドを実行したら
"Create which script?" にはsheetsと答えましょう

```:cmd
$ clasp create
```

![bandicam 2020-02-18 00-59-43-985.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/358f0440-bedd-bd1b-9253-fc171ba1a21c.jpeg)

ここまで正しく工程を踏めていれば以下のようにスクリプトとスプレッドシートのリンクが吐き出されます
![bandicam 2020-02-18 01-00-43-439.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/7db994ca-e879-6b69-1de5-8e17f1c855aa.jpeg)

#### 扱いやすいようにフォルダと設定を整理<a id="gasReady_seiri"></a>
.clasp.jsonに`rootDir`を設定することで、`rootDir`で指定したディレクトリ以下のみがGASへpushされるようになります。

```json:.clasp.json
{ 
    "scriptId":"xxxxxxxxxxxxxxxxxx-xxxx",
    "rootDir": "./src"
}
```
以下の様なフォルダ構成にします。
pushの際、 appsscript.json を含めないといけないため、appsscript.json は必ずrootDirで指定したフォルダ以下に移動しておいてください。

```
nyan-bot/
├── .clasp.json
├── node_modules/
├── package-lock.json
├── package.json
|
├── node_modules
└── src
    └─ ts
    └─ appsscript.json
```
ひとまずGASのセットアップは終わりです。お疲れ様。

### GASのテスト<a id="gasReady_test"></a>
セットアップが終わったので、まずは動作のチェックをします

#### .tsファイルを作る<a id="gasReady_createTS"></a>
以下のmain.ts ファイルを src/ts 下に作ります

```ts:main.ts
function TestAction()
{
    //アクティブなスプレッドシートを取得する
    const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
    //一番初めのシートを取得する
    const firstSheet = spreadSheet.getSheets()[0];
    //セルに書き込む
    firstSheet.appendRow(["こんにちは世界","Hello World","なんでプログラマすぐあいさつするん？"]);
};
```

#### GASへpush<a id="gasReady_GASpush"></a>
以下のコマンドでpushできます

```:cmd
$ clasp push
```
![bandicam 2020-02-19 23-07-57-263.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/edb12642-bfbe-51e5-238a-3a3f4193aaa3.jpeg)

pushしたらGASへ確認しに行きましょう。
URLで飛んでもいいですが、下記のコマンドでもアクセスできます。

```:cmd
$ clasp open
```
pushがうまくいっていればトランスパイルされた main.gs と再会できます
.gsとありますが、言語は ~~JavaCusoript~~ JavaScriptです
![bandicam 2020-02-19 23-14-45-660.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/35c4b07f-e892-0b06-8c35-4a3b9b7e8b85.jpeg)

#### 実行<a id="gasReady_execute"></a>
GASは関数単位で実行されます。
電球マークの隣が TestAction になっていると思いますが、ここのリストに実行可能な関数名が列挙されます。
今回実行するのはそのまま TestAction  なので、その左にある三角マークを押して実行しましょう。

関数内にスプレッドシートをいじる処理があるので、初めて実行する時は許可を求められます。
とりあえずはいはい言って許可を出します。

実行後、スプレッドシートに以下の様に書き込まれていれば成功です。
![bandicam 2020-02-19 23-23-22-431.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/e3e46ff9-e76c-d4cf-c748-c0eb3785be76.jpeg)

GASの準備は一通り完了。次はIFTTTに移ります。

# IFTTTとやり取りをするための準備<a id="ToIFTTReady"></a>
といいましたが、先にスプレッドシート側の受け入れ準備をします。

### シートを整理<a id="ToIFTTReady_createSheet"></a>
IFTTTからツイート内容を受け取るシート`RecvTweet`と、
GASのログを出力するシート`Log`をそれぞれ用意しておきます。
![bandicam 2020-02-22 15-53-46-102.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/ab05c1d1-f31b-39f9-8dde-1449888a7a18.jpeg)
### スプレッドシートのパスを変更<a id="googleDrivePathSetting"></a>
また、スプレッドシートは現状Googleドライブのルートディレクトリに直置きされているので、IFTTTフォルダを作ってその中に放り込んでおきます。
(IFTTTでスプレッドシートのパスを選択する際、ルートディレクトリが選べないので)
![bandicam 2020-02-22 17-08-51-100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/19a4b591-c071-e7a3-8937-43edc5a832ab.jpeg)

これで準備は完了。IFTTTへ移りましょう


# IFTTTを設定<a id="IFTTSetting"></a>
#### IFTTTってなんやねん<a id="IFTTSetting_nannyanen"></a>
イフトと読みます。IF This Then That(もし、これをしたらあれをする)の略です。
この子はInstagram、Twitter、Googleドライブなどのプラットフォームの仲介をしてくれます。
TwitterでツイートしたらGoogleドライブのスプレッドシートに書き込む、みたいなことができます。便利ですね。

ということでそれを利用します。
#### やっていき2<a id="IFTTSetting_yatteiki"></a>
IFTTTの設定は[この記事](https://tonari-it.com/gas-chatwork-twitter/#toc4 "Google Apps ScriptでTwitterの検索結果を自動でチャットワークに通知")を参考にしました

こちらを参考に、ツイートを感知してスプレッドシートへ書き込む機構を作ります。

まずは[IFTTT](https://ifttt.com/ "IFTTT") にアクセスしてログインしましょう
Googleアカウントでログインできるので、アカウントがなくても簡単に入れます。

### レシピを作成<a id="IFTTSetting_createRecipi"></a>
右上の自分のアイコンをクリックし、Createを選びます
![bandicam 2020-02-20 00-14-17-512.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/df595841-0d6f-09ea-7c63-267b4ef7052c.jpeg)

#### Twitter側の設定<a id="IFTTSetting_settingTwitter"></a>
Create後、以下の様な画面になるので、If This Then That の発火条件に当たる [+]This をクリックしましょう。
![bandicam 2020-02-20 00-15-27-203.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/f55159d0-bb51-6ab7-26f2-30105d06f997.jpeg)

クリックすると大量のプラットフォームが出てくるので、その中からTwitterを選びます。
マウスホイールを虐めながらTwitterを探すのもいいですが、Search servicesを利用した方がマウスホイールにやさしいです。

Twitterを選んだら、次はトリガー(発火条件)を選びます。
今回は自分がツイートしたときに発火して欲しいので、左上の New tweets by you を選択し、
Create Trrigerしましょう。
![bandicam 2020-02-20 00-19-26-043.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/6ee9faca-1896-289a-7afc-ad88b86aa977.jpeg)

![bandicam 2020-02-20 00-23-31-711.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/5177e083-07db-4836-4576-8d83d578ef7c.jpeg)

これで This、発火条件は設定完了です。

#### スプレッドシート側の設定<a id="IFTTSetting_settingSheet"></a>
続いて [+]That をクリックしてアクションを設定しましょう。
さっきのTwitterと同じようにして、今度はGoogleSheetsを選びます。
スプレッドシートの更新を見てGASを起動するので、TriggerはUpdate cell in spreadsheetにします。
<a id="spreadSheetSetting"></a>
するとActionの設定が出てきます。項目は以下の通り。
`Drive folder path`: 書き込みたいスプレッドシートのGoogleドライブ上のパス
`Spreadsheet name`: 書き込みたいシートの名前
`Which cell?`: 書き込むセル番地
`Value`:書き込む内容。Add ingredientを押すと、Twitterからの情報を選べるので、Text(本文)とLinkToTweet(ツイートへのリンク)を選んでおきます。
以下のように設定したらCreate action。
![bandicam 2020-02-22 18-35-43-626.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/e82d5ea5-c544-12ca-70ac-8ca5a9cfa375.jpeg)

後はFinishをクリックで終了。

### 動作テスト<a id="IFTTSetting_test"></a>
動作させるために、先ほど作ったレシピをConnentさせておく
下のトグルスイッチに"Connected"と表示されてたらokです
![bandicam 2020-02-22 19-15-14-784.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/e9eb32e5-597b-8aa6-d72a-f2257d6a87ed.jpeg)
#### This(Twitter) の動作チェック<a id="IFTTSetting_twittertest"></a>
[+]This でTwitterを選んだ時にログインしたアカウントでツイートしてみましょう。
![bandicam 2020-02-22 19-24-08-957.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/29dc81fe-20e7-bca2-62db-611d924872e6.jpeg)
ではIFTTTがツイートを拾えているか確認しに行きましょう。
先ほど作ったレシピのSettingから、View activityを開きます。
ツイートの内容が拾えていれば以下の様に表示されいます。
ただ、ツイートしてから拾うまでのラグがまちまちのため、しばらく待たないと出て来ないことが多いです
![bandicam 2020-02-22 19-27-06-491.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/159af725-3bd2-3c32-b1b6-03b5d23fd83c.jpeg)
ここで表示されていない場合は、記事を遡りつつ以下の可能性を考慮してみてください

- IFTTTが拾うのに失敗している(何度かツイートしてみてください)
- Connectしてない(IFTTTのレシピがConnectedになってるか確認してください)
- ツイートするアカウントを間違えている

#### That(スプレッドシート)の動作チェック<a id="IFTTSetting_sheettest"></a>
GASのスプレッドシートを開いて確認してください。
一番目のシートのA1にツイート内容とリンクが入力されていればokです
![bandicam 2020-02-22 19-38-52-383.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/2feb7968-c53c-f757-4fff-4afd884302f5.jpeg)
ここで、GASのスプレッドシートではなく新しくスプレッドシートが生成されてしまっている場合は[スプレッドシートの配置](#googleDrivePathSetting "IFTTTとやり取りするための準備")、もしくは[IFTTTのスプレッドシートのパス設定](#spreadSheetSetting "レシピを作成")が間違っています。

ここまでうまくいっていればIFTTTの準備は終わり。お疲れ様です

# DiscordのBot準備<a id="discordReady"></a>
さて、入力側の準備が終わったので今度は出力側の準備をしましょう。
BotといってもWevhookというものを使った機構なので、よく使うサーバーに呼び込んで使うものとはちょっと違います。

#### Webhookってなんやねん<a id="discordReady_nannyanenWebhook"></a>
[こちらの記事](https://qiita.com/soarflat/items/ed970f6dc59b2ab76169 "Webhookとは?")に詳しく書かれています
とりあえずは他のアプリケーションとやりとりするための機構だと思ってもらえればokです。
#### やっていき3<a id="discordReady_yatteiki"></a>
派遣する猫が迷わないようにします。
もとい、サーバーのWebhookを作成します

[こちらの記事](https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks "Intro to Webhooks")を参考にしました。

### サーバーの準備 <a id="serverOnedari "></a>
Webhookを作成するにはサーバーでの権限が必要です。
他人のサーバーで猫を受け取りたい場合は場合は管理人に相談して権限をもらってください。
もしくは自分でサーバーを立てましょう。

#### テキストを流すチャンネルの準備<a id="discordReady_textChannel"></a>
派遣された猫を受け入れるテキストチャンネルを用意します。
![bandicam 2020-02-22 20-57-21-248.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/27283ac8-ad64-27c5-8872-c5cb65fe0c0a.jpeg)

### Webhookの作成<a id="discordReady_createWebhook"></a>
サーバーの設定を開き、Webhookを作成します。
サーバーの設定に`ウェブフック`の項目がない場合はそのサーバーでの権限がない状態なので[どうにか](#serverOnedari "サーバーの準備")してください。
![bandicam 2020-02-22 21-02-43-966.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/851fef82-9920-b2c0-1c91-60958888cfa7.jpeg)
![bandicam 2020-02-22 21-02-54-878.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/72f94c1a-a988-3f09-7eb2-9f143a91c5f1.jpeg)

#### Webhookの設定 <a id="webhookURL"></a>
Webhookを作成したら設定が開くので、お好みの情報を入力してください。
猫を受け取った時、`ウェブフックのアイコン`と`お名前` を使ったBotが`チャンネル`にメッセージを送ってくれます。
また、一番下の`ウェブフックURL`はGASからDiscordにメッセージを送るのに使うため、控えておいてください。
![bandicam 2020-02-22 21-10-34-959.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/e722cafa-de9a-0610-9897-08418cb79b58.jpeg)
とりあえず私はこんな感じの設定にしました
![bandicam 2020-02-22 21-18-50-338.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/f808bcc4-36e0-dd6f-bab1-9d0c6f630b6d.png)

保存を押せばDiscordの受け入れ準備は完了です

# GASでDiscordへメッセージを送る<a id="sendDiscord"></a>
Discord側の受け入れ準備は終わったので、GASからメッセージを送りこめるようにします
#### やっていき4<a id="sendDiscord_yatteiki"></a>
VSCodeで、[GASの準備](#gasReady "GASの準備")で作ったプロジェクトを開いてください。

以下の様なフォルダ構成でやっていきます
各ファイルについてはこれから説明していきます

```
nyan-bot/
├── .clasp.json
├── node_modules/
├── package-lock.json
├── package.json
|
├── node_modules
└── src
    ├─ ts
    |  ├─ discord
    |  |  └─ IDiscordSendParameters.ts
    |  |  └─ IDiscordWebhookPayload.ts
    |  |  └─ WebhookSender.ts
    |  └─ gas
    |     └─ SpreadSheetUtil.ts
    └─ main.ts
    └─ appsscript.json
```

### ログ出力を実装<a id="sendDiscord_logREady"></a>
簡単にスプレッドシートにログを出す機構を先に作っておきます

```ts:SpreadSheetUtil.ts
export default class SpreadSheetUtil 
{
    //テキストのログ書き込み
    public static WriteToLogSheet = (text: string) => {
        //スプレッドシートを取得
        const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
        //シート`Log`を取得
        const sheet = spreadSheet.getSheetByName("Log");
        //シート`Log`の最終行にtextを書き込み
        sheet.appendRow([text]);
    };
    //HTTPResponse用のログ書き込み
    public static WriteResponseToLogSheet = (
      response: GoogleAppsScript.URL_Fetch.HTTPResponse
    ) => {
        SpreadSheetUtil.WriteToLogSheet(
        `[${response.getResponseCode()}] ${response.getContentText()}`
      );
    };
}
```

SpreadSheetUtil.WriteToLogSheet("ログ")
で、スプレッドシートのLogにログが出せます。
テストしてみましょう。
main.tsをいじってGASにpushします

```ts:main.ts
import SpreadSheetUtil from "./gas/SpreadSheetUtil";

function LogTest()
{
    SpreadSheetUtil.WriteToLogSheet("丸太テスト");
};
```

![bandicam 2020-02-22 22-23-13-849.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/fe92dc8c-3939-ba76-b30b-8389804f9e2f.png)

実行して、スプレッドシートの`Log`に出力されていれば成功です。
![bandicam 2020-02-22 22-28-35-993.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/1af5a8fa-1f44-5169-a671-0a8f33cf89a3.png)


### Discordのメッセージ型を実装<a id="sendDiscord_sendMSGReady"></a>
Discordにメッセージを送らせる、と言っても普通に送ってもWebhook君には理解できません。
Jsonで送る必要があります。
ということで[こちらの記事](https://qiita.com/Eai/items/1165d08dce9f183eac74 "DiscordにWebhookでいろいろ投稿する")を参考にメッセージInterfaceを作ります。
各ステートの詳細は参考記事の方を見てください。

```ts:IDiscordWebhookPayload.ts

export default interface IDiscordWebhookPayload {
    username?: string;
    avatar_url?: string; 
    content?: string; 
    embeds?: [ 
      {
        title?: string;
        description?: string;
        url?: string;
        timestamp?: string;
        color?: number;
        footer?: {
          text?: string;
          icon_url?: string;
        };
        image?: {
          url?: string;
        };
        thumbnail?: {
          url?: string;
        };
        author?: {
          name?: string;
          url?: string;
          icon_url?: string;
        };
        fields?: {
          name?: string;
          value?: string;
          inline?: boolean;
        }[];
      }
    ];
  }
```

### DiscordのWebhookにPostリクエストを送る<a id="sendDiscord_sendPost"></a>
メッセージの型も準備ができたので、いよいよDiscordにメッセージを送る機構を作っていきます。

#### HttpRequestパラメータを定義<a id="sendDiscord_paramReady"></a>
初めにHttpRequestのパラメータ型を定義しておきます

```ts:IDiscordSendParameters.ts
export default interface IDiscordSendParameters
{
    method: "get" | "delete" | "patch" | "post" | "put";
    payload: string;
    contentType: string,
    muteHttpExceptions: boolean;
}
```

#### DiscordにPostリクエストを送る機構を実装<a id="sendDiscord_requestReady"></a>
先ほどのパラメータを使ってDiscordにPostリクエストを送ります。
`DiscordWebHookSender.webhookURL`には[DiscordのBot準備](#webhookURL "Webhookの設定")で取得したウェブフックURLを入力してください。

```ts:WebhookSender.ts
import IDiscordWebhookPayload from "./IDiscordWebhookPayload";
import IDiscordSendParameters from "./IDiscordSendParameters";
import SpreadSheetUtil from "../gas/SpreadSheetUtil";

export default class DiscordWebHookSender
{
    //DiscordのウェブフックURL
    public static webhookURL:string="https://discordapp.com/api/webhooks/xxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx";

    //Postプロセスを送る
    public static Send(payload: IDiscordWebhookPayload):void
    {
        //Postリクエストのパラメータを作成
        const params: IDiscordSendParameters = {
            method: "post",
            payload: JSON.stringify(payload),
            contentType: 'application/json',
            muteHttpExceptions: true //エラーを起こしたときに、エラーの代わりに内容をHttpResponseを返してくれます。
        };
        
        //ログに、Discordに送るパラメータを表示
        SpreadSheetUtil.WriteToLogSheet("[Throw Discord Message]: "+params.payload);
      
        //DiscordにPostリクエストを送信
        const response = UrlFetchApp.fetch(this.webhookURL, params);
        //レスポンスをログに出力
        SpreadSheetUtil.WriteResponseToLogSheet(response);
    }
}
```

#### Discordにメッセージを送る！<a id="sendDiscord_sendDiscord"></a>
さて、Discordにメッセージを送る準備が整いました。
ということで動作テストです。
main.tsをいかに書き換えてGASにpushしましょう

```ts:main.ts
import SpreadSheetUtil from "./gas/SpreadSheetUtil";
import IDiscordWebhookPayload from "./discord/IDiscordWebhookPayload";
import DiscordWebHookSender from "./discord/WebhookSender";

function DiscordTest()
{
    const payload:IDiscordWebhookPayload=
    {
        content:"にゃんにゃん"
    };

    DiscordWebHookSender.Send(payload);
};
```
![bandicam 2020-02-22 23-30-12-797.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/c6bfc2a5-41a1-bd37-3936-e07dabbe49bd.png)

実行して、Discordでメッセージが送られれば成功です。
合わせてログも確認しましょう。
うまく送信できてない場合は`[204]`ではなくLogにエラーメッセージが出ます。
![bandicam 2020-02-22 23-29-23-598.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/aba5b168-5bff-448a-677c-23dabae8cd29.png)
![bandicam 2020-02-22 23-39-06-675.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/3a1d8409-80a6-0e18-4ef8-51721a71424b.png)


# IFTTTとDiscordをつなげる!<a id="connectBoth"></a>
準備は整った！あとはスプレッドシートに書きこまれるツイートを感知して、Discordに猫を派遣するのみです
### スプレッドシートに書き込まれたツイートを読み込む機能を実装<a id="connectBoth_read"></a>
ts:SpreadSheetUtil.tsに、スプレッドシートに書き込まれたツイートを読み込む機能、ReadRecvTweetを追加します

```ts:SpreadSheetUtil.ts
export default class SpreadSheetUtil 
{
    //テキストのログ書き込み
    public static WriteToLogSheet = (text: string) => {
        //スプレッドシートを取得
        const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
        //シート`Log`を取得
        const sheet = spreadSheet.getSheetByName("Log");
        //シート`Log`の最終行にtextを書き込み
        sheet.appendRow([text]);
    };
    //HTTPResponse用のログ書き込み
    public static WriteResponseToLogSheet = (
      response: GoogleAppsScript.URL_Fetch.HTTPResponse
    ) => {
        SpreadSheetUtil.WriteToLogSheet(
        `[${response.getResponseCode()}] ${response.getContentText()}`
      );
    };
    
    //ツイートの読み込み
    public static ReadRecvTweet():string {
        //スプレッドシートを取得
        const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
        //シート`RecvTweet`を取得
        const sheet = spreadSheet.getSheetByName("RecvTweet");

        //A1の内容を返す
        return sheet.getRange("A1").getValue();
    };
}
```

### "にゃーん"かどうか判別して、猫を派遣する<a id="connectBoth_sentCat"></a>
main.tsに、スプレッドシートが変更されたときに走る処理を書きます。
ツイートの内容が`にゃーん`なら猫を派遣し、それ以外が来た場合は派遣しません

```ts:main.ts
import SpreadSheetUtil from "./gas/SpreadSheetUtil";
import IDiscordWebhookPayload from "./discord/IDiscordWebhookPayload";
import DiscordWebHookSender from "./discord/WebhookSender";

function SocialFilterCat()
{
    //ツイートを取得
    const tweet=SpreadSheetUtil.ReadRecvTweet();

    //ツイートににゃーんが含まれるか解析
    if(tweet.indexOf("にゃーん")===-1)
    {
        //社会性フィルターじゃないので返る
        SpreadSheetUtil.WriteToLogSheet("<"+tweet+"> is not social filter");
        return;
    }

    //URLを取得
    const urlIndex=tweet.lastIndexOf("http://twitter.com/");
    const tweetURL=tweet.substring(urlIndex);

    const payload:IDiscordWebhookPayload=
    {
        content:":cat: \n"+tweetURL
    };

    DiscordWebHookSender.Send(payload);
};

```

できたらGASへpushして、`SocialFilterCat`を実行します。
実行したらLogを確認してください。
"にゃーん"とツイートしていなければこういうLogが出ると思います
![bandicam 2020-02-23 00-13-33-493.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/b7f81516-981f-51e6-a123-fe087f0220a8.png)

続いて、スプレッドシートの内容を"にゃーん"に変えて実行してみましょう。
![bandicam 2020-02-23 00-15-12-465.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/5d3cf40a-42f0-17bf-44de-8ec62a42b5ba.png)
![bandicam 2020-02-23 00-15-28-991.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/9c704a85-3c8c-c8c0-91af-8c969268c811.png)

可愛い猫ちゃんが派遣されました。

### IFTTTからの書き込みを検知して自動で実行する<a id="connectBoth_autoExe"></a>
これで一応猫を派遣できるようにはなりましたが、
手動でしか動かないのでまだ流しそうめんを一人でやっているような感じです。
…ということでIFTTTからのツイート書き込みを検知して自動で動くようにしましょう

#### トリガーを設定<a id="connectBoth_trrigerSett"></a>
発火条件、トリガーを設定します。
GASの`編集`->`現在のプロジェクトのトリガー`を開きます
![bandicam 2020-02-23 00-18-12-817.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/54111b67-31d4-35c5-cc61-75ec94e1921b.png)

開いたらトリガーを追加をクリック。
以下の設定にして保存します。
スプレッドシートで変更が行われたら`SocialFilterCat`が実行されるといった感じ。
![bandicam 2020-02-23 00-20-18-889.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/1856d7b9-3105-f298-aa26-caa062e5d99e.png)


# 鳴く！<a id="mew"></a>
![bandicam 2020-02-23 00-26-04-360.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/c7c10b85-1cde-4291-df46-14420a711f07.png)
![bandicam 2020-02-23 00-31-17-349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/66689323-4418-d6b5-624e-16f4dc6f5a54.png)
![bandicam 2020-02-23 00-30-43-108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575311/9f8f5600-6932-7517-8eac-1201ea6c7643.png)



…終わります。