📝
Twitterの埋め込みツイート取得API叩いてみる
Twitterのツイート埋め込みHTML取得の仕様について
endpoint
https://publish.twitter.com/oembed?url={url}&partner=&hide_thread=false
公開されていて、特に制限がなさそう(?)
→叩いてみる
% curl "https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FTwitterJP%2Fstatus%2F1587301348604841987&partner=&hide_thread=false" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1181 100 1181 0 0 7249 0 --:--:-- --:--:-- --:--:-- 7474
{
"url": "https://twitter.com/TwitterJP/status/1587301348604841987",
"author_name": "Twitter Japan",
"author_url": "https://twitter.com/TwitterJP",
"html": "<blockquote class=\"twitter-tweet\"><p lang=\"ja\" dir=\"ltr\">ジブリさん (<a href=\"https://twitter.com/JP_GHIBLI?ref_src=twsrc%5Etfw\">@JP_GHIBLI</a>) に書き下ろしていただいたヘッダーを、ジブリパークのオープンを記念して、みなさんにも使っていただけることになりました🤩<br><br>常識の範囲内でつかって下さい。 <a href=\"https://t.co/HQ94KU3YAI\">pic.twitter.com/HQ94KU3YAI</a></p>— Twitter Japan (@TwitterJP) <a href=\"https://twitter.com/TwitterJP/status/1587301348604841987?ref_src=twsrc%5Etfw\">November 1, 2022</a></blockquote>\n<script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\n",
"width": 550,
"height": null,
"type": "rich",
"cache_age": "3153600000",
"provider_name": "Twitter",
"provider_url": "https://twitter.com",
"version": "1.0"
}
- input(query param)
- url
- TweetのURLをエンコードした値
- url
- output(json)
- author_name
- author_url
- html
- これを使ってみる
- cache_age
- height
- width
- provider_name
- provider_url
- type
- url
- version
Next.jsのページに組み込んでHTMLを取得して表示までやる
src/pages/test/index.tsx
import { useState } from "react";
import parse from "html-react-parser";
const TestIndex = () => {
const [url, setUrl] = useState("");
const [tweetHTML, setTweetHTML] = useState("");
const handleURLChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setUrl(e.target.value);
}
const submit = async (url: string) => {
const res = await fetch("/api/test", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ url: url }),
});
setTweetHTML((await res.json()).response.html);
// ツイート表示用のスクリプトを追加
const head = document.getElementsByTagName("head")[0] as HTMLElement;
const script = document.createElement("script");
script.src = "https://platform.twitter.com/widgets.js";
script.async = true;
script.type = "text/javascript";
head.appendChild(script);
}
return (
<>
<h2>Tweet 埋め込みHTML 取得ページ</h2>
<input type="text" value={url} onChange={handleURLChange} />
<button onClick={() => submit(url)}>submit</button>
<div>{parse(tweetHTML)}</div>
</>
);
};
export default TestIndex;
src/pages/api/test/index.ts
import fetch from "node-fetch";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
res.status(405).json({ message: "Method Not Allowed" });
return;
}
if (req.body == null) {
res.status(405).json({ message: "Bad Request" });
}
const tweetURL: string = req.body.url;
const publishTwitterAPIURL = `https://publish.twitter.com/oembed?url=`;
const param = `&partner=&hide_thread=false`;
const endpoint = publishTwitterAPIURL + encodeURIComponent(tweetURL) + param;
const response = await fetch(endpoint);
const resData = (await response.json());
res.status(200).json({ response: resData });
}
注意
レスポンスのHTMLをそのままparse(html)
しても正しく描画されない。以下のようにTwitterのスクリプトを非同期に読み込む必要があった
さいごに
特定用途にツイートのURLを大量に保存しておいて、表示させたいときに使えそう(?)
Discussion