9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

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

僕のハマっているゲーム(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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?