🐷

Payloadのフック機能について簡易的な承認ワークフローを実装して理解する

に公開

はじめに

Payloadにはフックという機能があります。これは特定のイベントが発生した際にカスタム処理を実行することができる機能で、たとえば下記のようなイベント発生時に実行できます。

  • コンテンツの閲覧前
  • コンテンツの変更前
  • コンテンツの変更後
  • コンテンツの削除前
  • コンテンツの削除後
  • etc...

この記事では、Payloadのフック機能について理解するために、簡易的な承認ワークフローを実装してみたいと思います。Payloadの承認ワークフローは、有償のエンタープライズ版でのみ提供されており、無償のOSS版にはないようです。コンテンツに承認待ちチェックボックスを設けることで、簡易的な承認ワークフローを実装してみようと思います。

前提

下書き・バージョン管理機能が有効化されているコレクションに、簡易的な承認ワークフローを実装する前提で解説します。下書き・バージョン管理機能の設定については、下記の記事をご参照ください。

https://zenn.dev/ksk1kd/articles/0634148d336e22

簡易的な承認ワークフローの機能

まずは、簡易的な承認ワークフローの機能について考えます。Payloadのコンテンツは標準で、下書き状態と公開状態を持つことができます。これらに承認待ち状態を追加する方針としたいです。また、承認待ち状態は、コンテンツに承認待ちチェックボックスを設けることで表現したいと思います。整理するとコンテンツのライフサイクルは下記のフローになります。

下書き

承認待ち(下書きのコンテンツのうち承認待ちチェックボックスがONになっているもの)

公開

さらに、コンテンツが公開されたタイミングで承認待ちチェックボックスを自動的にOFFにするよう実装したいと思います。この機能の実装にPayloadのフック機能を使用します。

コレクションに承認待ちチェックボックスを追加

はじめに、コレクションに承認待ちチェックボックスを追加します。下記が承認待ちチェックボックスの設定です。任意のコレクションのfieldsキー配下の配列に追加します。

src/collections/[Collection Name]/index.ts
  // ...
  fields: [
    // ...
    {
      name: 'isAwaitingApproval',
      label: {
        en: 'Awaiting Approval',
        ja: '承認待ち',
      },
      type: 'checkbox',
      admin: {
        position: 'sidebar',
      },
    },
    // ...

上記の設定により、下記キャプチャのようにコンテンツ編集画面に承認待ち(Awaiting Approval)チェックボックスが表示されます。

コンテンツ編集画面の承認待ちチェックボックス

コレクション設定にフック処理を追加

次に、コレクション設定にフック処理を追加します。フック処理はファイルを分割し、コレクション設定からフック処理をインポートする形にしたいと思います。

フック処理は、src/collections/[Collection Name]/hooks/resetAwaitingApprovalFlag.tsを作成し、その中に記述します。

src/collections/[Collection Name]/hooks/resetAwaitingApprovalFlag.ts
import type { CollectionBeforeChangeHook } from 'payload'

import type { News } from '../../../payload-types'

export const resetAwaitingApprovalFlag: CollectionBeforeChangeHook<News> = async ({ data }) => {
  if (data._status === 'published' && data.isAwaitingApproval === true) {
    data.isAwaitingApproval = false
  }

  return data
}

更新される対象のコンテンツのステータスがpublishedかつ、承認待ちチェックボックスがtrueの場合に、承認待ちチェックボックスをoffに変更するよう実装しています。

コレクション設定から上記のフック処理をインポートします。

src/collections/[Collection Name]/index.ts
import { resetAwaitingApprovalFlag } from './hooks/resetAwaitingApprovalFlag'

  // ...
  hooks: {
    beforeChange: [resetAwaitingApprovalFlag],
  },
  // ...

コンテンツの更新前のタイミングで処理を行いたいため、beforeChangeのフック処理に追加しています。

動作確認

以上の設定・実装によりどのような挙動になるのか動作確認をします。

まずは、コンテンツを下書きで作成し、承認待ちチェックボックスをONにしておきます。

承認待ちチェックボックがONの状態

次に、承認待ちチェックボックスをONにしたまま、コンテンツ編集画面右上の「Publish changes」ボタンでコンテンツを公開します。すると、承認待ちチェックボックスが自動的にOFFになりました。

承認待ちチェックボックスがOFFの状態

以上で、フックが機能し簡易的な承認ワークフローを実装できていることを確認できました。

まとめ

この記事では、Payloadのフック機能について理解するために、簡易的な承認ワークフローを実装してみました。フック機能を使用すれば、他システムとの連携や通知メールの送信など様々な要件に対応できそうだと感じました。

参考

https://payloadcms.com/docs/hooks/collections

Discussion