現在React Native + Expo + Twitter APIで個人開発をしているのですが、Twitter APIに苦戦したので書きます。
コードは基本的にReact/React Native上で動くものになります。
#idが大きすぎる
Twitter APIでは一度で取得できるツイート数に制限があります。
import Client from '../hoge';
const getTweets = () => {
Client.get('favorites/list.json',{
count: 200, // 最大200まで
tweet_mode: 'extended',
})
};
なので、自動スクロールなどで追加取得する際にパラメーターにmax_idかsince_idを追加する必要があります。
import Client from '../hoge';
const getTweets = () => {
Client.get('favorites/list.json', {
count: 200,
max_id, // 追加
tweet_mode: 'extended',
})
};
この時、最後に取得したツイートのidをそのまま渡すと、渡されたID以下のツイートが取得されることになるので、最後のツイートが重複してしまいます。なので、idに-1をしてから渡さないといけません(古い順で取得してる時は+1)。
ここで問題が発生します。これは実際の自分のツイートのレスポンスです。
{
created_at: "Sat Feb 20 13:38:04 +0000 2021",
id: 1363120740321558500,
id_str: "1363120740321558529",
full_text: "明日中にアプリの申請絶対だすぞ",
...
}
number型のidとstring型のid_strが返ってくるのですが、number型の方は値が大きすぎて丸まっています。さすがTwitterです。
実際に計算をしてみても、結果は以下のようになります。
console.log(tweet.id, tweet.id - 1);
// 1363120740321558500 1363120740321558500
正確な値であるid_strの方を使うことになるのですが、文字列なので数値に変換しないといけません。しかしparseIntなどで変換しても上記の計算と同じ結果になってしまうので、Big Intとして計算しないといけません。
#解決策
簡易的なコードの例ですが、自分の解決策を載せます。bignumber.jsというライブラリを使用しました。
yarn add bignumber.js
import React, { useState } from "react";
import { BigNumber } from "bignumber.js";
import Client from '../hoge';
export const App = () => {
const [tweets,setTweets] = useState([]); // 既に取得しているツイートが入ります
...
const getMoreTweets = () => {
const max_id = new BigNumber(tweets.slice(-1)[0].id_str).minus(1).c?.join(''); // 最後に取得したツイートのidを-1
Client.get('favorites/list.json', {
count:200,
max_id,
tweet_mode: 'extended'
}).then((res:any) => setTweets([...tweets,...res]));
}
...
}