node-fetchやtwitterモジュールの説明は割愛して、ハマったポイントのみ。
結論
こんな感じでうまくいった。
const twitter = require("twitter")
const fetch = require("node-fetch")
class FetchImgAndTweet{
static async tweet(text, url, tokenKey, tokenSecret) {
const client = new twitter({
consumer_key: "XXX",
consumer_secret: "XXX",
access_token_key: tokenKey,
access_token_secret: tokenSecret,
})
const imgData = await FetchImgAndTweet.fetchImg(url)
const imgId = await FetchImgAndTweet.uploadImg(client, imgData)
await FetchImgAndTweet.update(client, text, imgId)
}
static async fetchImg(url) {
const res = await fetch(url) //画像が返ってくる
if (!res.ok) throw new Error("画像が正常に取得できませんでした")
const blob = await res.arrayBuffer()
return Buffer.from(blob)
}
static async uploadImg(client, img) {
const media = await client.post("media/upload", { media: img })
return media.media_id_string
}
static async update(client, text, imgId) {
const status = { status: text, media_ids: imgId }
const res = await client.post("statuses/update", status)
return true
}
}
はまりポイント
画像のデータ形式がblobやarrayBufferだとうまくいかない。fetchしてきた画像をres.arrayBuffer()でarrayBufferに変換し、更にBuffer.from()でBufferに変換する。これをしないとtwitterモジュールくんがヘソを曲げて大変だった。
↧