14
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

gasでちょっとしたdiscord botを作成

Last updated at Posted at 2020-01-15

僕のハマっているゲーム(FPS)には練習モードがありまして、
そのモードをどうやら僕はたくさんやっているようで、
1日どれくらいやってるのか、友人とどれくらい差があるのか

を知りたくなりました。


なので、今回はゲームのマッチング待ち時間を利用してdiscordのbotを作成してみました。
gasで簡単にスケジュール実行ができると聞いたので、gasでやりました。

仕組み

https://r6tab.com/
↑はそのゲームの統計を見るサイトです(非公式)

そのAPIを利用して統計を取得しています。

  1. スプレッドシートからユーザー名を取得
  2. ユーザーのプレイヤーIDを取得、練習モードのキル数を取得
  3. スプレッドシートの値と比較して差分を計算
  4. 諸々をテキストにしてDiscordに投稿

といった流れをスケジュール実行しています。

実行結果

スクリーンショット 2020-01-15 15.12.24.png _自分のユーザー名以外は一応隠しています。_

ユーザー名と総キル数、昨日との差分を表示しています。

スプレッドシート

スクリーンショット 2020-01-15 14.55.08.png _自分のユーザー名以外は一応隠しています。_

A列にユーザー名
B列にキル数(初回登録時は0)
を設定する。

ソースコード

function main() {
  // チェックするユーザー, キル数を取得
  var sheet = SpreadsheetApp.getActiveSheet();
  var users = sheet.getRange('A:A').getValues();
  var count = users.filter(String).length;  // ユーザー数
  var beforeKills = sheet.getRange('B:B').getValues();

  var messages = [];

  for (var i = 0; i < count; i++) {
    var id = getPlayerId(users[i]);
    if (!id) {
      messages.push('このユーザー名は存在しません。');
      continue;
    }
    var currentKills = getThuntKills(id);

    // 差分計算
    var diff = Number(currentKills) - Number(beforeKills[i]);
    diff = Math.floor(diff);

    messages.push('総キル数: `' + currentKills + '`\n 前回との差分: `' + diff + '`');
    // スプレッドシートの更新
    sheet.getRange('B' + (i + 1)).setValue(currentKills);
  }

  // キル数でソート
  sort();

  var text = createText(count, users, messages);
  postDiscord(text);
}


/**
 * プレイヤーIDを取得する
 *
 * @param {String} username - ユーザー名
 * 
 * @returns String プレイヤーID
 */
function getPlayerId(username) {
  var url = 'https://r6.apitab.com/search/uplay/' + username;
  var response = UrlFetchApp.fetch(url);
  var content = JSON.parse(response.getContentText('UTF-8'));
  // 存在しないユーザーを確認
  if (content['foundmatch'] === false) { return false; }
  var p_id = Object.keys(content['players'])[0];

  return p_id;
}


/**
 * テロハントのキル数を取得する
 *
 * @param {String} id - プレイヤーID
 * 
 * @returns Number キル数
 */
function getThuntKills(id) {
  var url = 'https://r6.apitab.com/player/' + id;
  var response = UrlFetchApp.fetch(url);
  var content = JSON.parse(response.getContentText('UTF-8'));
  var kills = content['stats']['generalpve_kills']

  return kills;
}


/**
 * 投稿するメッセージを作成する
 *
 * @param {Int} count - ユーザー数
 * @param {Array} users - ユーザー
 * @param {Array} messages - メッセージ
 * 
 * @returns Object - 投稿するメッセージ
 */
function createText(count, users, messages) {
  var results = [];

  for (i = 0; i < count; i++) {
    results[i] = {
      'name': users[i][0],
      'value': messages[i],
      'inline': true
    };
  }

  var text = {
    "embeds": [
      {
        "color": 15105570, // orange
        "fields": results
      }
    ]
  };

  return text;
}


/**
 * Discordに投稿する
 *
 * @param {Object} text - 投稿するメッセージ
 */
function postDiscord(text) {
  var url = 'https://discordapp.com/api/webhooks/000000000000/xxxxxxxxxxxxxxxxxx';

  var params = {
    'method': 'POST',
    'headers': { 'Content-type': 'application/json' },
    'payload': JSON.stringify(text)
  };

  UrlFetchApp.fetch(url, params);
}


/**
 * キル数でソートをする
 */
function sort() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var range = sheet.getRange("A:B");
  range.sort([{ column: 2, ascending: false }]);
}

実行トリガー

スクリーンショット 2020-01-15 16.14.41.png

選ぶだけですが朝9時くらいに投稿される様にしました。

感想

  • 簡単にbot?をつくることができた。
  • 確かに友人より多くやっていることがわかった。
  • このモードを多くやってるからといって強くなるわけではないことがわかった。

未来の自分へ

  • 他鯖でも使用できるように、シートの追加の対応
  • セキュリティ的にwebhook urlを隠す
  • ソートのタイミングが1日遅いのを修正

をやってください。

リンク

rainbow six siege
使用したAPI
discord webhook document

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?