microCMS

microCMSのコンテンツを外部サービスにも自動で投稿しよう(with Lambda × LINE Messaging API)

高宮 竜太

こんにちは。カスタマーエンジニアの高宮です。
本記事ではmicroCMSで投稿したコンテンツをLINEにも自動で投稿する方法をご紹介します。

この仕組みを使うことで、Webサイトに限らず重要なお知らせや最新のコンテンツをLINEのようなユーザーが日常的に利用しているプラットフォームに届けることができます。

今回はLINEを例に説明しますが、XやSlackなど他のサービスとも同じような手順で連携が可能ですので、ぜひ参考にしてみてください。

なお、本記事ではSSR(サーバーサイドレンダリング)を前提にした方法を説明します。SSG(静的サイト生成)を利用している場合は本記事で紹介する方法とは若干異なるアプローチを取る必要があります。詳細については後述します。

はじめに

はじめに今回実装する機能の全体像をご覧ください。
microCMSのコンテンツが公開されたタイミングで公式LINEからユーザーに向けてコンテンツの公開情報を届けるような仕組みを作ります。
microCMSにコンテンツを公開してLINEにコンテンツを投稿する様子。LINEに投稿されたコンテンツをクリックするとWebサイトにリンクする
LINEに送信するメッセージには以下の情報を出力します。

  • ブログ更新をお知らせするメッセージ
  • アイキャッチ画像
  • ブログのタイトル
  • 説明文
  • サイトにリンクするためのボタン

LINEのトーク画面。「ブログを更新しました」という更新を知らせるテキストと、サムネイル画像、タイトル、説明が出力されている

使用するサービス・機能

microCMSで投稿したコンテンツをLINEに自動で投稿するために以下のサービス・機能を使用します。

  1. microCMS Webhook
  2. LINE Messaging API
  3. AWS Lambda

処理の流れ

  1. microCMSでコンテンツを公開する
  2. 公開を検知し、Lambda関数にWebhookを送信する
  3. Lambda関数で受け取ったデータを整形し、Messaging APIに送信する
  4. LINEのトークルームにメッセージが送信される

micrcoCMSの情報をLINEにも投稿する際の処理の流れ。コンテンツ管理者がmicroCMSで記事を公開するとLambdaにWebhookが通知され、LambdaからMessaging APIにリクエストすることでユーザーにコンテンツを届ける
AWS LambdaでmicroCMSのWebhookを受け取っていますが、Zapierpipedreamなどの別のサービスでも可能です。
今回はなるべくコードの実装についてのみ言及したかったのと、将来的な拡張性やメンテナンス性を考慮してサーバーレスのサービスであるLambdaを選択しています。

注意

microCMSを通じて公開するサイトのレンダリング形式がSSGの場合は、コンテンツのビルドが完了した後にMessaging APIへリクエストする必要があります。
公開のタイミングでMessaging APIにリクエストをしてしまうと、サイトにコンテンツが生成されていない状態でLINEに通知が送信されてしまいます。
レンダリング形式がSSGの場合は、Vercel WebhookGitHub 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のコンソールで取得できますので、控えておきましょう。
LINE Developersのスクリーンショット。チャネルアクセストークンの箇所を強調している

実装方法

準備が整ったら、実際にmicroCMSのコンテンツをLINEに送信する仕組みを実装します。

Lambda関数の作成

今回はマネジメントコンソールでLambda関数を作成します。
AWS Lambdaの「関数の作成」画面 にアクセスします。
AWSマネジメントコンソールのスクリーンショット。Lambda関数を作成している。一から作成を選択。関数名にsend-line-messageを入力。ランタイムはNode.js 20.xを選択。アーキテクチャはx86_64を選択。
以下の手順で関数を作成します。

  1. 一から作成を選択
  2. 関数名にsend-line-messageを入力
  3. ランタイムはNode.js 20.xを選択
  4. アーキテクチャはx86_64を選択

