新しい Google サイトで IFTTT の Webhooks をしてページ遷移が起こらないようにする

注）結構手間がかかります。中継地点として、AWS Lambda 使います。

「Google サイトで IFTTT の Webhooks にリクエストを送る NatureRemo のリモコンサイトを作って手軽にみんなに共有しよう！！！」

そう思い、ボタンを並べた Google サイトを作り始めたら、、、

「Google サイトに設置したボタンを押すとページが遷移してしまうやん！！」

…… それが嫌だということで色々考えてみました。

わざわざそんなことしなくていいじゃんという人もいるかもしれませんが、やってみたのでとりあえず共有します。

※ IFTTT の Webhooks の作り方には触れません。
※ Google サイトから NatureRemo の API を直接実行していないのは、IFTTT で NatureRemo のアクションを作るのが簡単だからです。だれでもボタンを追加、作成できるという点を意識した結果、このようにしています。

（新しい Google サイトの埋め込みコードで、リクエスト送れるのかという実験という意味合いでやったところもあります。）

# 現象（直したいところ）

IFTTT で Webhooks を使って作成した NatureRemo（家電を操作するスマートリモコン）の Applet のリンクを新サイトのボタンに設定すると、まあ当然といえば当然なのですが、リンクのページが開きます。（下図参照）
<img width="863" alt="Screen Shot 2019-05-16 at 16.26.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92506/fe8af1f4-07a0-c3f3-3f29-deec174c2571.png">

押す度にタブを閉じたり、切り替えたりするのをやりたくないので、今回直してみました。


# 直し方

新 Google サイトの埋め込みコードでリクエストを送るようにします。
<img width="125" alt="Screen Shot 2019-05-16 at 16.49.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92506/e051b017-8fd8-86bf-b377-c6a3432aa9c7.png">

"埋め込む"ボタンからオブジェクトを作成し、下記のコードを埋め込みます。

```html:GoogleSite埋め込み

<html>
<button id="test" onClick="sendAct()">TVオンボタン</button>

<script>
function sendAct() {
  var xhr = new XMLHttpRequest();
  var url = 'https://{AWS API Gateway エンドポイント}?url=https://{IFTTT Webhooks アドレス}';
  xhr.open('GET', url);
  xhr.onload = function() {
    console.log(xhr.status);
  };
  xhr.onerror = function() {
    console.log("error!");
  };
  xhr.send();
}
</script>
</html>
```

ここで直接、下図の IFTTT の POST リクエストを埋め込むと CORS エラーが出るので、AWS Lambda を中継することにしました。
<img width="766" alt="Screen Shot 2019-05-16 at 16.55.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92506/9236c1f3-3065-fb7f-6fbc-46cc2823d1c8.png">

<img width="1564" alt="Screen Shot 2019-05-16 at 17.21.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92506/f8e67e12-cb1a-0ebd-857a-7548ffb6f69b.png">

なので実際の作成手順は、AWS Lambda からになります。
下記コードで Lambda 関数を作成します。（child_process のモジュールが必要なので、zipファイルにしてソースコードをアップロードする必要があります。）

```javascript:index.js(Lambda)
exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin": "*" // Required for CORS support to work
        },
        body: JSON.stringify('OK, toss for IFTTT!'),
    };
    const execSync = require('child_process').execSync;
    
    console.log(event.queryStringParameters.url);
    const paramUrl = event.queryStringParameters.url;

    const cmd = `curl -X POST ${paramUrl}`;
    console.log(cmd);

    const result = execSync(cmd).toString();
    console.log(result);

    return response;
};

```

ボタンによってリモコンの操作内容を変えるため、新サイトのボタン埋め込み内容（リクエストのパラメータ値（"url="部））を変えることにより、IFTTT に投げる URL を切り替えられるようにしています。

Lambda 関数が完成したら、それを呼び出す API Gateway を "Lambda プロキシ統合の使用" をチェックの設定で作成します。

完成したエンドポイントを上記した新サイトの埋め込みコードの {AWS API Gateway エンドポイント} 部にセットします。
実行したい IFTTT のリクエストを "url=" 後の {IFTTT Webhooks アドレス} 部にセットして完成です。

<img width="1032" alt="Screen Shot 2019-05-16 at 17.15.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92506/70c5e790-c9c7-7286-cdc9-c2e49135f03d.png">

ボタンの見た目は、HTML を調整してうまいことかっこよくしてください。


# まとめ

切り替わっている様子を動画に撮る気までは起きないので見せられませんが、ページ遷移、新規タブが開くことなく快適に切り替わっています。
作ってみといてアレなのですが、、、本当にこのやり方しかなかったのかな？？？ とは思いました。