esmieの技術倉庫

RTA / 配信 / ゲーム関連のつくったもの置き場

PCゲームのプレイ記録を出力するDiscord Botの導入#3 出力ログのカスタマイズ

この記事は、私が作ったDiscord Bot 「Gaming Logger」の導入方法を解説する記事(第3回)です。

今回は、BotがDiscordチャンネルやスプレッドシートに出力するプレイ記録のカスタマイズ方法を紹介します。

Botの導入方法については、このシリーズの第1回と第2回をご確認ください:

第1回:PCゲームのプレイ記録を出力するDiscord Botの導入#1 GlitchでBotを動かす
第2回:PCゲームのプレイ記録を出力するDiscord Botの導入#2 GlitchとGASの連携

ー Contents ー

まずはじめに

作業はすべてGlitch上で行います。
GlitchでDiscord Botのプロジェクト選択、左側のファイル一覧からmain.jsをクリックして開いておきましょう。

Discordに出力されるメッセージを変更する

デフォルトの表示形式はこんな感じ

f:id:esmie:20201217135148p:plain

これをカスタマイズしていきます。

ざっくり全体的な説明

Glitch上のファイルmain.jsの52~56行目あたりに以下の記述があります。

// プレイログをDiscordに出力
if (playtime.hours() == 0) {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`${activity.name}を${playtime.minutes()}分プレイしました`);
} else {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`${activity.name}を${playtime.hours()}時間${playtime.minutes()}分プレイしました`);
}

これを日本語化すると、

  • プレイ時間が1時間未満のとき、指定したチャンネルに「{ゲーム名}を{ }分プレイしました」というメッセージを送信
  • プレイ時間が1時間以上のとき、指定したチャンネルに「{ゲーム名}を{ }時間{ }分プレイしました」というメッセージを送信

という内容になります。

変数playtimeにはゲームをプレイした時間が格納されていて、

  • playtime.hours()でプレイ時間の「○時間」を表す数字
  • playtime.minutes()でプレイ時間の「○分」を表す数字

を取得することができます。また、プレイしたゲームのタイトルはactivity.name()で取得できます。

出力するメッセージの内容は、clientから始まる行のsend()の中で定義しています。 

client.~~~.send(`${activity.name}を${playtime.hours()}時間${playtime.minutes()}分プレイしました`);

このsend()の中身は、以下のルールを守って書く必要があります。

  1. 文章全体を ` `(バッククオーテーション)で囲む
  2. 変数を書くときは${ }で囲む

例えば、出力するメッセージにゲーム名を入れたい場合は変数activity.name${ }で囲んで${activity.name}と書きます。

[case1] プレイ時間の秒まで出力する

プレイ時間の秒数はplaytime.seconds()で取得できます。
該当部分を以下のコードに置き換えると、文章はそのままで秒数を追加できます:

if (playtime.hours() == 0) {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`${activity.name}を${playtime.minutes()}分${playtime.seconds()}秒プレイしました`);
} else {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`${activity.name}を${playtime.hours()}時間${playtime.minutes()}分${playtime.seconds()}秒プレイしました`);
}

// 出力例
// Blastboardを1時間8分25秒プレイしました 

[case2] 出力メッセージを英語にする

変数${ }の中身はそのままで文章を変更すればOKです。
一例:

if (playtime.hours() == 0) {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`You played ${activity.name} for ${playtime.minutes()}min.`);
} else {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`You played ${activity.name} for ${playtime.hours()}h ${playtime.minutes()}min.`);
}

// 出力例
// You played Blastboard for 1h 8min. 

[case3] プレイ時間を hh:mm:ss 形式で出力する

ここで言う hh:mm:ss 形式は、1時間8分25秒を 1:08:25 のように表現することを指します。

この場合、playtime.minutes()をそのまま使うと分数が1桁のときに 1:8:25 となって不格好なので、十の位を0で埋めた変数minuteを使って記述します。
また、同様の理由から秒数もplaytime.seconds()の代わりにsecondを使います。

if (playtime.hours() == 0) {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`You played ${activity.name} for ${minute}:${second}.`);
} else {
  client.channels.cache.get(process.env.CHANNEL_ID).send(`You played ${activity.name} for ${playtime.hours()}:${minute}:${second}.`);
}

// 出力例
// You played Blastboard for 1:08:25. 

