GatsbyJS + Netlify で予約投稿っぽいことをする

GatsbyJS + Netlify で予約投稿**っぽい**ことをする。
決められた時間にきっちり投稿させるのは難しいので、毎時単位で実現させた。
マークダウンで投稿した記事が対象です。

概要は以下👇

## TL;DR
1. [gatsby-plugin-draft](https://www.gatsbyjs.org/packages/gatsby-plugin-draft/) を使い frontmatter の `date`と現在時刻を比較して、現在時刻より前の記事だけビルドさせる
2. Netlify の Build hooks(Webhook) を発行
3. IFTTT で毎時 Build hooks を叩いてビルドを走らせる


## gatsby-plugin-draft
[gatsby-plugin-draft](https://www.gatsbyjs.org/packages/gatsby-plugin-draft/) というありがたいプラグインで frontmatter の時刻と現在時刻を比較してビルドを制御できます。

npmかyarnでパッケージをインストールして、 `gatsby-config.js` と `gatsby-node.js` に設定を追記。


```gatsby-config.js
    {
      resolve: 'gatsby-plugin-draft',
      options: {
        timezone: 'Asia/Tokyo',
      },
    },
```


```gatsby-node.js
  return graphql(`
    {
      allMarkdownRemark(
        limit: 1000
        filter: { fields: { draft: { eq: false } } }
      ) {
# ~以下略~
```


あとは マークダウンの `date` に日時を書くだけ。

```post.md
---
id: 2
title: Second Post
date: 2019-12-31T12:00:00+09:00
---
 
Draft content.
```

ポイントとしては、 `+09:00` を書いて日本時間のタイムゾーンに指定すること。
ビルドした際の時間は UTC±00:00で見てしまうらしい。
<del>これはNetlify CMSでは指定できないので、Netlify CMSで時間まで設定したい場合は マイナス9時間を計算して設定する必要がある。</del>
Netlify CMSは `Build & deploy` > `Environment variables` の設定で環境変数を設定すればmdの書き込みを自動で-9時間してくれました。 
<img width="1224" alt="スクリーンショット 2019-09-06 17.01.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/dd650fcc-0759-3b20-0d1a-bfd31f4bb9d7.png">
Key: TZ
Value: Asia/Tokyo
と設定。

ちなみに `date: 2019-12-31`みたいに時間なしでも指定できる。
この場合はタイムゾーンの関係で日本では朝9時にビルド→公開されることになる。


Gatsbyの設定はできたので、後はNetlifyのビルドを毎時で回して、予約投稿っぽいことを実現する。


## Netlify Build hooks
NetlifyでBuild hooksを発行する。

サイト管理画面から、
Settings > Build & deploy > Continuous Deployment に行き、
Build hooks の `Add build hook` を選択。

名前とブランチを設定。
<img width="1047" alt="スクリーンショット 2019-09-06 13.14.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/194bb43c-336d-02cd-40d0-b9a1db7d40ab.png">

`https://api.netlify.com/build_hooks/********` という Webhook のURLが発行される。


## IFTTT
発行したURLをIFTTTで毎時叩く。
リニューアルして新規レシピ作成が全然どこかわからなくなって迷ったが、右上のアイコンから `create` を選択。

### This
Thisは`date & time`、トリガーは`Every hour at`を選択。
<img width="902" alt="スクリーンショット 2019-09-06 13.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/4f12762e-90e3-7e50-1a94-4cb8bec2412c.png">

`Minutes past the hour`で何分にビルドするか設定する。
「:00, :15, :30, :45」から選べるがひとまず「00」に。
これで毎時00分にThenを実行する。

### Then

Thenは`Webhooks`、トリガーは`Receive a web request`を選択。
`
<img width="786" alt="スクリーンショット 2019-09-06 13.11.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/ef5930fe-0b5d-83fe-30b3-f157a38e65f5.png">

URLに Netlify で発行したURLをコピペ。
Methodは `POST`、Content Typeは `application/x-www-form-urlencoded` を選択。

<img width="1148" alt="スクリーンショット_2019-09-06_13_17_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/05858bf6-b2f2-016b-b2af-e32294cc4818.png">


あとは`Create action`ボタンを押して、レシピ名前を決めて`Finish`。

## 完成

Netlify管理画面の `Deploys` で確認すると毎時ビルドされているのが分かる。
ビルドの時間があるので、指定した日時からプラス数分で公開されるはず。

<img width="1219" alt="スクリーンショット 10.14.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/4b9f0218-0207-d1ab-1f0f-5949925811a2.png">

今回はIFTTTを使ったが、CIやZapierでもできる。
ただしZapierは無料プランでは100タスク/月なので、毎時ビルドにはStarterプラン以上が必要になる。