経緯
EPGStationには録画追加時や開始時、エンコード終了時に指定のコマンドを実行する機能がありますが、エンコード開始時だけは唯一実行できない仕様になっています(2024/10/19時点、見落としていたらすみません)。
標準で実行できるトリガーは以下の通りで、私はDiscordのWebhook経由で通知を送るようにしています。
- 予約新規追加時
- 予約更新時
- 予約削除時
- 録画準備開始時
- 録画準備失敗時
- 録画開始時
- 録画終了時
- 録画失敗時
- エンコード終了時
詳しくは公式リポジトリの外部コマンド実行の欄をご覧ください。
https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md
エンコードは予約時に指定していれば録画終了直後に開始されるわけですが、ここだけ通知がないのもなーと思い実装することにしました。
enc.jsに加筆
力技になってしまいますがお許しください。
やってることは単純で、enc.jsの頭の方にDiscordへ通知するよう書き加えるだけです。
enc.jsは、実行される際にepgstationから環境変数として番組情報を受け取っています。
まずはそれを受け取っていきます。
(unixTimeをNumber型に変換しないとDate型を生成できず苦戦しました。)
// この短さで UnixTimeをYYYY/MM/DD hh:mm:ssに すごい
// "2-digit" で0埋めまでしてくれる すごい
const unixTimeToDateTime = (unixTime) =>
new Date(unixTime).toLocaleString('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
});
// ミリ秒か秒のUnixタイムを判定し、差分を分に変換
const getDurationInMinutes = (start, end) =>
Math.floor(((end - start) / 1000) / 60);
const title = process.env.NAME; // 番組タイトル
const channel = process.env.CHANNELNAME; // 放送局名
// 環境変数の受け取り
const startAt = process.env.START_AT
const endAt = process.env.END_AT
const startTime = unixTimeToDateTime(Number(startAt)); // 録画開始時刻
const endTime = unixTimeToDateTime(Number(endAt)); // 録画終了時刻
const durationMinutes = getDurationInMinutes(startAt, endAt); // 録画時間(分)
これで番組タイトル、放送局名や録画時間等が取得できます。他にもいろいろな情報を受け取れますが詳しくは公式リポジトリを。
あとはEmbedに加工して送信しましょう。ベースのコードはこちらからお借りしました。
const WEBHOOK_URL = `https://discord.com/api/webhooks/xxxxxxx`;
// POSTするデータの作成
const postData = {
username: '予約通知',
embeds: [
{
title: '🔄 エンコード開始',
description: `**${title}**\n${channel}\n${startTime} ~ ${endTime} (${durationMinutes}分)`,
color: 5814783,
},
],
};
const post = async () => {
try {
const response = await fetch(WEBHOOK_URL, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
});
if (!response.ok) {
throw new Error(`HTTPエラー: ${response.status}`);
}
console.log('通知が正常に送信されました');
} catch (error) {
console.error('通知の送信に失敗しました:', error);
}
};
post();
正常に動作すれば、画像のように通知が来るはずです。お読みいただきありがとうございました。
(予約追加のコマンドが実行されているのに、通知が70%位の確率で送られてこないのはおま環でしょうか?
それ以外の通知は正常なのですが...)
参考