時間が0のときも 0:45:03 のように出力したい場合は、if else文を削除して、

client.channels.cache.get(process.env.CHANNEL_ID).send(`You played ${activity.name} for ${playtime.hours()}:${minute}:${second}.`);

// 出力例
// You played Blastboard for 0:45:03. 

このように1行で記述できます。

[case4] プレイ開始日時と終了日時も出力する

プレイ開始日時は変数startDate、プレイ終了日時は変数endDateでそれぞれ定義しています(main.jsの47~48行目あたり)。

let startDate = moment(start).format("YYYY/MM/DD HH:mm:ss");
let endDate = moment(end).format("YYYY/MM/DD HH:mm:ss");

出力形式はformat()の中で設定しており、YYYYは西暦4桁、MMは月2桁を表しています。その他使えそうな表現をこの記事の最後にまとめてあるので、気になる方はおまけを確認してください。

カスタマイズの一例を紹介します。例えば、47~48行目を以下のように書き換えて、

let startDate = moment(start).format("YYYY-MM-DD ddd.  HH:mm:ss");
let endDate = moment(end).format("YYYY-MM-DD ddd. HH:mm:ss");

52~56行目を

client.channels.cache.get(process.env.CHANNEL_ID).send(`タイトル  : ${activity.name}\nプレイ時間 : ${playtime.hours()}:${minute}:${second}\n開始時刻  : ${startDate}\n終了時刻  : ${endDate}`);

のように変更すると、Discordの送信されるメッセージは以下のようになります。
ここで、send()の中に登場する\n改行を表す文字列です。

タイトル  : Blastboard
プレイ時間 : 1:08:25
開始時刻  : 2020-12-17(Thu) 12:00:00 
終了時刻  : 2020-12-17(Thu) 13:08:25  

スプレッドシートの出力ログを変更する

デフォルトのスプレッドシート出力はこんな感じ

f:id:esmie:20201217135150p:plain

ざっくり全体的な説明

書き換えるのは、main.jsの62行目あたりにある以下の記述です。

// spreadsheet URLにパラメータを付加
url = `${url}?game=${activity.name}&playtime=${hour}:${minute}:${second}&start=${startDate}&end=${endDate}`;

ここの=以下の部分を変更することで、スプレッドシートに書き込まれる形式を変更することができます。

プログラミングにある程度触れたことがある方向けに簡単に説明すると、前回記事にてGASで作成したアプリケーションのURLにパラメータを付加して送信 ⇒ 受け取ったアプリケーション内で各パラメータを処理してスプレッドシートに出力、ということをやっています。
(もし上の文章が何言ってるか分からなくても、カスタマイズはできるので無問題)

デフォルトでスプレッドシートに書き込める値(パラメータ)は全部で4つです。

  • game
  • playtime
  • start
  • end

[case5] 時間表記 / 日付表記を変更する

上で説明した、Discordチャンネルへの送信メッセージのカスタマイズとほぼ同じです。

プレイ時間の表記を変更したい場合はplaytime=以降の部分を変更します。例えば、

playtime=${hour}:${minute}:${second}

playtime=${hour}時間${playtime.minutes()}

とすると、スプレッドシート2列目には「1時間8分」のように出力されます。

また、プレイ開始日時や終了日時の表記を変更したい場合はmain.jsの47~48行目あたりの変数startDateendDateの記述を書き換えます。

let startDate = moment(start).format("YYYY/MM/DD HH:mm:ss");
let endDate = moment(end).format("YYYY/MM/DD HH:mm:ss");

format()内の書き方については、記事末尾のおまけを確認してください。

もし、「Discordへの送信メッセージにプレイ開始日時と終了日時を出力するように変更した」かつ「スプレッドシートには違う形式で開始日時と終了日時を出力したい」という方がいたら、その場合は以下のようにmain.js47~48行目をその下にコピペして複製し、変数名を(startDate2などに)書き換えて使って下さい。

// 47~48行目あたりの2行を複製⇒変数名変更
let startDate2 = moment(start).format("YYYY/MM/DD HH:mm:ss");
let endDate2 = moment(end).format("YYYY/MM/DD HH:mm:ss");

// 62行目あたり
//(start=とend=の後の変数を上で変更した変数名に書き換え)
url = `${url}?game=${activity.name}&playtime=${hour}:${minute}:${second}&start=${startDate2}&end=${endDate2}`;

