【JavaScript】TwitterAPI特定情報取得（リツイート除去機能 & 完全コピペで動く）【GAS】

2022年10月5日更新。

# 【はじめに】
会社の人から頼まれ、特定の言葉が入ったツイートをデータとして抽出することになりました。
そこで、手始めにGASとスプレッドシートを使いボタンひとつで最新のツイートを表示しようと思います。

### 【条件】
・API登録は完了しているものとし、GASの設定項目から説明していきます。こちらが完璧な方は。プログラムまで飛ばしてください。
・今回はGASにて抽出していくため、取得件数は10〜100件が限界になります。
・完結に書きました。

### 【参考にしたサイト】
・事前準備パート
https://note.com/taraco123/n/n7337d2b8a6b3
・プログラムパート
https://isub.co.jp/efficiency/twitter-specified-keyword-to-spreadsheet/

# 【1部】
まずは、API利用のための準備について説明を行っていきます。
まずは、スプレッドシートとGASの準備とAPIの準備です。


#### 【Twitter API のキーを取得】
下記のサイトにアクセスし、「Details」を押します。
https://developer.twitter.com/en/apps
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/0b1be021-8aa7-7900-fc40-c3e94f5317aa.png)


キーとトークンより、「API key」と「API secret key」を控えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/2fa9aeee-f191-d223-8957-d950f53bec1b.png)




#### 【ライブラリの導入】
GASに2つのライブラリを登録します。

スクリプトエディタの左側メニューのライブラリの追加ボタンを押し、表示されるダイアログ内に下記のプロジェクトキーを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/176da060-c5cf-6a6b-e2b1-4816d702ff1d.png)


###### ①TwitterWebServiceライブラリを導入します。
公式のライブラリではないようです。(https://gist.github.com/M-Igashi/750ab08718687d11bff6322b8d6f5d90)

TwitterWebService
プロジェクトキー: 1rgo8rXsxi1DxI_5Xgo_t3irTw1Y5cxl2mGSkbozKsSXf2E_KBBPC3xTF

ライブラリのバージョンは2(現時点の最新)で大丈夫です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/2e18228f-4474-f1a4-4258-094f3148cb1e.png" width=80%>


###### ②OAuth1ライブラリを導入します。
プロジェクトキー: 1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s

ライブラリのバージョンは18(現時点の最新)で大丈夫です。
※最新ではエラーが発生するという記事も有りましたが、現在は大丈夫でした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/58da9b40-d8a9-f409-de51-b897c9568a0c.png" width=80%>


#### 【コールバックURL設定】

コールバックとは、ある機能を呼び出したときに、その結果を反映させる受け皿のことを指します。
今回の場合はGASからTwitter上にアクセス後に再びGASに戻るような処理を行っています。

GASのスクリプトIDが必要なため控えておいてください。
GASのスクリプトIDは、GAS開発画面のURLの下記の部分になります。
```
https://script.google.com/home/projects/[GASのスクリプトID]/edit
```
メモをしたら、再びTwitterDeveloperに戻ります。
「Edit details」を押し、コールバックURLを設定していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/d1feaf85-7db8-fb74-35b7-8c541caa9318.png)

「Callback URLs」の「＋Add another」ボタンにて下記のURLを設定して保存してください。
```
https://script.google.com/macros/d/[GASのスクリプトID]/usercallback
```
※保存のとき、「Tell us how this App will be used」欄に100文字記載しなければならないエラーが出現する場合があります。
内容はAPIを利用する理由やどのような内容の取得を行うのかで大丈夫です。



#### 【Twitterアプリ認証】
下記のサイトを参考にしました。
https://qiita.com/akkey2475/items/ad190a507b4a7b7dc17c

下記のスクリプトをコピーしてください。「API key」と「API secret key」は上記でメモを取ったものに置き換えてください。

```
// 認証用インスタンス
var twitter = TwitterWebService.getInstance('API Key', 'API secret key');

// 認証
function authorize() {
  twitter.authorize();
}

// 認証解除
function reset() {
  twitter.reset();
}

// 認証後のコールバック
function authCallback(request) {
  return twitter.authCallback(request);
}
```

authorize関数を実行してください。
※GASのラインタイムバージョン(appsscript.json)がV8になっているとエラーが発生するという記事もあるが、今回は現時点では大丈夫でした。

他のエラーが出た場合は、「API Key」が最新状態であるのかや、記載の仕方に間違いがないか確認してみてください。


