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ユーザIDをGoogleスプレッドシートへ自動書き込みする方法【Node.js / GCP】

0
Last updated at Posted at 2026-02-27

ひょんなことからあるコミュニティの業務自動化をお願いされたので、備忘録として記載します。
まずは自動通知機能を作りたい。…が、DiscordBotでのメンション機能をつけるにはDiscord上で一意となるユーザIDなるものが必要とな。
※人が手でメンションする分には「@+ニックネーム」でOKなんですが、Botで自動通知するには不正防止のためにユーザIDをメンションしないとメンションとして飛ばないそうです。

ということで開発手前段階のDiscordユーザIDを全取得する機能を作りました。
やることぜーんぶちゃっぴーに教えてもらったので、記事もほとんどチャッピーに書いてもらいました。ありがとうチャッピー。

やったこと

  • Discord Bot 作成
  • GCP側の準備
  • ソース作成
  • Cloud Run にデプロイ

最終的に、

👉 Cloud RunのURLにアクセスすると
👉 Discordメンバー一覧がスプレッドシートに自動反映

するところまで完成させます。


全体構成

Discord API
     ↑
Cloud Run (Node.js + discord.js)
     ↓
Google Sheets API
     ↓
Googleスプレッドシート

① Discord Botを作成

1. Developer Portalへアクセス

2. New Application

任意の名前を入力

3. Botを作成

  • 左メニュー「Bot」
  • 「Add Bot」

4. Members Intent をON

Bot設定画面で:

  • ✅ Server Members Intent を有効化

これをONにしないとメンバー一覧は取得できません。


5. Botトークンを取得

「Reset Token」→ Copy

⚠ このトークンは後でCloud Runの環境変数に設定します。


6. Botをサーバーに招待

OAuth2 → URL Generator

  • scopes → bot
    image.png

  • Bot Permissions → View Channels(私はテスト環境でいろいろやりたかったので管理者権限にしました)
    image.png

生成されたURLでサーバーに招待
image.png


7. サーバーIDを取得

  • Discord設定 → 詳細設定 → 開発者モードON
    image.png

  • サーバー右クリック → 「サーバーIDをコピー」
    ⚠ このIDは後でCloud Runの環境変数に設定します。
    image.png


② GCP側の準備

1. プロジェクト作成

Google Cloud Consoleで新規プロジェクト作成


2. Cloud Runを有効化

APIとサービス → ライブラリ → Cloud Run API 有効化


3. Google Sheets API有効化

APIとサービス → ライブラリ → Google Sheets API 有効化


③ スプレッドシート準備

新規スプレッドシートを作成

1行目にヘッダーを入れる:

A列 B列
DiscordユーザID ユーザ名

スプレッドシートURLの:

/d/【ここ】/edit

の部分が SPREADSHEET_ID になります。
⚠ このIDは後でCloud Runの環境変数に設定します。


④ Cloud Runのサービスアカウント設定

1. Cloud Runのサービスアカウント確認

Cloud Run → サービス → セキュリティタブ

例:

123456789-compute@developer.gserviceaccount.com

※セキュリティタブにいない場合はIAM → サービスアカウント で上のようなアカウントを見つけられたらOKです。


2. IAMで権限付与

IAM → 上記サービスアカウントに

編集者

ロールを付与


3. スプレッドシートに共有

スプレッドシート → 共有

サービスアカウントメールを追加
権限:編集者


⑤ ローカル環境準備(Node.js)

1. フォルダ作成

mkdir discord-member-export
cd discord-member-export

2. 初期化

npm init -y

3. 必要パッケージ

npm install express discord.js googleapis

⑥ ソースコード

index.js

// ===== 必要ライブラリ読み込み =====
const express = require('express');
const { Client, GatewayIntentBits } = require('discord.js');
const { google } = require('googleapis');

// ===== Expressサーバー設定(Cloud Run用)=====
const app = express();
const PORT = process.env.PORT || 8080;

// ===== HTTP GET "/" にアクセスされたときの処理 =====
app.get('/', async (req, res) => {

  // ===== Discordクライアント生成(メンバー取得Intent必須)=====
  const client = new Client({
    intents: [
      GatewayIntentBits.Guilds,
      GatewayIntentBits.GuildMembers
    ]
  });

  try {
    // ===== Discord Botログイン =====
    await client.login(process.env.BOT_TOKEN);

    // ===== 指定サーバー取得 =====
    const guild = await client.guilds.fetch(process.env.GUILD_ID);

    // ===== サーバー内メンバー全件取得 =====
    const members = await guild.members.fetch();

    // ===== シートに書き込むデータ作成 =====
    // A列:DiscordメンバーID
    // B列:globalName(なければusername)
    const values = members.map(member => ([
      member.user.id,
      member.user.globalName ?? member.user.username
    ]));

    await client.destroy();

    // ===== Google Sheets API 認証 =====
    const auth = new google.auth.GoogleAuth({
      scopes: ['https://www.googleapis.com/auth/spreadsheets']
    });

    const sheets = google.sheets({ version: 'v4', auth });

    // ===== 既存データ削除(A2:B)=====
    await sheets.spreadsheets.values.clear({
      spreadsheetId: process.env.SPREADSHEET_ID,
      range: 'Sheet1!A2:B'
    });

    // ===== データ書き込み(A2から)=====
    await sheets.spreadsheets.values.update({
      spreadsheetId: process.env.SPREADSHEET_ID,
      range: 'Sheet1!A2',
      valueInputOption: 'RAW',
      requestBody: {
        values: values
      }
    });

    res.send("スプレッドシート更新完了");

  } catch (error) {
    console.error(error);
    res.status(500).send("Error");
  }
});

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

package.json

{
  "name": "discord-member-fetch",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "discord.js": "^14.0.0",
    "express": "^4.18.2",
    "googleapis": "^171.4.0"
  }
}

⑦ Dockerfile

FROM node:20

WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

ENV PORT=8080

CMD ["node", "index.js"]

最終的に以下のフォルダ構成になっています。

discord-member-fetch/
│
├─ index.js
├─ package.json
├─ package-lock.json ※npm install時に勝手にできる
└─ Dockerfile

⑧ デプロイ

プロジェクトフォルダで:

gcloud run deploy discord-member-export \
  --source . \
  --region asia-northeast1 \
  --allow-unauthenticated

⑨ 環境変数設定(Cloud Run)

Cloud Run → 新しいリビジョンの編集とデプロイ → 変数とシークレット

追加:

名前
BOT_TOKEN Discordトークン
GUILD_ID サーバーID
SPREADSHEET_ID シートID

image.png

設定できたら「デプロイ」


⑩ 動作確認

Cloud RunのURLにアクセス

スプレッドシート更新完了

と表示され、

スプレッドシートに

  • DiscordメンバーID
  • ニックネーム

が書き込まれます。
image.png


私が詰まったエラー

TokenInvalid

→ BOT_TOKEN未設定

Unable to parse range

→ シート名が一致していない(例:Sheet1とシート1)

JSON is undefined

→ 環境変数未設定


まとめ

情弱エンジニア1人でやったら何日もかかる機能が1日でできちゃうGCPとChatGPTすごい。

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?