[case6] スプレッドシートに書き込むパラメータを減らす

main.js62行目あたりのコードから、出力したくないパラメータを削除すればOKです。

例えば、プレイ開始日時と終了日時をスプレッドシートに出力したくない場合は、以下のように書き換えます:

url = `${url}?game=${activity.name}&playtime=${hour}:${minute}:${second}`;

[case7] スプレッドシートに書き込むパラメータを増やす

GASで作ったアプリケーションの中身とGlitch上のmain.jsの両方に変更を加える必要があります。

以下では一例として、プレイ開始日時と終了日時の日付と時刻を別のパラメータとして(列を分けて)出力するようにコードを書き換えています。

GAS

  1. 前回記事にて作成したスプレッドシートを開いて、画面上部のツールバーからツール > スクリプトエディタを選択
  2. 下記のようにパラメータ名を追加({}はいらない)
const doGet = (e) => {   
  const game = e.parameter.game;
  const playtime = e.parameter.playtime;
  const start = e.parameter.start;
  const end = e.parameter.end;

  // ここに追加したいパラメータを定義
  // const {パラメータ名} = e.parameter.{パラメータ名};
  const start_time = e.parameter.start_time;
  const end_time = e.parameter.end_time;

  const sheet = SpreadsheetApp.getActiveSheet();

  // []の中に上で追加したパラメータを追加
  sheet.appendRow([game, playtime, start, start_time, end, end_time]);
}

Glitch: main.js

  1. 新しく定義したパラメータに入力する値を定義
  2. urlにパラメータを追加
let startDate = moment(start).format("YYYY/MM/DD");
let endDate = moment(end).format("YYYY/MM/DD");

// 1. 以下を追加
let startTime = moment(start).format("HH:mm:ss");
let endTime = moment(end).format("HH:mm:ss");

// ~~省略~~

// 2. URLに新しいパラメータを付加(順不同)
url = `${url}?game=${activity.name}&playtime=${hour}:${minute}:${second}&start=${startDate}&end=${endDate}&start_time=${startTime}&end_time=${endTime}`;

[case8] スプレッドシートに書き込む順番を変更する

デフォルトでは、

タイトル プレイ時間 開始日時 終了日時

の順でスプレッドシートに書き込まれます。これを

開始日時 終了日時 タイトル プレイ時間

のように変更したい場合、

とすればOKです。

const doGet = (e) => {   
  // ~~省略~~

  // []の中の並び順を変更
  sheet.appendRow([start, end, game, playtime]);
}

おまけ:Node.jsで使える日付形式

(英語と出力が同じになる場合の日本語欄は空欄としています)

表記 出力(locale="en") 出力(locale="ja")
YY 西暦下2桁
YYYY 西暦4桁
M 1, 2, ..., 11, 12
MM 01, 02, ..., 11, 12
MMM Jan, Feb, ..., Nov, Dec 1月, 2月, ..., 11月, 12月
MMMM January, ..., December 1月, 2月, ..., 11月, 12月
D 1, 2, ..., 30, 31
DD 01, 02, ..., 30, 31
Do 1st, 2nd, ..., 30th, 31st 1日, 2日, ..., 30日, 31日
曜日 ddd Sun, Mon, ..., Fri, Sat 日, 月, ..., 金, 土
dddd Sunday, ..., Saturday 日曜日, ..., 土曜日
H 0, 1, ..., 22, 23
(24時間表記)
HH 00, 01, ..., 22, 23
(24時間表記)
m 0, 1, ..., 58, 59
mm 00, 01, ..., 58, 59
s 0, 1, ..., 58, 59
ss 00, 01, ..., 58, 59

表の一番右の列のように日本語表記にしたい場合は、main.jsの10行目あたりに以下をコピペしてください:

moment.locale("ja");

元の英語表記に戻したい場合は、"ja""en"に変更すればOKです。

以下のサイトに一覧が載っているので、日付表現についてもっと詳しく知りたい方はそちらを確認してみてください: momentjs.com

シリーズ記事

第1回:PCゲームのプレイ記録を出力するDiscord Botの導入#1 GlitchでBotを動かす
第2回:PCゲームのプレイ記録を出力するDiscord Botの導入#2 GlitchとGASの連携
第3回:この記事