次に詳細情報を設定します。
AWSマネジメントコンソールのスクリーンショット。Lambda関数を作成している。関数URLを有効化にチェックを入れる。認証タイプはNONEを選択している。

  1. 「関数URLを有効化」にチェックを入れる
  2. 認証タイプは「NONE」を選択
  3. その他の設定はデフォルトのまま[関数の作成]ボタンをクリック

認証タイプに関する注意点

認証タイプをNONEに設定する場合、Lambda関数のエンドポイントは認証なしでアクセスできてしまいます。今回はmicroCMSからのリクエスト時のみ処理を実行するように関数を実装するため、NONEに設定しています。

環境変数の設定

関数が作成できたら環境変数を設定します。
LINEのチャネルアクセストークンとmicroCMSからのリクエストを検証するために利用するシークレット値を設定します。
設定 > 環境変数 > 編集へと移動します。
Lambda関数の環境変数を設定している。設定 > 環境変数 > 編集へと移動する。
LINEのチャネルアクセストークン:キーにはLINE_CHANEL_ACCESS_TOKEN、値に控えていたチャネルアクセストークンを設定します。
シークレット値:キーにはMICROCMS_SECRET、値には極力推測されづらい値を設定してください。シークレット値は後にWebhookの設定でも利用します。
2つを設定したら[保存]ボタンをクリックします。
2つの環境変数を設定している。1つ目はLINEのチャネルアクセストークンでキーにはLINE_CHANEL_ACCESS_TOKEN、値に控えていたチャネルアクセストークンを設定します。2つ目にはシークレット値を登録していてキーにはMICROCMS_SECRET、値には極力推測されづらい値を設定している。

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}`,
            },
          ],
        },
      },
    ],
  }

左側にはLINEチャット上でのメッセージ表示があり、テキストメッセージとボタンテンプレートメッセージが表示されている。右側にはメッセージオブジェクトのコードが示されており、矢印で指定された要素(テキスト、サムネイル画像、タイトル、説明文、リンク)がどこに表示されているかがLINEチャット上の該当部分に対応して説明されている。
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を控えておきます。
AWSのマネジメントコンソール内のスクリーンショット。Lambdaの関数URLが表示されている箇所を強調している。

Lambda関数のURLをmicroCMSのWebhookに設定

Lambdaの実装を終えたら、microCMSのWebhookに設定します。
API > API設定 > Webhook > 追加 > カスタム通知の順で選択します。
microCMSの管理画面のスクリーンショット。Webhookを設定するための手順について説明している。1.API 2.API設定 3.Webhook 4.追加 5.カスタム通知の順で選択
Webhookを通知するURLには控えていたLambdaの関数URLを入力します。
シークレットにはLambdaの環境変数に登録したMICROCMS_SECRETと同じ値を入力します。
また、通知タイミングの設定はコンテンツの公開に関する操作のみチェックをいれます。
microCMSの管理画面のスクリーンショット。Webhookを通知するURLにはLambdaの関数URLを入力。シークレットにはLambdaの環境変数に登録したMICROCMS_SECRETと同じ値を入力。通知タイミングの設定はコンテンツの公開に関する操作のみチェックをいれる。
ここまで設定するとコンテンツ公開時に公式LINEからユーザーに向けてメッセージが送信されるようになります。

最後に

今回はmicroCMSで投稿したコンテンツをLINEにも自動で投稿する仕組みを構築しました。
microCMSのWebhookを利用すればLINEだけでなくXやSlackなどのサービスにも自動でコンテンツを投稿できます。
ぜひさまざまなユースケースに応用してみてください。

まずは、無料で試してみましょう。

APIベースの日本製ヘッドレスCMS「microCMS」を使えば、 ものの数分でAPIの作成ができます。

microCMSを無料で始める

microCMSについてお問い合わせ

初期費用無料・14日間の無料トライアル付き。ご不明な点はお気軽にお問い合わせください。

お問い合わせ

microCMS公式アカウント

microCMSは各公式アカウントで最新情報をお届けしています。
フォローよろしくお願いします。

  • X
  • Discord
  • github

ABOUT ME

高宮 竜太
元小学校教員。Web制作会社のフロントエンドエンジニアを経て現在はmicroCMSのカスタマーエンジニアをしています。趣味はバス釣り🎣