こんにちは。カスタマーエンジニアの高宮です。
本記事ではmicroCMSで投稿したコンテンツをLINEにも自動で投稿する方法をご紹介します。
この仕組みを使うことで、Webサイトに限らず重要なお知らせや最新のコンテンツをLINEのようなユーザーが日常的に利用しているプラットフォームに届けることができます。
今回はLINEを例に説明しますが、XやSlackなど他のサービスとも同じような手順で連携が可能ですので、ぜひ参考にしてみてください。
なお、本記事ではSSR(サーバーサイドレンダリング)を前提にした方法を説明します。SSG(静的サイト生成)を利用している場合は本記事で紹介する方法とは若干異なるアプローチを取る必要があります。詳細については後述します。
はじめに
はじめに今回実装する機能の全体像をご覧ください。
microCMSのコンテンツが公開されたタイミングで公式LINEからユーザーに向けてコンテンツの公開情報を届けるような仕組みを作ります。
LINEに送信するメッセージには以下の情報を出力します。
- ブログ更新をお知らせするメッセージ
- アイキャッチ画像
- ブログのタイトル
- 説明文
- サイトにリンクするためのボタン
使用するサービス・機能
microCMSで投稿したコンテンツをLINEに自動で投稿するために以下のサービス・機能を使用します。
処理の流れ
- microCMSでコンテンツを公開する
- 公開を検知し、Lambda関数にWebhookを送信する
- Lambda関数で受け取ったデータを整形し、Messaging APIに送信する
- LINEのトークルームにメッセージが送信される
AWS LambdaでmicroCMSのWebhookを受け取っていますが、Zapierやpipedreamなどの別のサービスでも可能です。
今回はなるべくコードの実装についてのみ言及したかったのと、将来的な拡張性やメンテナンス性を考慮してサーバーレスのサービスであるLambdaを選択しています。
注意
microCMSを通じて公開するサイトのレンダリング形式がSSGの場合は、コンテンツのビルドが完了した後にMessaging APIへリクエストする必要があります。
公開のタイミングでMessaging APIにリクエストをしてしまうと、サイトにコンテンツが生成されていない状態でLINEに通知が送信されてしまいます。
レンダリング形式がSSGの場合は、Vercel WebhookやGitHub Actionsなどを利用して、コンテンツのビルドが完了したタイミングでMessaging APIにリクエストするようにしてください。
準備
まずは必要な設定をします。
microCMSの設定
まず、APIを作成します。今回はテンプレートからブログのAPIを作成します。
フロントエンドの実装に関する詳細は省略しますが、ブログをSSRでレンダリングするページを作成します。
Webhookの設定はAWS Lambda関数を作成した後に設定します。
Messaging APIを利用するための設定
Messaging APIを利用するにはLINE公式アカウントを作成後、Messaging APIを有効にする必要があります。
公式アカウントの作成方法とMessaging APIの有効にする方法については、以下の記事を参考にしてください。
LINE Developers: Messaging APIの利用を始めよう
今回はMessaging APIの「ブロードキャストメッセージ」を利用します。
ブロードキャストメッセージは以下のエンドポイントにリクエストすると友だちになっているすべてのユーザーに、メッセージを送信できます。
POST https://api.line.me/v2/bot/message/broadcast
なお、エンドポイントへのリクエスト時、リクエストヘッダーにチャネルアクセストークンを含める必要があります。
チャネルアクセストークンはLINE Developersのコンソールで取得できますので、控えておきましょう。
実装方法
準備が整ったら、実際にmicroCMSのコンテンツをLINEに送信する仕組みを実装します。
Lambda関数の作成
今回はマネジメントコンソールでLambda関数を作成します。
AWS Lambdaの「関数の作成」画面 にアクセスします。
以下の手順で関数を作成します。
- 一から作成を選択
- 関数名にsend-line-messageを入力
- ランタイムはNode.js 20.xを選択
- アーキテクチャはx86_64を選択
次に詳細情報を設定します。
- 「関数URLを有効化」にチェックを入れる
- 認証タイプは「NONE」を選択
- その他の設定はデフォルトのまま[関数の作成]ボタンをクリック
認証タイプに関する注意点
認証タイプをNONEに設定する場合、Lambda関数のエンドポイントは認証なしでアクセスできてしまいます。今回はmicroCMSからのリクエスト時のみ処理を実行するように関数を実装するため、NONEに設定しています。
環境変数の設定
関数が作成できたら環境変数を設定します。
LINEのチャネルアクセストークンとmicroCMSからのリクエストを検証するために利用するシークレット値を設定します。
設定 > 環境変数 > 編集へと移動します。
LINEのチャネルアクセストークン:キーにはLINE_CHANEL_ACCESS_TOKEN
、値に控えていたチャネルアクセストークンを設定します。
シークレット値:キーにはMICROCMS_SECRET
、値には極力推測されづらい値を設定してください。シークレット値は後にWebhookの設定でも利用します。
2つを設定したら[保存]ボタンをクリックします。
Lambda関数のコードを記述
環境変数を設定したらコードを記載します。
全体像は以下のとおりです。
import crypto from 'crypto'
export const handler = async event => {
// microCMSからのリクエストかを検証
const signature = event.headers['x-microcms-signature']
const expectedSignature = crypto
.createHmac('sha256', process.env.MICROCMS_SECRET)
.update(event.body)
.digest('hex')
if (
!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature),
)
) {
throw new Error('署名認証エラー')
}
// リクエストボディからコンテンツIDとコンテンツの内容を取得
const data = event.body
const { id, contents } = JSON.parse(data)
// 更新の場合は処理を終了
const isUpdated = contents.old !== null
if (isUpdated) return 200
// 公開したコンテンツの情報を取得
const { title, eyecatch, description } = contents.new.publishValue
// Messaging APIにリクエストする際のメッセージオブジェクトに整形
const obj = {
messages: [
{
type: 'text',
text: '\ ブログを更新しました /',
},
{
type: 'template',
altText: 'ブログを更新しました',
template: {
type: 'buttons',
thumbnailImageUrl: eyecatch.url,
imageSize: 'contain',
title: title,
text: description,
actions: [
{
type: 'uri',
label: '詳しく見る',
uri: `https://example.com/blogs/${id}`,
},
],
},
},
],
}
// LINE Messaging APIにリクエスト
try {
const res = await fetch('https://api.line.me/v2/bot/message/broadcast', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.LINE_CHANEL_ACCESS_TOKEN}`,
},
body: JSON.stringify(obj),
})
return res.json()
} catch (e) {
console.error(e)
return 500
}
}
1. microCMSからのリクエストかを検証する
今回は、Lambda関数へのリクエストは関数URLを利用しています。この関数URLの認証タイプを「NONE」に設定しているため、誰でもそのURLにアクセスしてLINEにメッセージが送信できてしまいます。
microCMSのWebhookからのリクエストのみ処理を実行するために、シークレット値を利用してリクエストの検証をします。
const signature = event.headers['x-microcms-signature']
const expectedSignature = crypto
.createHmac('sha256', process.env.MICROCMS_SECRET)
.update(event.body)
.digest('hex')
if (
!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature),
)
) {
throw new Error('署名認証エラー')
}
2. リクエストボディからコンテンツIDとコンテンツの内容を取得する
microCMSからのWebhookはPOSTリクエストで送信されます。
リクエストボディにはJSON形式でエンコードされたコンテンツの情報(以下これをPayloadと呼びます)が含まれているので、そこから必要なデータを取得します。
const data = event.body
const { id, contents } = JSON.parse(data)
3. 更新の場合は処理を終了する
今回は、コンテンツが新規で公開されたときのみLINEに通知するようにします。
Payloadには、コンテンツの編集前と編集後のデータが含まれています。
コンテンツの新規作成時にはcontents.old
の値がnull
になりますので、null
ではない場合は更新とみなして処理を終了します。
const isUpdated = contents.old !== null
if (isUpdated) return 200
4. 必要なデータの取得してメッセージオブジェクトに整形する
必要なデータを取得し、Messaging APIが受け取れるメッセージオブジェクトに整形します。
Messaging APIのメッセージタイプには、いくつかの種類がありますが今回は「テキストメッセージ」と「ボタンテンプレート」を使用します。
const { title, eyecatch, description } = contents.new.publishValue
const obj = {
messages: [
{
type: 'text',
text: '\ ブログを更新しました /',
},
{
type: 'template',
altText: 'ブログを更新しました',
template: {
type: 'buttons',
thumbnailImageUrl: eyecatch.url,
imageSize: 'contain',
title: title,
text: description,
actions: [
{
type: 'uri',
label: '詳しく見る',
uri: `https://example.com/blogs/${id}`,
},
],
},
},
],
}
actions:[...]
にはタップされた際の挙動に関する記載をしています。
[詳しく見る]ボタンをクリックするとuri
に指定されたURLにリンクします。この例では、https://example.com/blogs/${id}
のようにブログのIDを動的に埋め込むことで、更新した記事にリンクするように設定しています。
5. Messaging APIへのリクエスト
POSTメソッドで以下のエンドポイントにリクエストを送信します。
https://api.line.me/v2/bot/message/broadcast
リクエストヘッダーには、Authorization
ヘッダーを含め、環境変数で定義したチャネルアクセストークンをBearerトークンとして指定しています。
リクエストボディには、前述のメッセージオブジェクトをJSON形式でエンコードして送信します。
try {
const res = await fetch('https://api.line.me/v2/bot/message/broadcast', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.LINE_CHANEL_ACCESS_TOKEN}`,
},
body: JSON.stringify(obj),
})
return res.json()
} catch (e) {
console.error(e)
return 500
}
}
ここまで実装したらLambda関数をデプロイし、関数URLを控えておきます。
Lambda関数のURLをmicroCMSのWebhookに設定
Lambdaの実装を終えたら、microCMSのWebhookに設定します。
API > API設定 > Webhook > 追加 > カスタム通知の順で選択します。
Webhookを通知するURLには控えていたLambdaの関数URLを入力します。
シークレットにはLambdaの環境変数に登録したMICROCMS_SECRET
と同じ値を入力します。
また、通知タイミングの設定はコンテンツの公開に関する操作のみチェックをいれます。
ここまで設定するとコンテンツ公開時に公式LINEからユーザーに向けてメッセージが送信されるようになります。
最後に
今回はmicroCMSで投稿したコンテンツをLINEにも自動で投稿する仕組みを構築しました。
microCMSのWebhookを利用すればLINEだけでなくXやSlackなどのサービスにも自動でコンテンツを投稿できます。
ぜひさまざまなユースケースに応用してみてください。