こんにちは、せこしょーです。
今回のスプレッドシート活用術は、
GAS(Google Apps Script)を使って、Twitterデータを取得します。
トリガーを設定すると毎日決まった時間に検索キーワードを含むツイートを自動取得してくれます。
動画はこちら↓↓
ツイートデータを取得するTwitter API v2をGASで利用するために、APIの利用申請(EssentialもしくはElevated)が必要です。
詳細は動画を参考ください。
キーワードに一致する昨日分のツイートを取得するGASのコード↓ ↓
const BEARER_TOKEN = "{BEARER_TOKEN}"
/**
* Twitterから検索キーワードに一致するツイートを取得し、スプレッドシートへの書き込みをする
* */
const main = () => {
const keyword = getValueOnSheet('B2');
if (keyword == '') {
Browser.msgBox(`キーワードを入力して下さい。`);
return;
}
const searchWord = "(" + keyword + " OR %23" + keyword + ") -is:retweet"; // キーワードもしくはハッシュタグ(リツイートは除く)
// const searchWord = keyword + " -is:retweet";
// const searchWord = "(" + keyword + " OR %23" + keyword + ") -is:retweet -is:quote -is:reply";
let next_token = undefined;
do {
const topics = fetchTopics(searchWord,next_token);
console.log(topics);
if (topics.meta.result_count == 0) {
console.log("検索結果は0件です。")
return;
}
next_token = topics.meta.next_token;
const dataForSheet = makeData(topics);
recordToSpreadsheet(dataForSheet);
} while (next_token != undefined);
}
/**
* 昨日の検索キーワードのツイートを取得する
* */
const fetchTopics = (keyword,pageToken) => {
const date = new Date(); // 現在の日時でDateオブジェクトを生成
// Twitter API仕様にあわせて協定世界時の開始日、終了日を設定する
// なお、日本標準時は協定世界時の+9時間
date.setDate(date.getDate() - 2)
const startDate = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd')+"T15:00:00Z";
date.setDate(date.getDate() + 1)
const endDate = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd')+"T14:59:59Z";
let targetUrl = `https://api.twitter.com/2/tweets/search/recent?query=${keyword}&tweet.fields=created_at,text,public_metrics,entities&start_time=${startDate}&end_time=${endDate}&expansions=author_id&max_results=100`;
if (pageToken != undefined) {
targetUrl = targetUrl + `&next_token=${pageToken}`;
}
const options = {
'method': 'get',
'headers': {
'Content-Type': 'application/json',
'authorization': 'Bearer ' + BEARER_TOKEN,
},
};
const response = JSON.parse(UrlFetchApp.fetch(targetUrl, options));
return response;
}
/**
* ツイート取得内容を記載用に分解し、2次元配列を返す
* */
const makeData = (topics) => {
const users = topics.includes.users;
console.log(users);
let usernames = [];
for (let i = 0; i < users.length; i++) {
usernames.push(users[i].username)
}
formatted_user_names = usernames.join();
console.log(formatted_user_names);
// ユーザー名(100件)のユーザ情報をAPIで取得する
const usersData = fetchUsersInfo(formatted_user_names).data;
console.log(usersData);
let rows = [];
for (let i = 0; i < topics.data.length; i++) {
const data = topics.data[i];
const tweet = data.text
// リツイートは除外する
// if (tweet.slice(0,4).indexOf("RT @") != -1) {
// continue;
// }
const userInfo = getUserInfo(data.author_id, usersData);
const name = userInfo[0];
const username = userInfo[1];
const following_count = userInfo[2];
const followers_count = userInfo[3];
const url = "https://twitter.com/"+username+"/status/"+data.id;
const jstDate = formatDate(new Date(data.created_at), 'yyyy-MM-dd HH:mm:ss');
rows.push([jstDate, name, following_count,followers_count,tweet, data.public_metrics.like_count, data.public_metrics.retweet_count, data.public_metrics.quote_count, data.public_metrics.reply_count,url]);
}
return rows;
}
/**
* スプレッドシートに対象ツイートを記載する
* */
const recordToSpreadsheet = (rows) => {
const sheet = getSheet();
const lastRowNumber = sheet.getLastRow();
sheet.getRange(lastRowNumber+1,1,rows.length,10).setValues(rows);
}
/**
* ユーザー情報を取得する(API)
* */
const fetchUsersInfo = (usernames) => {
const targetUrl = `https://api.twitter.com/2/users/by/?usernames=${usernames}&user.fields=public_metrics`;
const options = {
'method': 'get',
'headers': {
'Content-Type': 'application/json',
'authorization': 'Bearer ' + BEARER_TOKEN,
},
};
const response = JSON.parse(UrlFetchApp.fetch(targetUrl, options));
return response;
}
/**
* ユーザーを特定し、ユーザー情報を取得する
* */
const getUserInfo = (authorId, users) => {
for (let i = 0; i < users.length; i++) {
if (authorId == users[i].id) {
return [users[i].name,users[i].username,users[i].public_metrics.following_count,users[i].public_metrics.followers_count];
}
}
return undefined;
}
/**
* 日付のフォーマット
* */
const formatDate = (date, format) => {
date.setDate(date.getDate());
return Utilities.formatDate(date, 'JST', format);
}
/**
* データ書き込み対象のシートを取得する
* */
const getSheet = () => {
return SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Twitter');
}
/**
* スプレッドシートから検索キーワードを取得する
* */
const getValueOnSheet = (cellPosition) => {
const sheet = getSheet();
return sheet.getRange(cellPosition).getValue();
}
コメント