14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

これでもう見逃さない!Amazonアウトレットのお得情報をTwitterからLINE Botに自動連携。

Last updated at Posted at 2021-05-29

##Amazonアウトレットのお得情報は見逃せない!
Amazonアウトレットというサービスをご存知でしょうか?
Amazonでは以下のように説明されていますが、とにかくお得に商品を購入できるサービスです。

Amazonアウトレットは、倉庫内で梱包に傷を負った商品・お客様から返品された商品のうち、商品の状態が良いにも関わらず、Amazon.co.jp の厳密な基準では新品として販売しないものを「アウトレット品」という扱いで、お手頃な価格で販売しています。また、倉庫内で保管され、賞味期限が近づいた食品を、お手頃な価格で販売しています。

さて、とてもお得なAmazonアウトレットですが、問題点が一つ。
商品が登録されてから売り切れるまでが非常に早いのです。(モノによりますが)
私はTwitterでAmazonアウトレットのお得情報をツイートしてくれるアカウントをフォローしていますが、気づいて見に行った時にはもう売り切れているということが良くありますし、そもそも他のツイートに埋もれて気づかないということも間々あります。

そこで、Twitterで発信されたお得情報を素早くキャッチするため、LINE Botで通知をもらうようにしました。
ついでにGoogleスプレッドシートで一覧化すれば商品の検索もスムーズになるってもんです。

##作ったもの
以下の様なサービスを組み合わせて自動化の仕組みを作りました。
image.png

Screenshot_20210529-152122_LINE.jpg
こんな感じでLINEに飛んできます。

それぞれの役割と使用理由について簡単に書きます。

①Twitter
Amazonアウトレットのお得情報を拾うための媒体です。
今回は特定のアカウントのツイートを監視することになります。

②Googleスプレッドシート
Twitter上で発信された情報を一覧化するために使用。
リンクなどを見やすく一覧化することでAmazonアウトレットでのお買い物が捗るはずです。

③LINE Bot
Twitter上でお得情報が発信されたことを私に気づかせてくれます。
**「結局LINEが一番タイムリーに確認する(できる)」**ということで採用

④Zapier
ツイートに反応してGoogle Apps Scriptに伝える役割を担います。
IFTTTと違いWebhook機能が有料だったり(今回は無償期間で作成)月の実行制限(100回/月)が厳しかったりしますが、
UIが使いやすかったのとテストのし易さから採用に至りました。

⑤Google Apps Script(GAS)
Zapierからのリクエストを受け付けてGoogleスプレッドシートに書き込みつつ、次のWebhookに繋ぐという役割。
スプレッドシートの取り回しが良いところが一番の利点でしょうか。

⑥Integromat
GASからのリクエストを受け付けてLINE Botにブロードキャストする役割になります。
Webhook利用が無料且つLINEとのコネクタが用意されているので採用。

##作り方
ここからは作り方を解説していきます。
今回の仕組みは連携の後ろ側から作った方がやりやすいので順番は以下の通りです。
①LINE Botで通知する部分
②情報をスプレッドシートに書き込む部分
③ツイートに反応してWebhookを投げる部分

###①LINE Botで通知する部分
最終的にLINE Botで通知を受け取りたいのですが、通知の内容はツイートの本文にしようと思います。
この部分は既に記事にしてあるので、こちらを参考にしてください。(リンク先の内容がそのまま使えます。)

Integromatを使ってWebhookで受け取った内容をLINE Botに流す

###②情報をスプレッドシートに書き込む部分
続いてGAS上で作る部分です。
自身のGoogleアカウントで新規スプレッドシートを開きましょう。
Googleのホーム画面でアプリ一覧を選択して真ん中あたりにあるスプレッドシートを選択
image.png

スプレッドシートの管理画面に飛んだら空白のスプレッドシートを選択
image.png

スプレッドシートが開いたら「ツール」⇒「スクリプトエディタ」を選択
image.png

エディタが開くので、ここにスクリプトを書き込んでいきます。

