0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Discordコミュニティ内のワンドロイベント用のbot(webhook)を作った

Last updated at Posted at 2025-08-23

どういう記事?

Discord鯖内で、ワンドロ(1時間とか時間制限ありで、決められたお題で絵を描くやつ)がしたいという要望があり、良い感じに自動化出来ないかなぁという所で、Google Form → Spreadsheet → Apps Script → Webhook(Discord)という構成でbot(厳密にはbotではない)を作ったという記事。

この記事ではwebhookの設定やapps script自体の設定は書きませんので、その辺は各自調べて下さい。

この構成の利点は?

  • サーバーが要らないし、運用費もかからない
  • Apps scriptのトリガーを使えば定期的な投稿もできる
  • お題はコミュニティメンバーに投稿してもらう事で、お題を用意するタスクが分担できる

実際の処理の流れ

  1. ユーザーがGoogle Formに回答
  2. 回答がSpreadsheetに書き込まれる
  3. その回答を上から順に、Spreadsheetに紐づいたApps scriptがHTTPでDiscordのwebhookに投げる
  4. 一度送信したお題には、送信済みフラグを立てる

実装

コードはLLMが生成したのに必要に応じて手を加えたものです。
columnなどは各自のspreadsheetに合わせれば動くと思います。
コードとしては汚いですが、一応参考程度に置いておきます。
ここで想定しているspreadsheetのcolumnは以下です。

image.png

function sendToDiscordWebhook() {
  const WEBHOOK_URL = '{your discord webhook url}';

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  const lastRow = sheet.getLastRow();
  if (lastRow < 2) {
    console.log('データがありません。');
    return;
  }
  const range = sheet.getRange(2, 1, lastRow - 1, 3);
  const values = range.getValues();

  let targetRow = null;
  let targetValue = null;

  // 残数を数える(ブールtrue もしくは文字列"TRUE"を完了扱い)
  const isDone = v => v === true || (typeof v === 'string' && v.toUpperCase() === 'TRUE');
  const remainingCount = values.reduce((acc, row) => acc + (isDone(row[2]) ? 0 : 1), 0);

  for (let i = 0; i < values.length; i++) {
    const bVal = values[i][1];
    const cVal = values[i][2];
    if (!isDone(cVal)) {
      targetValue = bVal;
      targetRow = i + 2;
      break;
    }
  }

  if (targetValue === null) {
    console.log('条件に一致する行が見つかりませんでした。');
    return;
  }

  const embed = {
    title: "ワンドロ今回のお題",
    description: "10秒/1分/10分/1時間/100分の中で時間制限を選び、絵をかいてみましょう!",
    color: 0x3498db,
    fields: [
      {
        name: "📝 お題",
        value: `** 『${targetValue} **` || "(空)",
        inline: true
      },
    ],
    footer: {
      text: `お題残り:${remainingCount-1}`
    },
    timestamp: new Date().toISOString()
  };

  const payload = {
    username: "ワンドロお題Bot",
    embeds: [embed]
  };

  const options = {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(WEBHOOK_URL, options);
    if (response.getResponseCode() === 204) {
      sheet.getRange(targetRow, 3).setValue(true);
    } else {
      console.error('送信に失敗しました:', response.getResponseCode());
    }
  } catch (error) {
    console.error('エラーが発生しました:', error);
  }
}

その他

Discordのwebhookで、forum内のチャンネルに投稿したい場合は、webhook URLの発行時にそのフォーラムを指定し、URLにthread_idをパラメーターとして付けてやる必要があるようです(これで無事いけてます)。

参考:

あとがき

我ながら丁度いい解法じゃないかと思います。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?