質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Q&A

解決済

1回答

1394閲覧

【GAS】Twitter ユーザー情報自動取得ツール作成で大きな壁にブチ当たってしまいました。お助けください

TN.7

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

1グッド

0クリップ

投稿2022/12/25 15:38

編集2022/12/26 00:14

前提

GASでTwitterのユーザー情報を取得するシートを作成しています。
https://note.com/nepia_infinity/n/n751c04669657#5WC1x
この方の記事を参考に作成しているのですが、エラーが表示されてしまいます。

コピペで作成した場合は下記のエラーコードが表示されます

Exception: Request failed for https://api.twitter.com returned code 403. Truncated server response: {"errors":[{"code":99,"message":"Unable to verify your credentials","label":"authenticity_token_error"}]} (use muteHttpExceptions option to examine full response)

26行目、27行目は自分のAPI Key, secret Keyに置き換えてます

エラーログには認証に失敗しているとのメッセージが出るのですが、コード内のどこが悪いのかがイマイチ分かりません。

実現したいこと

最終的には

  • Twitterユーザーリンクをスプシに入力したら、自動でプロフ情報を取得してスプシに記載されるシステムにしたいと考えています。

そのために、まずは先ほど挙げたエラーコードを解決したいです。

発生している問題・エラーメッセージ

Exception: Request failed for https://api.twitter.com returned code 403. Truncated server response: {"errors":[{"code":99,"message":"Unable to verify your credentials","label":"authenticity_token_error"}]} (use muteHttpExceptions option to examine full response)

該当のソースコード

GoogleAppsScript

1/* 2* userListに存在するユーザー名のフォロワー数などを調べる 3* @return {string} トークン 4* 5*/ 6function setUserInfo() { 7 const sheetName = 'userList'; 8 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 9 const sheet = spreadsheet.getSheetByName(sheetName); 10 const values = getUserInfo_(sheetName); 11 12 //1列目にユーザー名が記載されているため、2列目から書き込みを開始する。 13 sheet.getRange(2, 2, values.length, values[0].length).setValues(values); 14 15} 16 17 18/* 19* Twitterのアクセストークンを取得する 20* @return {string} トークン 21* 22*/ 23function getToken_() { 24 25 const API = { 26 KEY: PropertiesService.getScriptProperties().getProperty('API_KEY'), 27 SECRET_KEY: PropertiesService.getScriptProperties().getProperty('API_SECRET_KEY'), 28 MILLISECOND: 100000 //tokenの有効期限(ミリ秒) 29 }; 30 31 const tokenUrl = 'https://api.twitter.com/oauth2/token'; 32 const tokenCredential = Utilities.base64EncodeWebSafe(API.KEY + ':' + API.SECRET_KEY); 33 const tokenOptions = { 34 headers : { 35 'authorization': 'Basic ' + tokenCredential, 36 'Content-Type': 'Application/x-www-form-urlencoded;charset=UTF-8' 37 }, 38 method: 'post', 39 payload: 'grant_type=client_credentials' 40 }; 41 42 const responseToken = UrlFetchApp.fetch(tokenUrl, tokenOptions); 43 const parsedToken = JSON.parse(responseToken); 44 const token = parsedToken.access_token; 45 46 //console.log(token); 47 return token; 48} 49 50 51 52/* 53* シートに記載されているユーザー名を取得する 54* 55* @param {string} シート名 56* @return {object} 1次元配列 57* 58*/ 59 60function getUserList_(sheetName) { 61 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 62 const sheet = spreadsheet.getSheetByName(sheetName); 63 const lastRow = sheet.getLastRow(); 64 65 //A2から最終行まで 66 const userArray = sheet.getRange(2, 1, lastRow -1, 1).getValues().flat(); 67 const string = userArray.join(',');//文字列化 68 69 console.log(string); 70 return string; 71}//end 72 73 74 75/* 76* シートに記載されているユーザーのフォロワー数などを取得する 77* 参考URL : https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username 78* @param {string} シート名 79* @return {object} 2次元配列 80* 81*/ 82 83function getUserInfo_(sheetName){ 84 85 const users = getUserList_(sheetName);//string 86 const apiUrl = 'https://api.twitter.com/2/users/by?usernames=' + users + '&user.fields=id,profile_image_url,public_metrics,description,location'; 87 const token = getToken_(); 88 const apiOptions = { 89 headers : { 90 'Authorization': `Bearer ${token}` 91 }, 92 method : 'get', 93 muteHttpExceptions : true 94 }; 95 96 const responseApi = UrlFetchApp.fetch(apiUrl, apiOptions); 97 98 console.log(apiUrl); 99 console.log(`HTTPデータ: ${responseApi.getContentText()}`); 100 101 102 //HTTP リスポンスが200以外だったら、処理を終了 103 if (responseApi.getResponseCode() !== 200){return}; 104 const objects = JSON.parse(responseApi.getContentText()); 105 console.log(objects); 106 107 let values = []; 108 109 //usersは1度、シートからユーザ名を取得する際に使用している 110 const targetUsers = objects.data; 111 //console.log(tweets); 112 113 for(const user of targetUsers){ 114 const userName = user.username;//ユーザーネーム 115 const nameJp = user.name;//アカウント名 116 const userImage = `=IMAGE("${user.profile_image_url}",1)`;//プロフィール画像 117 const followers = user.public_metrics.followers_count;//フォロワー数 118 const profileUrl = 'https://twitter.com/' + userName;//プロフィールページのURL 119 const userDescription = user.description;//アカウントの説明 120 const userLocation = user.location; 121 122 console.log(`${userName}, \n${nameJp}, \n${userImage}, \n${profileUrl}, \nフォロワー ${followers}`); 123 values.push([nameJp, userImage, profileUrl, followers, userDescription, userLocation]); 124 125 }//for 126 return values 127}//end

最後に

本気で完成させたいので、お手隙の際にでも大丈夫なので何かヒントをいただけますと幸いです。
よろしくお願いいたしますm(_ _)m

TN.7👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Demerara

2022/12/25 19:42

コピペしたとありますが、API キーとアクセストークンは取得済みでコード内のそれぞれの値を自身の値で置き換えてますか?エラーログを見る限り認証に失敗しているようなので。 もし置き換えているのであれば、補足に追加しておいたほうがいいかもしれません。
TN.7

2022/12/26 00:12

ご回答ありがとうございます! APIキーとアクセストークンは自分のものに置き換えてます。 TwitterAPI自体は他のツールにも使えています。
guest

回答1

0

自己解決

自己解決したためこのスレッドは閉じさせて頂きます

投稿2022/12/26 01:37

編集2022/12/26 11:56
TN.7

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問