GridsomeとContentfulとCircleCIを組み合わせて予約投稿ができるようにする

公開日時

静的サイトジェネレーターのGridsome@gridsome/source-contentfulプラグインを使うことでコンテンツ取得元をContentfulにすることができる。

また、ContentfulにはWebhookが設定できるので、記事更新時に任意のURLに対してリクエストを飛ばすことができる。

このWebhookでCircleCI APIを呼び出すようにすれば記事更新時にサイトを再構築できる。

ただし、この状態だと未来の日付で投稿しても、そのまま公開されてしまうので予約投稿をすることができない。

そこで、Gridsomeの設定とCircleCIのSchedule Jobsを使って予約投稿ができるようにする。

  1. 記事が未来の日付の場合はサイト生成時に除外する
  2. 厳密な日時チェックはせず1日1回サイト構築を自動実行する

このようにすることで簡易の予約投稿ができるようになる。

記事が未来の日付の場合はサイト生成時に除外する

content filtering based on today's date and published date frontmatter (draft content)を参考に[[gridsome.server.js]]に日付チェック処理を入れる。

const moment = require("moment");

module.exports = function(api) {
  api.loadSource(({ addContentType, getContentType }) => {
    const posts = getContentType("ContentfulBlogPost");
    posts.data().forEach(node => {
      if (moment(node.publishDate) > moment()) {
        posts.removeNode(node.id);
      }
    });
  });
};

1日1回サイト構築を自動実行する

[[.circleci/config.yml]]のworkflowsにtriggersを設定。

workflows:
  version: 2
  build-deploy:  # 通常デプロイの設定
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master
  scheduled-deploy: # 定期デプロイの設定
    triggers:
      - schedule:
          cron: "0 1 * * *" # 10:00 JST
          filters:
            branches:
              only: master
    jobs:
      - build
      - deploy:
          requires:
            - build

これで予約投稿ができるようになった。

参考


Related #contentful

Contentfulで管理しているブログ記事を一括公開する

一括置換以外にも細かい調整を加えたかったため、更新と公開でスクリプトを分けることにした

Contentfulで管理しているブログ記事を一括更新する

Content Management APIを使う

Contentfulの記事をAlgoliaのインデックスに登録する

Contetful Webhookの変換Helperが便利

Contentful GraphQL APIで最終更新日時を取得する

sys.publishedAtで最終更新日時が取得できる

ContentfulのContent modelにvalidationを設定する

slugに正規表現のvalidationを設定した