ADVENT CALENDAR 2019
ツイートで自動更新する静的サイトを作った話
By negset
これは AmusementCreators 2019 アドベントカレンダー その 1 の 21 日目の記事です。 その 2 もあります。
以前、以下のようなサイトを作成しました。
どっとライブの配信スケジュールを表示する非公式のウェブサイトを作りました。
— hakooshi.LIVE (@hakooshiLIVE) June 8, 2019
どっとライブファンの方は、良ければご活用ください。#どっとライブ #VR_Siro #アイドル部https://t.co/vyIGLE4nfq
これは、とある VTuber プロダクションの配信スケジュールを表示するサイトです。
運営が毎日スケジュールをツイートするので、それを基に自動で更新しています。
この記事では、上記サイトの技術的な仕組みを解説します。
動作例
これが ↓
【どっとライブ】【アイドル部】
— .LIVE【どっとライブ】 (@dotLIVEyoutuber) November 30, 2019
【YouTube生放送スケジュール12月1日】
21:00~: #神楽すず
22:00~: #金剛いろは
23:00~: #メリーミルク
メンバーの動画、SNSのリンクはこちらから!https://t.co/t6a5SqZbqf#アイドル部 #どっとライブ
こうなって ↓
source = "http://twitter.com/dotLIVEyoutuber/status/1200731195937443840"
update = "2019-11-30T20:00:00"
date = "2019-12-01"
[[timeline]]
time = "21:00"
member = [ "神楽すず" ]
[[timeline]]
time = "22:00"
member = [ "金剛いろは" ]
[[timeline]]
time = "23:00"
member = [ "メリーミルク" ]
こうなる ↓
参考
以下の記事を参考にしました。
How to automate your Github Pages blog - for free - with IFTTT and Glitch
概要
おおまかに次のような流れでツイートがサイトに反映されます。
- IFTTT1 がツイートを監視し、新規ツイートがあれば Glitch2 に POST する。
- Node.js が受け取ったツイートをもとに toml を作成し、GitHub のリポジトリにコミットする。
- Netlify3 が GitHub リポジトリを監視し、更新があれば Hugo4 でビルドし、生成されたサイトをホスティングする。
ちなみに、ここで使用するサービスは全て無料で利用できるので、運用費は 0 円です。
各種詳細設定
Glitch
Glitch で Express を使ってプレーンテキストを受け取るアプリを作成します。
以下のような感じのコードになります。
const express = require('express');
const bodyParser = require('body-parser');
const toml = require('@iarna/toml');
const Octokit = require('@octokit/rest');
const app = express();
app.use(bodyParser.text());
app.post('/', (req, res) => {
if (req.query.token !== process.env.WEBHOOK_TOKEN) {
// invalid token
return res.sendStatus(400);
}
// "|||" を改行で置換する。
const body = req.body.replace(/\|\|\|/g, '\n');
// toml としてパースする。
const parsed = toml.parse(body);
//
// 必要に応じて toml の編集を行う。
//
const path = `data/${parsed.date}.toml`;
const content = Buffer.from(toml.stringify(parsed)).toString('base64');
const msg = parsed.date;
commitFile(path, content, msg).then(_ => {
return res.sendStatus(200);
}).catch(err => {
console.log(err);
return res.sendStatus(500);
});
});
ファイルをコミットする処理は別関数に実装しました。
async function commitFile(path, content, msg) {
const octokit = new Octokit({
auth: `token ${process.env.GH_TOKEN}`
});
const params = {
owner: process.env.GH_USER,
repo: process.env.GH_REPO,
path: path,
message: msg,
content: content
};
// ファイルが既に存在する場合は更新する。
await octokit.repos.getContents(params)
.then(result => {
params.sha = result.data.sha;
});
return octokit.repos.createOrUpdateFile(params)
}
また、GitHub と Webhook のトークンを .env ファイルに書いておきます。
(GitHub のトークンはあらかじめ取得しておき、Webhook のトークンは自分で 適当 に決めます。)
GH_USER=...
GH_REPO=...
GH_TOKEN=...
WEBHOOK_TOKEN=...
IFTTT
IFTTT で新規アプレットを作成します。
THIS に「Twitter: New tweet by a specific user.」を選択、
THAT に「Webhooks: Make a web request.」を選択します。
Webhook は以下のように設定しておきます。
- URL:
https://PROJECT-NAME.glitch.me/?token=WEBHOOK-TOKEN
- Method:
POST
- Content Type:
text/plain
- Body:
source = "{{LinkToTweet}}"|||update = "{{CreatedAt}}"|||text = '''{{Text}}'''
URL は作成した Glitch のプロジェクト名と Webhook トークンに応じて書き換えてください。
Body は toml 形式ですが、改行が使えないので代わりに |||
を使っています。これは Node.js 側で受け取った際に改行に置換します。
Hugo
Data Templates を使って、toml からいい感じの html を生成するコードを書きます。
Netlify
デプロイ時に自動で Hugo のビルドが走るように設定しておきます。
結び
かなり端折って書いたので分かりにくい点もあるかと思いますが、参考元の記事を読めば解決すると思います。
どっとライブはいいぞ 🌸🐈
SHARE THIS POST
Tweet