Twitterで APIキーを取得するには事前に「デベロッパー申請」が必要です(英語で申請目的などを書く必要があります💧)
- ベアラートークンを取得して保存します
- ベアラートークンを使ってエンドポイントにリクエストを送ります
トークンを取得
TwitterAPIへのリクエスト用のOAuth 2.0ベアラートークンを取得します
エンドポイント:https://api.twitter.com/oauth2/token
Basic認証:HTTPヘッダでは特殊記号を使用できないのでユーザー名とパスワードをコロン「 :」で区切ってBase64エンコードした文字列(アルファベットと数字と一部の記号だけにする)を使います
function setupToken() {
const API_KEY = encodeURIComponent('ここにAPI key')
const SECRET_KEY = encodeURIComponent('ここにAPI secret key')
const bt = Utilities.base64Encode(`${API_KEY}:${SECRET_KEY}`);
const params = {
"method" : "POST",
"headers" : {
"Authorization" : "Basic " +bt,
"Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
"Accept-Encoding" : "gzip"
},
"payload" : {
"grant_type" : "client_credentials"
}
};
const response = UrlFetchApp.fetch('https://api.twitter.com/oauth2/token', params);
const data = JSON.parse(response.getContentText());
console.log(data)
}
// { token_type: 'bearer',
// access_token: 'AAAAAAAAA...' }
GASのPropertiesServiceクラスを利用してトークンを保存します(Key-Value形式のデータを保存できます)
例として:別の関数(getToken)から保存したトークンを呼び出します
function setupToken() {
//省略
const data = JSON.parse(response.getContentText());
// console.log(data)
if(data.access_token){
PropertiesService.getScriptProperties().setProperty("TOKEN", data.access_token);
}
}
function getToken(){
const token = PropertiesService.getScriptProperties().getProperty("TOKEN");
console.log(token);
}
リクエストを送る
検索キーワードからツイートを取得する例
function search() {
const token = PropertiesService.getScriptProperties().getProperty("TOKEN");
if(token === null){
token = setupToken();
}
//エンドポイント
const url = `https://api.twitter.com/1.1/search/tweets.json?q=${検索ワード}&count=1`;
const params = {
"method" : "GET",
"headers" : {
"Authorization" : "Bearer " +token ,
"Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
"Accept-Encoding" : "gzip"
},
// "followRedirects" : true,
// "muteHttpExceptions" : true
};
const response = UrlFetchApp.fetch(url, params);
const data = JSON.parse(response.getContentText());
const tweet = data.statuses;
console.log(tweet);
}
備考
- Content-Type:”application/x-www-form-urlencoded;charset=UTF-8″
キーと値が ‘=’ で挟まれ ‘&’ で区切られてエンコードされる - ContentType :”application/json”
JSON形式で{“a”:1,”b”:2}で送る:JSON.stringify(params)
Accept-Encodingはサポートしている圧縮方式を伝えてその方式で返却してもらう
- muteHttpExceptions:true
404などエラーの場合でもレスポンスを返します - validateHttpsCertificates:true
true : SSL証明書エラーが発生した場合でも処理を継続します。 - followRedirects:true
参照先にてリダイレクトが発生した場合、リダイレクト先を参照します
指定したアカウントの固定ツイートをシートに書き出す
複数のアカウントの固定ツイートを取得して、シートに書き出す
*IDはhttps://tweeterid.com/で検索
*パラメータにexpansions=pinned_tweet_idを追加すると固定ツイートがあれば取得できます
https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users#requests
function createData() {
const data =[]
const token = PropertiesService.getScriptProperties().getProperty("TOKEN");
if(token === null){
token = setupToken();
}
//エンドポイント
const url = 'https://api.twitter.com/2/users?ids=1つ目のID,2つ目のID,3つ目のID,...&expansions=pinned_tweet_id';
const params = {
"method" : "GET",
"headers" : {
"Authorization" : "Bearer " +token,
"Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
"Accept-Encoding" : "gzip"
},
};
const response = UrlFetchApp.fetch(url, params);
const res = JSON.parse(response.getContentText());
//console.log(res)
const contents = res.includes.tweets
contents.forEach((content)=>{
//必要な場合 HTMLタグの整形
let text = content.text.replace(/\n/g, '<br>')
text = AutoLink(text)
data.push([text])
})
//シートに書き込む
const ss = SpreadsheetApp.openById('シートのID');
const sheet = ss.getSheetByName('data');
let row = data.length;
let col = data[0].length;
let range = sheet.getRange(1, 1, row, col);
range.setValues(data);
}
//固定ツイート本文にURLがあればリンクにするため
function AutoLink(str) {
const regexp_url = /((h?)(ttps?:\/\/[a-zA-Z0-9.\-_@:/~?%&;=+#',()*!]+))/g; // ']))/;
const regexp_makeLink = function(all, url, h, href) {
return '<a href="h' + href + '">' + url + '</a>';
}
return str.replace(regexp_url, regexp_makeLink);
}
備考(便利な関数)
文字列にURLが含まれていた場合にアンカータグを追加する
function AutoLink(str) {
var regexp_url = /((h?)(ttps?:\/\/[a-zA-Z0-9.\-_@:/~?%&;=+#',()*!]+))/g; // ']))/;
var regexp_makeLink = function(all, url, h, href) {
return '<a href="h' + href + '">' + url + '</a>';
}
return str.replace(regexp_url, regexp_makeLink);
}
固定ツイートのスプレッドシートへの書き込みをトリガーで定期実行
スプレッドシートから取得したデータをJSONで公開
function doGet(e){
const data = {
status : 'success',
data : myData()
};
const output = JSON.stringify(data);
return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JSON);
}
//スプレッドシートからデータを取得
function myData() {
const ss = SpreadsheetApp.openById('シートID');
const sheet = ss.getSheetByName('data');
const rows = sheet.getDataRange().getValues();
const data = rows.map(row=>{
return {content: row[0]}
})
return data;
}
公開したJSONを取得してDOMに表示する
<div id="news"></div>
async function load() {
let error = ''
let results = []
try {
let data = await fetch('エンドポイント')
if(!data.ok || data.status == 404) {
throw Error('取得に失敗しました')
}
const result = await data.json()
results = result.data
}
catch(err) {
error =`エラー:${err.message}`
}
return {error, data: results}
}
(async () => {
const el = document.querySelector('#news')
el.innerHTML = `<div>Loading...</div>`
const { data, error } = await load()
let contents = data.reduce((accu, str) => {
return accu + `<p>${str.content}</p>`
}, '')
if(error === ''){
el.innerHTML = contents
}
if(error !== ''){
el.innerHTML = `<p>${error}</p>`
}
})()