【無料】X(Twitter)にTech Blog の記事をランダムに定期・自動投稿するScriptをGASで作る!
こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、X(Twitter)にTech Blog の記事をランダムに定期・自動投稿するScriptをGASで作る方法について、解説します。
X(Twitter)にTech Blogの記事をランダムに定期・自動投稿したい!
私は個人Tech Blogと、Zennの2つでTech Blogの執筆をしています。
今回は、この2つのBlogのうち個人Tech Blogの方の記事をランダムに定期・自動投稿するためのScriptをGASで作成しました。
GASを選んだ理由
最初は、PythonでTech Blogの記事をランダムに定期・自動投稿するScriptを作成しようと考えていましたが、コストの面でGASを採用しました。
(GASなら、無料で簡単に定期・自動投稿するScriptを実現できます。。。🙌 🌟)
GAS採用までの調査のプロセスを記したスクラップ記事
要件定義
次の内容をプログラムで自動化することを要件定義とする。
- Tech Blogの記事を投稿したい。
- 投稿する記事は、ランダムに選びたい。
- 毎日、朝(午前7~8時)と昼(午後11時〜12時)と夕方(午後6~7時)の3回、定期的に投稿をしたい。
【事前準備】GASとX(Twitter)APIの設定をする💪🥺💪✨
Google Apps Script(GAS)を使って、X(Twitter)に自動投稿を行うには、GASとX(Twitter)それぞれの設定が必要です。
こちらの記事を参考に、X(Twitter)APIの登録と、Google Apps Scriptのプロジェクトを作成・OAuth2ライブラリの追加やOAuth2の認証を進めてください。
GoogleのOAuth2の認証
X(Twitter)のOAuth2認証
スプレッドシートで投稿のMetaデータを作成する💪🥺💪✨
今回は、GASで投稿を作成するためのMetaデータ(記事一覧データ)の保管庫として、スプレッドシートを活用します。
イメージとしては、次のようなデータを作成していきます。
WordPressで、スプレッドシートに投稿のMetaデータを作成する場合
WordPressを使っている方の場合は、Export All URLsというPluginを使って、記事一覧データの抽出を実行することができます。
結果は、次のように表示されます。
これをコピペして、スプレッドシートに貼り付ければ、Metaデータ(記事一覧データ)の保管庫は完成です。
X(Twitter)にTech Blog の記事をランダムに定期・自動投稿するScript
X(Twitter)にTech Blog の記事をランダムに定期・自動投稿するScriptの内容は、次のとおりです。
こちらのGASのCodeは、こちらの『GAS×スプレッドシートでTwitterに定期自動投稿する方法』のSampleCodeをベースにハッシュタグに使用するカテゴリー情報などを追加しています。
(素晴らしい記事をありがとうございます🙌)
// X APIを使った OAuth2認証 & 投稿の定期実行のサンプル Ver. ハッシュタグ追加
/** ツイッターのクライアント識別子 */
const CLIENT_ID = "";
/** ツイッターのClient Secret */
const CLIENT_SECRET = "";
/** スプレッドシートのID */
const SHEET_ID = "";
/** 編集権限のある Google Acount の G_Mail */
const G_MAIL = "";
// 初回だけ必要な OAuth2・認証処理
function main() {
const service = getService();
Logger.log("初回だけ必要な OAuth2・認証処理 Start");
if (service.hasAccess()) {
Logger.log("認証済みです");
} else {
Logger.log("認証ができていません");
const authorizationUrl = service.getAuthorizationUrl();
Logger.log("次の URL を開いて、認証をします。: %s", authorizationUrl);
}
}
// スプレッドシートからツイッターに投稿する記事をランダムに取得して、ツイート本文を作成する
function autoTweetFromSheet() {
Logger.log("ツイート本文を作成する・処理 Start");
let today = new Date();
let todayStr = Utilities.formatDate(today, "JST", "YYYY/MM/dd");
const mySpreadSheet = SpreadsheetApp.openById(SHEET_ID);
Logger.log(mySpreadSheet);
// 編集権限のある Google Acount の G_Mail を渡す
mySpreadSheet.addEditor(G_MAIL);
const sheetList = mySpreadSheet.getSheets();
Logger.log(sheetList);
// 1番目のスプレッドシートを取得する
const sheet = mySpreadSheet.getSheets()[0];
Logger.log(sheet);
const lastRow = sheet.getLastRow();
const targetRow = makeRundom(lastRow);
/** タイトル */
const title = sheet.getRange(targetRow, 1).getValue();
/** URL */
const link = sheet.getRange(targetRow, 2).getValue();
/** カテゴリー(ハッシュタグに使用する) */
const category = sheet.getRange(targetRow, 3).getValue();
/** 投稿本文を作成する Ver. ハッシュタグ追加 */
const msg =
`【Tech Blog おすすめ記事紹介 ${todayStr}】\n` +
`\n${title}\n` +
`\n記事はこちら🌟\n${link}\n` +
`\n#${category}\n#Web開発\n#Webエンジニア\n#エンジニアと繋がりたい\n#プログラミング`;
return msg;
}
// 乱数作成
function makeRundom(count) {
let random = Math.random();
random = Math.floor(random * count) + 1;
return random;
}
// X(Service) に X-API, OAuth2 を使って Access する
function getService() {
pkceChallengeVerifier();
const userProps = PropertiesService.getUserProperties();
const scriptProps = PropertiesService.getScriptProperties();
// X-Service作成
return OAuth2.createService("twitter")
.setAuthorizationBaseUrl("https://twitter.com/i/oauth2/authorize")
.setTokenUrl(
"https://api.twitter.com/2/oauth2/token?code_verifier=" +
userProps.getProperty("code_verifier")
)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setCallbackFunction("authCallback")
.setPropertyStore(userProps)
.setScope("users.read tweet.read tweet.write offline.access")
.setParam("response_type", "code")
.setParam("code_challenge_method", "S256")
.setParam("code_challenge", userProps.getProperty("code_challenge"))
.setTokenHeaders({
Authorization:
"Basic " + Utilities.base64Encode(CLIENT_ID + ":" + CLIENT_SECRET),
"Content-Type": "application/x-www-form-urlencoded",
});
}
// 認証後のCallBack
function authCallback(request) {
const service = getService();
const authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput("Success!");
} else {
return HtmlService.createHtmlOutput("Denied.");
}
}
function pkceChallengeVerifier() {
var userProps = PropertiesService.getUserProperties();
if (!userProps.getProperty("code_verifier")) {
var verifier = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
for (var i = 0; i < 128; i++) {
verifier += possible.charAt(Math.floor(Math.random() * possible.length));
}
var sha256Hash = Utilities.computeDigest(
Utilities.DigestAlgorithm.SHA_256,
verifier
);
var challenge = Utilities.base64Encode(sha256Hash)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
userProps.setProperty("code_verifier", verifier);
userProps.setProperty("code_challenge", challenge);
}
}
function logRedirectUri() {
var service = getService();
Logger.log(service.getRedirectUri());
}
// ツイートを実行する
function sendTweet() {
const payload = {
text: autoTweetFromSheet(),
};
Logger.log("ツイートを実行する");
const service = getService();
if (service.hasAccess()) {
Logger.log("サービスアクセス完了 ツイート処理を続行する");
const url = `https://api.twitter.com/2/tweets`;
const response = UrlFetchApp.fetch(url, {
method: "POST",
contentType: "application/json",
headers: {
Authorization: "Bearer " + service.getAccessToken(),
},
muteHttpExceptions: true,
payload: JSON.stringify(payload),
});
const result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
const sheet = SpreadsheetApp.openById(SHEET_ID).getSheets()[0];
const lastRow = sheet.getLastRow();
let now = new Date();
sheet.getRange(lastRow + 1, 1).setValue(result["data"]["id"]);
sheet.getRange(lastRow + 1, 2).setValue(result["data"]["text"]);
sheet.getRange(lastRow + 1, 3).setValue(now);
} else {
Logger.log("認証ができていません");
var authorizationUrl = service.getAuthorizationUrl();
Logger.log("次の URL を開いて、認証をします。: %s", authorizationUrl);
}
}
GASで、トリガーの設定をする
最後に「毎日、朝, 昼, 夕の3回、定期的に投稿する」ためのGAS・トリガーの設定をしていきます。
まずは、GASのトリガーを選択します。
続いて、朝, 昼, 夕の3タイプの定期実行トリガーを作成していきます。
朝(午前7~8時)のトリガー設定
昼(午後11時〜12時)のトリガー設定
夕方(午後6~7時)のトリガー設定
これで、Blogの記事をランダムに定期・自動投稿する仕組みが完成しました🙌✨
まとめ
今回の自動・定期投稿のScript作成により、おすすめ投稿を手間をかけずにできるようになりました。
やはり自動化は偉大ですね。
まさぴょんのX(Twitter)のフォロー、ぜひともお願いします。
これから、Zenn Tech Blogの方も自動投稿対象に追加する予定です。
個人で、Blogもやっています、よかったら見てみてください。
注意事項
この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。
求む、冒険者!
AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨
詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。
参考・引用
AIQ 株式会社 に所属するエンジニアが技術情報をお届けします。 ※ AIQ 株式会社 社員による個人の見解であり、所属する組織の公式見解ではありません。 Wantedly: wantedly.com/companies/aiqlab
Discussion