microCMSのコンテンツ公開時に自動でXにポストする
やりたいこと
WebサイトのコンテンツをmicroCMSで管理しているとします。コンテンツ公開時に自動で新着記事をお知らせする投稿をX(旧Twitter)にポストすることを考えます。
SSG構成だとビルド完了までに時間がかかり、すぐにポストしてしまうと公開状態が追いつきません。また、タイミングは新規公開時のみを対象にして、既存コンテンツの更新時はポストしないようなものを作りたいです。
Pipedreamを使ってこのワークフローをうまく構築できたので、内容を書いておきます。
ざっくり設計
- Pipedreamを使ってmicroCMSのWebhook通知を受け、Twitter APIを使ってポストする
- Webhookのbodyをパースして、ポストの本文を構築する
- Webhookのbodyを見て、更新のイベントであればポストしない
- ビルド待ちの設計はルーズで良いとして、ビルドが大体1分前後なので2分待ってからXにポストする
こんな感じを目指して作っていきます。
詳細
Pipedreamについて
PipedreamはIFTTTやZapierのようなワークフロー統合プラットフォームで、いろいろなサービスのAPIやデータがあらかじめプリインされています。
必要な処理をパズル感覚で繋げていくことでワークフローを構築でき、必要に応じてNode.jsやPythonでコードを書けるなど、小回りの効く設計になっています。
各サービスのAPI仕様書を読んで実装して、APIがアップデートしたらそれに追従して...とするのは大変です。Pipedreamに任せておけば自動でアップデートしてもらえるのでとても助かります。
Twitter APIのプラン変更でIFTTTなどのサービスは有料プランでしかTwitter連携ができなくなっていますが、Pipedreamでは送信だけなら無料で利用できます。趣味のブログにとってはありがたいことなので、今回はPipedreamを選びました。
全体感
作ったワークフローは4つのステップからなります。それぞれ紹介します。
1. WebhookをワークフローのTriggerに設定
起点となるTriggerを「Webhook」にしています。
PipedreamでWebhookを選ぶと専用のURLが発行されるので、それをmicroCMSにセットします。
microCMSでは、API > API設定 > Webhook > カスタム通知 を選択し、上記のURLをセットしました。
これでmicroCMSで記事が更新されたときにワークフローを発火できます。
2. Filterで新規公開のイベントのみに絞る
今回の要件では新規公開時のみを対象にしたく、既存記事の更新時にはポストしたくありません。Webhookのbodyの内容をみて分岐していきます。
注目するのは oldValue
という項目で、新規公開時にはこの値が null
になっています。oldValue
の値が null
の場合のみ次のステップに進むよう、Pipedreamでセットします。
値とConditionをセットしました。Initial ValueのところはWebhookのペイロードから選択して入力できるようになっており、自分で記述する必要はありません。
3. 2分待機する
ビルド完了を待つために2分遅らせます。Pipedreamに「Delay」というアイテムが用意されているので、それを選択して時間を指定するだけです。
待ち時間を決め打ちしてしまうのはややラフな設計です。ページ数が増えてビルド時間が伸びると間に合わなくなりますし、何らかの理由でビルドが失敗した場合もポストされてしまいます。
VercelのWebhookを使えばもう少しうまく表現できる気がしましたが、今回は厳密な運用は必要ないのでDelayでつくりました。
4. Xにポストする
ここは本来「Xにポストする」ワークフローを使えば簡単に組めるですが、OAuthの認証がなぜかうまくいかなかったのでPythonで自分で書いています。なので参考にならないかもですが、一応書いておきます。
Pipedreamで「Python」のブロックを選び、そこに以下のコードを実装します。
import os
import tweepy
def handler(pd: "pipedream"):
# Webhookのbodyの内容を取得
id = pd.steps["trigger"]["event"]["body"]["id"]
title = pd.steps["trigger"]["event"]["body"]["contents"]["new"]["publishValue"]["title"]
# キー情報を環境変数から読み出し
CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
ACCESS_TOKEN = os.environ['ACCESS_TOKEN']
ACCESS_SECRET = os.environ['ACCESS_SECRET']
# Twitterクライアントを作成
client = tweepy.Client(
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET,
access_token=ACCESS_TOKEN,
access_token_secret=ACCESS_SECRET,
)
# ポストを投稿
client.create_tweet(text=f"{title}\nhttps://my-blog.com/posts/{id}")
ソースコードの最初でWebhookのbodyから必要な内容を抽出しています。
ここのパスは自分で構築する必要はなく、Webhookのbodyを確認する画面で対象フィールドにhoverすると表示される「Copy Path」を押下すると取得できます。便利ですね。
Twitter APIにアクセスするための各種情報はTwitter Developer Platformで発行します。やや複雑ですが、取得方法を紹介している記事はたくさんあるので探してみてください(こちらの記事とか)。
取得したキー情報は環境変数に保持します。Pipedreamのプロジェクトに環境変数をセットして、os.environ['CONSUMER_KEY']
のような形で読み出せます。
Xへのポストにはtweepyというライブラリを使ってます。Pipedreamでは必要なライブラリは事前にインストールされるそうで、pip install
といったコマンドは書かなくてOKです。便利ですね。
動作確認する
ワークフローができたらDeployして実行できる状態にします。microCMSで記事を公開してみてると、Xにポストが投稿されることが確認できるはずです。
また、既存記事の更新でXへポストされないことも確認してみましょう。microCMSで既存記事を更新してみます。
2つ目のステップでワークフローが終了していることが確認できました。
これでワークフロー構築は完了です。
おわりに
microCMSの記事公開を受けてXに投稿する方法について書きました。
Pipedreamは初めて使いましたがUIも使い方もわかりやすかったです。機会があれば触ってみてください:)
Discussion