ツイッターの検索結果をウェブページに埋め込みたいとき、昔は公式のウィジェットがあったのですが、2018年に廃止されました。
でも、どうしても検索結果をウェブページに埋め込みたくて諸々調査した結果。
Next.js + Vercel + Twitter API で割と簡単に埋め込めそうでした。
ただし、
・最新100件まで
・過去7日まで
・15分間で180回の表示まで
という制約があるので、プロダクトとして使うには、どこかにキャッシュするなど、ひと工夫必要そうです。
僕の場合は検証のためにちょちょいと試したかっただけなので、下記の方法で実装しました。
手順
❷ .envに必要事項を記入する
アプリをつくると、consumer_key、consumer_secret、access_token_key、access_token_secretが手に入るので.envに記入しましょう。
consumer_key = 'XXXXXXXX' consumer_secret = 'XXXXXXXXj' access_token_key = 'XXXXXXXX' access_token_secret = 'XXXXXXXX'
❸ Next.jsでAPIをつくる
pages/api/tweets.ts
import Twitter from 'twitter'; import dotenv from 'dotenv'; dotenv.config(); const client = new Twitter({ consumer_key: process.env.consumer_key, consumer_secret: process.env.consumer_secret, access_token_key: process.env.access_token_key, access_token_secret: process.env.access_token_secret }); export default async (req, res) => { const { q } = req.query; if (!q) { return res.status(200).json([]); } const data = await (() => { return new Promise((resolve, reject) => { client.get('search/tweets', { q, count: 100 }, function(error, tweets, response) { resolve(tweets); }); }); })(); const statuses = (data as { statuses: { text: string; }[] }).statuses; const param : { text: string; }[] = []; if (statuses) { statuses.forEach((tweet) => { param.push({ text: tweet.text }); }); } return res.status(200).json(param); }
ざっくり書くとこんな感じです。
上記例ではツイート本文しか取得していませんが、本当はいろいろ取得できます。
❹ 表示用のページをつくる
pages/index.ts
import axios from 'axios'; import { useEffect, useState } from 'react'; export default function IndexPage() { const [tweets, setTweets ] = useState([]); useEffect(async () => { if (tweets.length) { return; } const q = '寿司'; const { data } = await axios.get(`/api/tweets?q=${ encodeURIComponent(q) }`); if (data.length) { setTweets(data); } }, [tweets]); return ( <ol>{ tweets.map((tweet, i) => { return ( <li key={ i }>{ tweet.text }</li> ) }) }</ol> ) }
ざっくり書くとこんな感じです。
上記例では「寿司」の検索結果を表示します。
❺ Vercelにデプロイ
Vercelにデプロイします。
その際に、.envの内容をEnvironment Variablesから登録しましょう。
vercel.com
手続きは以上となります。ちょっとした検証に使うのであればこれで充分な気がしました。