今回作ったスクリプトの全文はこちら
// POSTリクエストを処理する関数
function doPost(e) {
  // textというキーに値があればそれをスプレッドシートに書き込みます(FormData)
  let params = JSON.parse(e.postData.getDataAsString());
  writeLogToSheet(params.create,params.text,params.url1,params.url2);

  //Integromatで用意したWebhookURLにテキストを投げる
  const URL = 'Integromatで作成したWebhookのURL(末尾にパラメータ用の「?text=」を付ける)';
  UrlFetchApp.fetch(URL + encodeURIComponent(params.text));

  // リクエスト送信元に返信する
  const data = { text: `POSTリクエストを受付ました。` };
  return ContentService.createTextOutput(JSON.stringify(data));
}

// シートにログを書き込む関数
function writeLogToSheet(create = 'x',text = 'x',url1 = 'x',url2 = 'x') {
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  // ループを回して1行ずつすでに記録されていないか確認していく
  let currentRow = 1;
  while (true) {
    // 記録されていない行が見つかったとき:
    if (!sheet.getRange(currentRow, 1).getValue()) {
      // 1列目に日付時刻を記録
      sheet.getRange(currentRow, 1).setValue(create2date(create));
      // 2列目に本文テキスト(引数値)を記録
      sheet.getRange(currentRow, 2).setValue( text );
      //商品URLは","区切りなので分解
      let urls = url1.split(',');
      // 3列目に商品URL(分割した1つ目)を記録
      sheet.getRange(currentRow, 3).setValue( urls[0] );
      // 4列目に予備URL(分割した2つ目)を記録
      sheet.getRange(currentRow, 4).setValue( urls[1] );
      // 5列目にツイートURL(引数値)を記録
      sheet.getRange(currentRow, 5).setValue( url2 );
      // ループ中断
      break;
    }
    // 次の行へ
    currentRow++;
  }
}

//日付時刻を成型する関数
create2date = function(create){
	let date = new Date(create);
	date.setHours(date.getHours()); // UTC -> JST (+9時間)
	let y    = date.getFullYear();      // 年取得
	let mon  = date.getMonth() + 1;     // 月取得
	let day  = date.getDate();          // 日取得
	let h    = date.getHours();         // 時取得
	let min  = date.getMinutes();       // 分取得
  let sec  =  date.getSeconds();      // 秒取得

  //年月日時分秒に成型
	create = y+ '/' + mon + '/' + day +' ' + h + ':' + min + ':' + sec;
	return create;
}

作成したスクリプトは3つの関数でできています。
順番に見ていきましょう。

####POSTリクエストを処理する関数

function doPost(e) {
  // textというキーに値があればそれをスプレッドシートに書き込みます(FormData)
  let params = JSON.parse(e.postData.getDataAsString());
  writeLogToSheet(params.create,params.text,params.url1,params.url2);

  //Integromatで用意したWebhookURLにテキストを投げる
  const URL = 'Integromatで作成したWebhookのURL(末尾にパラメータ用の「?text=」を付ける)';
  UrlFetchApp.fetch(URL + encodeURIComponent(params.text));

  // リクエスト送信元に返信する
  const data = { text: `POSTリクエストを受付ました。` };
  return ContentService.createTextOutput(JSON.stringify(data));
}

POSTリクエストを受け付けた際に動く関数です。

パラメータはJson形式に変換します。

let params = JSON.parse(e.postData.getDataAsString());

スプレッドシートに書き込んだ後はLINE Botに繋げるために、先ほどの手順で作成したIntegromatのWebhookURLに対してGETリクエストを投げます。

const URL = 'Integromatで作成したWebhookのURL(末尾にパラメータ用の「?text=」を付ける)';
UrlFetchApp.fetch(URL + encodeURIComponent(params.text));

####スプレッドシートへの書き込みを行う関数

