この記事について
この記事では、Google Apps Script(GAS)初心者向けに、X(旧:Twitter, 以降Xと記載)への自動投稿と、実行結果をDiscordに自動通知する方法を記載します。
基本的な使い方から具体的なコード例、トリガー設定までカバーしています。
目次
概要
Google Apps Script(GAS)を使ってXに投稿し、その結果をDiscordへ自動通知する方法を紹介します。実際のユースケースとして、スプレッドシートのデータをもとにポストし、その投稿結果(成功・失敗)をDiscordのチャンネルにWebhookで通知します。
目的
- GASからXに投稿
- 実行結果(成功・失敗)をDiscordに自動通知
必要なもの
- Google スプレッドシート
※今回は以下の形式を使用します。ID タイトル 投稿文 投稿ステータス 1 サンプル投稿① これは自動投稿テストです①。 未投稿 2 サンプル投稿② これは自動投稿テストです②。 投稿済み 3 サンプル投稿③ これは自動投稿テストです③。 未投稿 - Google Apps Script エディタ
- Discord Webhook URL
- XのAPI認証情報
スクリプト構成
「スプレッドシートから投稿」→「投稿処理の中でX APIに通信」→「結果をDiscord通知」という構成になっています。
ステップ1. スプレッドシートの未投稿データをXに投稿する
関数:postX()
中で呼ばれる関数:postToX() → sendXRequest() → getOAuthHeader()
🧠 処理の流れ
- スプレッドシートから「未投稿」のデータを探す
- 見つけたテキストをpostToX()でX(旧Twitter)に投稿
- → この中で認証情報を元にAPIリクエストを送る関数が順に呼ばれます
- 投稿できたら「投稿済み」に更新
- 成否メッセージを返す(後でDiscord通知に使う)
コード(GAS)
function postX() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
var lastMonth = new Date();
lastMonth.setMonth(lastMonth.getMonth() - 1);
var data = sheet.getDataRange().getValues();
var itemToPost = null;
var rowIndex = -1;
for (var i = 1; i < data.length; i++) {
if (data[i][3] === "未投稿") {
itemToPost = {
title: data[i][1],
text: data[i][2],
};
rowIndex = i + 1;
break;
}
}
if (!itemToPost) {
return "投稿できる新しいコンテンツがありません";
}
var postResponse = postToX(itemToPost.text);
if (!postResponse || !postResponse.data || !postResponse.data.id) {
return "ポスト失敗: " + JSON.stringify(postResponse);
}
sheet.getRange(rowIndex, 4).setValue("投稿済み");
return "ポスト成功: " + itemToPost.title + "\n" + itemToPost.text;
}
function postToX(content) {
var url = "https://api.twitter.com/2/tweets";
var payload = { "text": content };
return sendXRequest(url, "POST", payload, "application/json");
}
/**
* APIへリクエストを送る関数
* @param {string} url - APIエンドポイントのURL
* @param {string} method - HTTPメソッド (POST/GET)
* @param {Object} payload - 送信するデータ (nullの場合は無し)
* @param {string} contentType - Content-Type (JSON, multipart/form-data など)
* @returns {Object} APIのレスポンス(JSON)
*/
function sendXRequest(url, method, payload, contentType) {
var options = {
"method": method,
"headers": {
"Authorization": getOAuthHeader(method, url),
"Content-Type": contentType
},
"muteHttpExceptions": true
};
if (payload) {
options.payload = (contentType === "application/json") ? JSON.stringify(payload) : payload;
}
var response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText());
}
/**
* OAuth1.0aの署名を作成し、OAuth認証ヘッダーを生成する関数
* @param {string} method - HTTPメソッド (POST/GET)
* @param {string} url - APIのURL
* @returns {string} OAuth認証ヘッダー
*/
function getOAuthHeader(method, url) {
var credentials = X_CREDENTIALS;
var timestamp = Math.floor(new Date().getTime() / 1000);
var nonce = Math.random().toString(36).substring(2, 15);
var parameterString = [
"oauth_consumer_key=" + credentials.consumerKey,
"oauth_nonce=" + nonce,
"oauth_signature_method=HMAC-SHA1",
"oauth_timestamp=" + timestamp,
"oauth_token=" + credentials.accessToken,
"oauth_version=1.0"
].sort().join("&");
var signatureBaseString = method + "&" + encodeURIComponent(url) + "&" + encodeURIComponent(parameterString);
var signingKey = encodeURIComponent(credentials.consumerSecret) + "&" + encodeURIComponent(credentials.accessTokenSecret);
var signatureBytes = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, signatureBaseString, signingKey);
var signature = Utilities.base64Encode(signatureBytes);
return 'OAuth ' +
'oauth_consumer_key="' + credentials.consumerKey + '", ' +
'oauth_nonce="' + nonce + '", ' +
'oauth_signature="' + encodeURIComponent(signature) + '", ' +
'oauth_signature_method="HMAC-SHA1", ' +
'oauth_timestamp="' + timestamp + '", ' +
'oauth_token="' + credentials.accessToken + '", ' +
'oauth_version="1.0"';
}
ステップ2. 投稿の結果をDiscordに通知する
関数:sendToDiscord(message)
🧠 処理の流れ
- ステップ①で取得した「成功」または「失敗」の結果メッセージをDiscordのWebhook URLにPOSTして通知
コード(GAS)
function sendToDiscord(message) {
const webhookUrl = "https://discord.com/api/webhooks/XXXXX/XXXXX"; // ここを自分のWebhookに置き換えてください
const payload = { content: message };
const options = {
method: "post",
contentType: "application/json",
payload: JSON.stringify(payload)
};
UrlFetchApp.fetch(webhookUrl, options);
}
ステップ3. ステップ1,2を実行する
関数:executeAndNotify()
🧠 処理の流れ
- postX()を呼び出してXに投稿
- その結果をsendToDiscord()で通知
→ これひとつで全体が動きます!
コード(GAS)
function executeAndNotify() {
var result = postX();
sendToDiscord(result);
}
トリガー設定手順
初心者でも簡単に設定できます。以下の手順で、自動実行の仕組みを構築しましょう。
- GASエディタ上部メニューから「トリガー」アイコンをクリック
- 「+ トリガーを追加」を選択
- 実行関数として
executeAndNotify
を選択 - イベントの種類(時間ベースなど)を選択し、実行頻度を設定
- 保存して完了
参考
まとめ
この構成により、スプレッドシートに登録された「未投稿」データを元にXへ投稿を行い、その処理結果をDiscordへ自動通知する仕組みが実現できます。GAS初心者でもすぐに始められる実用的な自動化テクニックです。
もし「XのAPIの使い方」や「Webhookの作成方法」などでつまずいた場合は、それぞれのドキュメントをチェックしてみてください。