X投稿の送信前ミスを公開前に発見|GASで承認・本文をdry-run監査
ツールおじ|GoogleアカウントをAIエージェント化
X投稿をまとめて準備していると、承認前の行、文字数が長すぎる本文、同じ文章の重複が混ざることがあります。この記事では、Xへ接続せず、投稿も予約も行わず、スプレッドシート上の投稿候補だけを事前確認します。
確認結果はログへ出すだけです。初期設定では本文の中身をそのままログへ残さず、行番号と理由だけを表示します。
先に知っておきたいこと
- X API、OAuth、外部投稿サービスへ接続しません。
- 投稿、予約、削除、いいね、リプ、フォローは行いません。
- 承認状態、本文の長さ、重複、URL欄の入れ忘れだけを確認します。
- 実データへ使う前に、コピーしたテスト用シートで試してください。
- 伸びる投稿や収益化を保証するものではありません。
準備するシート
スプレッドシートに「X投稿キュー」シートを作り、1行目へ次の見出しを入れます。
- A列: post_at
- B列: body
- C列: approved
- D列: status
- E列: source_url
- F列: memo
2行目以降へ投稿候補を入れます。approved は TRUE、status は draft / ready / posted / dropped のように管理します。
コピーして使える最小コード
const CONFIG = Object.freeze({
DRY_RUN: true,
SHEET_NAME: 'X投稿キュー',
MAX_ROWS: 100,
MAX_CHARS: 140,
LOG_BODY_TEXT: false
});
function auditXPostPrePublishFree() {
if (CONFIG.DRY_RUN !== true) {
throw new Error('安全のためDRY_RUNはtrue固定です');
}
if (!Number.isInteger(CONFIG.MAX_ROWS) ||
CONFIG.MAX_ROWS < 1 || CONFIG.MAX_ROWS > 100) {
throw new Error('MAX_ROWSは1〜100で指定してください');
}
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(CONFIG.SHEET_NAME);
if (!sheet) {
throw new Error('X投稿キューシートが見つかりません');
}
const values = sheet.getDataRange().getValues();
if (values.length < 2) {
throw new Error('確認する投稿候補を1件以上入力してください');
}
const seenBodies = new Map();
const issues = [];
const rows = values.slice(1, CONFIG.MAX_ROWS + 1);
rows.forEach((row, index) => {
const rowNumber = index + 2;
const postAt = row[0];
const body = String(row[1] || '').trim();
const approved = row[2] === true ||
String(row[2]).toUpperCase() === 'TRUE';
const status = String(row[3] || '').trim().toLowerCase();
const sourceUrl = String(row[4] || '').trim();
if (!body) {
issues.push({ row: rowNumber, reason: '本文が空欄' });
return;
}
if (!postAt) {
issues.push({ row: rowNumber, reason: '投稿予定日時が空欄' });
}
if (!approved) {
issues.push({ row: rowNumber, reason: 'approvedがTRUEではない' });
}
if (status && !['draft', 'ready'].includes(status)) {
issues.push({ row: rowNumber, reason: '公開前確認の対象外status' });
}
if (body.length > CONFIG.MAX_CHARS) {
issues.push({
row: rowNumber,
reason: '本文が長すぎる',
chars: body.length
});
}
if (!sourceUrl) {
issues.push({ row: rowNumber, reason: 'source_urlが空欄' });
}
const normalizedBody = body.normalize('NFKC').replace(/\s+/g, ' ');
if (seenBodies.has(normalizedBody)) {
issues.push({
row: rowNumber,
reason: '本文が別行と重複',
otherRow: seenBodies.get(normalizedBody)
});
} else {
seenBodies.set(normalizedBody, rowNumber);
}
});
const checkedCount = rows.filter((row) => String(row[1] || '').trim()).length;
const result = {
status: issues.length ? 'HOLD' : 'PASS',
dryRun: CONFIG.DRY_RUN,
checkedCount,
issueCount: issues.length,
issues
};
if (CONFIG.LOG_BODY_TEXT === true) {
result.warning = '本文をログへ出す設定です。機密情報がないか確認してください。';
}
Logger.log(JSON.stringify(result));
if (issues.length) {
throw new Error('送信前の確認でHOLDがあります');
}
}実行前の準備
1. テスト用のスプレッドシートをコピーします。
2. 「X投稿キュー」シートへ投稿候補を数行だけ入れます。
3. Apps Scriptへコードを貼り付けます。
4. auditXPostPrePublishFree を実行します。
5. 実行ログの status、issueCount、issues を確認します。
6. HOLDが出た行を直してから、もう一度コピー環境で確認します。
ログの読み方
- PASS: 承認、本文長、重複、URL欄の確認が通っています。投稿はまだ行われていません。
- HOLD: 投稿前に直すべき行があります。
- row: 修正対象の行番号です。
- otherRow: 重複元として見つかった行番号です。
停止条件
- approved が TRUE ではない
- 本文が空欄、または長すぎる
- 同じ本文が複数行にある
- 投稿予定日時や source_url が空欄
- status が posted / dropped など公開前確認の対象外になっている
どれか1つでも当てはまる場合は、投稿や予約処理を追加せず、表を直してから再確認してください。
制限と安全上の注意
- この無料コードは送信前監査専用です。Xへの投稿機能は含みません。
- URLの内容やSNS上の状態は確認しません。
- 文字数は単純な文字数で見ています。URL短縮後の厳密な投稿文字数とは一致しない場合があります。
- LOG_BODY_TEXTをtrueにすると本文がログへ出る可能性があります。通常はfalseのまま使ってください。
- Google公式・X公式の商品ではありません。
公開前チェックリスト
- [ ] コピー環境で実行した
- [ ] DRY_RUNがtrueのまま
- [ ] issueCountが0
- [ ] LOG_BODY_TEXTがfalse
- [ ] 投稿、予約、削除、いいね、リプ、フォローのコードを追加していない
まとめ
X投稿の自動化は、送信処理を書く前に「本当に送ってよい候補だけか」を分けると事故が減ります。このコードなら投稿前の表だけを読み取り、承認漏れ、本文の長さ、重複、URL欄の入れ忘れを先に見つけられます。
承認、停止条件、投稿キュー運用までまとめて整えたい方は、関連する有料Tipsも確認できます。
Gasおじ式 X投稿キュー自動実行GAS Pro|危ない時だけ止まる

GasおじのTips商品一覧を見る
GasおじのTips商品一覧

※学習・検証用の例です。実データへ適用する前にコピー環境で確認してください。Google公式・Google公認、またはX公式の商品ではありません。