function writeLogToSheet(create = 'x',text = 'x',url1 = 'x',url2 = 'x') {
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  // ループを回して1行ずつすでに記録されていないか確認していく
  let currentRow = 1;
  while (true) {
    // 記録されていない行が見つかったとき:
    if (!sheet.getRange(currentRow, 1).getValue()) {
      // 1列目に日付時刻を記録
      sheet.getRange(currentRow, 1).setValue(create2date(create));
      // 2列目にメッセージ(引数値)を記録
      sheet.getRange(currentRow, 2).setValue( text );
      //商品URLは","区切りなので分解
      let urls = url1.split(',');
      // 3列目に商品URL(分割した1つ目)を記録
      sheet.getRange(currentRow, 3).setValue( urls[0] );
      // 4列目に予備URL(分割した2つ目)を記録
      sheet.getRange(currentRow, 4).setValue( urls[1] );
      // 5列目にツイートURL(引数値)を記録
      sheet.getRange(currentRow, 5).setValue( url2 );
      // ループ中断
      break;
    }
    // 次の行へ
    currentRow++;
  }
}

先ほど新規作成したスプレッドシートを1行目から探索して、空行があったら書き込むようになっています。
POSTリクエストで受け取ったパラメータを1列目から順に書いていますが、「url1」だけはツイートの性質から2つURLが入ってくることが分かっているので、分割して記録しています。

//商品URLは","区切りなので分解
let urls = url1.split(',');
// 3列目に商品URL(分割した1つ目)を記録
sheet.getRange(currentRow, 3).setValue( urls[0] );
// 4列目に予備URL(分割した2つ目)を記録
sheet.getRange(currentRow, 4).setValue( urls[1] );

####ツイート時刻の成型をする関数

create2date = function(create){
	let date = new Date(create);
	date.setHours(date.getHours()); // UTC -> JST (+9時間)
	let y    = date.getFullYear();      // 年取得
	let mon  = date.getMonth() + 1;     // 月取得
	let day  = date.getDate();          // 日取得
	let h    = date.getHours();         // 時取得
	let min  = date.getMinutes();       // 分取得
  let sec  =  date.getSeconds();      // 秒取得

  //年月日時分秒に成型
	create = y+ '/' + mon + '/' + day +' ' + h + ':' + min + ':' + sec;
	return create;
}

TwitterのAPI仕様でツイート時刻のフォーマットが「Wed, 03 Oct 2012 00:00:00 +0000」のようになっています。
このままでは見づらいので変換をしています。

####作成したスクリプトをWebアプリケーションとしてデプロイ
スクリプトが完成したら保存した後にデプロイします。
画面右上のデプロイを選択ご、「新しいデプロイ」を選択

image.png

種類の選択の右にある歯車マークを選択して「ウェブアプリ」を選択
image.png

アクセスできるユーザーを「全員」にしてデプロイを選択
image.png

ウェブアプリのURLが表示されます。(アカウントに対する許可を求められる場合があります。)
このURLは次の工程で使用します。
image.png

これでGAS上での作業は完了です。

###③Twitterの呟きに反応してWebhookを投げる部分
Zapierで新しいZapを作ります。
Triggerに「Twitter」を選択。
image.png

今回は特定アカウントのツイートを監視するのでTrigger Eventは「User Tweet」を選択
image.png

自身のアカウントで認証したら、Set up triggerに監視したいアカウントを入力
image.png

Test triggerで問題なくツイートが拾えればOKです。

続いてActionの設定です。
Webhooks by Zapierを選択
image.png

Action EventはPOSTを選択します。
image.png

URLにGAS上のWebhookURLを設定して、Payload Typeを「Json」に変更します。
パラメータとして以下の4つを設定します。

パラメータ名 設定したtweetの属性 概要
create Created At ツイートされた時刻
text Text ツイートの本文
url1 Entities Urls URL ツイート中に記載の商品URL
url2 URL ツイートのURL

image.png

これで設定は完了です。
テストを実行してみてください。
上手くいけばスプレッドシートへの書き込みとLINE Botからの通知が実行されます。

##まとめ
今回はTwitterを監視してLINE Botに繋ぎましたが、これが想像以上に便利でした。
特定アカウントだけでなくツイートの中身によって通知することもできるので色々な使い道が出てきそうです。
ただ、今回使用したZapierは無料アカウントだとWebhookが使えなかったり、月の実行数制限が厳しかったりするので、IFTTTに置き換えるなども今後検討していきたいと思います。

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?