@kyanny's blog

Remember Everything

Integromat で Instagram の投稿を LINE に通知する

妻がたまに猫の写真を Instagram に投稿している。可愛いので妻の母にも見せたい。妻の母は Google Play に未対応のらくらくスマホを使っており Instagram が使えないが LINE は使える。そこで Instagram の投稿を LINE に通知する仕組みを作った。

以下の 4 つの方法を試し、 Integromat を採用した。

  1. IFTTT
  2. Zapier
  3. Integromat
  4. スクレイピング

なお、かつては myThings を使っていた。 myThings の Instagram 連携は自分自身だけでなく任意のユーザーの投稿をトリガーにできて便利だった。

1. IFTTT

サービス連携サービスの元祖。多少の癖はあるが、 4 つの中では一番簡単。

利点

  • 実行回数や実行時間などの制限が無い
  • LINE 連携の設定が簡単
    • アカウント連携して通知先チャンネルを選ぶだけ

欠点

  • デバッグがしづらい(ログ等が貧弱)
  • 投稿に複数の写真が含まれているとトリガーされない

「投稿に複数の写真が含まれているとトリガーされない」が致命的だったので不採用。

2. Zapier

IFTTT の高機能版。 JavaScript または Python で任意の処理を書けるのが非常に強力で、標準ライブラリも使えるので事実上なんでもできる。

Instagram API 対応も Zapier が一番充実していた。複数の写真を含む投稿は Instagram Basic Display API の用語だと media_type: CAROUSEL_ALBUM にあたるが、複数の写真全てのデータにアクセスできるのは Zapier だけだった。

利点

  • スクリプトを書けばなんでもできる
  • CAROUSEL_ALBUM 内の複数の写真データを扱える
  • デバッグしやすい(ログ等が比較的充実している)

欠点

  • オフィシャルに LINE 対応していない
  • 実行回数や実行時間の制限が厳しい(実行時間制限 1 秒)
    • 今回は実行回数は許容範囲内だったが、外部 API を叩くので 1 秒を超えることが多かった
  • 有料プランの値段が高い($19.99/month しかも一年分払った場合)

実行時間制限 1 秒の壁があり、成否が安定しないので不採用。それを撤廃するためだけに 2,000 円/月も払えない。金を払うのであれば RSS.app の BASIC プラン($4.99/month)で Instagram の RSS フィードを作って IFTTT と繋ぐほうが安上がりだ(タイムラグは長いが)。

なお、 Zapier のサイト上では Webhooks by Zapier は PREMIUM とラベルされている。 Free プランでは使えないと思い、今回は Code by Zapier を使って LINE Notify API に POST したが、試してみたら Free プランでも Webhooks で POST できた。なぜだろう。

3. Integromat

IFTTT の高機能版。こちらはスクリプトを書く機能は無いが、 HTTP リクエストを発行できる。 JSON の加工モジュールが充実しており、プログラミング無しでも高度なことをやれるようにという思想が垣間見える。 UI しかり、往年の Yahoo! Pipes を彷彿とさせる。

Instagram API の対応は IFTTT と Zapier の中間。 CAROUSEL_ALBUM の投稿でもトリガーされるが、複数の写真データは扱えない(最初の一枚だけ)。

利点

  • CAROUSEL_ALBUM の投稿でトリガーされる
  • 任意の HTTP リクエストを発行できる
    • LINE Notify API にも POST できる
  • デバッグしやすい(ログ等が充実している)
  • 実行回数や実行時間の制限が緩い

欠点

  • LINE Notify API を自分で叩く必要がある
  • CAROUSEL_ALBUM 内の複数の写真データは扱えない(最初の一枚だけ)
  • 多少おかしなところがある
    • 開発中にデータソースからテストデータを取得する条件を(過去何件分、とか)一度設定すると変更できない
    • Instagram アカウントと連携させる初回操作がわかりづらい(いきなり Add ボタンを押すという操作が UI から連想できない)
    • ワークスペースにモジュールを追加すると削除できない

複数枚の写真を全て LINE に通知することはできないが、 LINE Notify API は message が必須なのを逆手に取って一枚目の写真とともに permalink を投稿すれば、リンクをたどって Instagram のページから二枚目三枚目の写真を見ることができる(見ようと思えば)。今回はこれで妥協した。

4. スクレイピング

instagram-scraper を使う。これを GitHub Actions で動かす、というアイデア。 Docker Image もある。

instagram-scraper には差分ダウンロードの仕組みがある。

--latest オプション

ローカルディスク上にダウンロードしたメディアファイルのタイムスタンプで比較する。ローカルディスク上にメディアファイルを永続化する必要がある。

--latest-stamps オプション

タイムスタンプをテキストファイルに保存する点が --latest オプションと異なる。 --latest-stamps timestamp.txt のようにファイル名を指定する。ローカルディスク上にメディアファイルがなくてもよい。

一通り動く状態まで試行錯誤したものを GitHub に置いた。タイムスタンプを保存したテキストファイルを Add & Commit アクションで自身のリポジトリにコミットしたり、 GitHub Actions で完結するように工夫した。

スクレイピング処理をスケジュール実行するのは気が引けた。別の方法で Instagram の更新チェックをして GitHub Actions を叩く、などするとピタゴラスイッチ化するし、美しくないので不採用。

まとめ

いろいろ試す過程も含めて満足のいく結果となった。 Integromat の HTTP リクエスト組み立て時に LINE Notify のアクセストークンをべた書きしているのが玉に瑕。 RSS.app + IFTTT のほうがスマートな気もするが、 RSS.app の BASIC プランは更新間隔が 3 時間とやや長いのもあって今回は不採用。

f:id:a666666:20200510051943p:plain