次にログを参照します。
下記のようなURLが表示されるので、アクセスしてください。
```
https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxxxxxx
```

承認の画面に遷移したら、承認を完了させます。成功すると「Success」と書かれた画面が表示されます。

#### 【エラーが出た場合】
2つの対処法を記載しておきます。

①認証の解除
実行する関数を「reset」にして実行を行ってください。
現在存在している認証情報をリセットできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/a970098f-1c59-08f1-e048-88893ce0c99e.png)

②API Keyの再登録
TwitterDeveloperの画面からAPI Keyの「Regenerate」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/f3030f42-dda2-61b8-ac0c-7e2a4f641c77.png)


### 【1部終わり】
これでGASとAPIの準備は完了になります。


# 【2部】
それでは、プログラムに移ります。

#### 【スプレッドシート内容】
スプレッドシート上にキーワード検索欄と検索ボタンを作成しました。

検索ボタンには、「searchTweets」スクリプトの割当をしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706435/91d896d8-0953-774d-92b5-d07ffa69e021.png)

#### 【プログラム】
Twitterアプリ認証とは別で新規ファイルを作成し、コピーをお願いします。

```
function searchTweets() {

  //検索キーワードを宣言
  var keyword = getValueOnSheet('B2');

  //APIでタイムラインツイートを取得
  var service  = twitter.getService();//TwitterWebServiceのインスタンス
  var json = service.fetch("https://api.twitter.com/1.1/search/tweets.json?q="+keyword+"&result_type=recent&count=100");
  var array = JSON.parse(json); //json形式で返ってくるのでパース
  var array = array.statuses; //テキストデータがstatusesの中に入っているので一度取り出しが必要（これをしないとmapが使えない）

  //filterでリツイートの除去を行う 
  var result = array.filter( function( value ) {
    //取得した情報のテキストデータに「RT @」があるものをデータから除去する
    return value.text.includes('RT @') == false;
  })

  const sheet = getSheet(); //対象のシートを取得
  clearCell(sheet); //現在のセルをクリアする
  
  //mapにて配列を整理しスプレッドシートへアウトプットを行う
  var tweets = result.map(function(tweet){
    const jstDate = formatDate(new Date(tweet.created_at), 'yyyy-MM-dd HH:mm:ss')
    const twe = [jstDate, tweet.text, tweet.user.name, tweet.user.screen_name, tweet.favorite_count, tweet.retweet_count];
    sheet.appendRow(twe);
    return twe;
  });
}

// スプレッドシートID
const bookId = '[スプレッドシートID]';

// 日付のフォーマット
const formatDate = (date, format) => {
  date.setDate(date.getDate());
  return Utilities.formatDate(date, 'JST', format);
}

// 指定セルをクリア
const clearCell = (sheet) => {
  const range = sheet.getRange('A6:Z1000');
  range.clearContent();
}

// 検索キーワードや取得件数を取得
const getValueOnSheet = (cellPosition) => {
  const sheet = getSheet();
  return sheet.getRange(cellPosition).getValue();
}

// 対象シートを取得
const getSheet = () => {
  return SpreadsheetApp.openById(bookId).getSheetByName('Twitter');
}
```

#### 【プログラム解説】

①8行目では、Keyword、取得条件、取得件数を宣言しています。

```
json = service.fetch("https://api.twitter.com/1.1/search/tweets.json?q="+keyword+"&result_type=recent&count=100")
```

他に取得する情報があるときは下記のサイトをご参考ください。
タイムライン取得時に指定可能なパラメータについてわかりやすい解説がのっていました。
https://munokuno.com/other/tips/parameters-for-timelines/

検索したいキーワードの文字列を指定する「q」という変数は必須になります。


②13行目のresultに入る値は、filterとincludesを組み合わせて使うことで、リツイートデータ('RT @')の除去をしております。

③22行目のmap関数で、にてデータ特定のデータのみの配列を作成して、出力しています。

今回は、日時、ツイート内容、ユーザ名、ユーザID、いいね数、リツイート数を抽出しました。

他の情報を出力する場合は下記をご参考ください。
https://syncer.jp/Web/API/Twitter/REST_API/Object/User/

# 【終わりに】
今回利用しているのはTwitterAPI v1.1でありv2とはレスポンス内容からサービスレベルも変わっているようです。また勉強します。

更に、100件以上のツイート取得可能になるよう工夫し完成したら記事にします。