generated at
tweet2image-upload
/ci7lus/tweet2image-uploadの2022/5/3時点のコピペ
2023-09-15 使えなくなってた
https://tweet2image.vercel.app/ が利用できないため

script.js
/* https://scrapbox.io/ci7lus/tweet2image-upload */ /* MIT License Copyright (c) 2020 ci7lus */ /*const style = document.createElement("style"); style.innerText = `@import "https://scrapbox.io/api/code/ci7lus/tweet2image-upload/style.css";`; document.body.appendChild(style);*/ import { insertText } from "/api/code/customize/scrapbox-insert-text/script.js" cosense.PageMenu.addMenu({ title: "tweet2image", // image: "https://scrapbox.io/files/60e9891a6f8d0b0022457e87.svg", icon: "fab fa-twitter", onClick: async () => { if (!window.get_tweet_card) { alert("UserScriptが入ってなさそうです?") window.open("https://scrapbox.io/ci7lus/tweet2image-proxy", "blank") return } const text = prompt("ツイートのURLを入力してください") if (text === null) return const gyazoClientId = "e2bd725244baa768eb100126fa2cd85910445778a25ba7ef1328608750b070d5" const tweetcard = "https://tweet2image.vercel.app" const m = text.match(/(?:twitter|x).com\/(.+)\/status\/(\d+)/) if (!m) { alert("無効な形式のURLです") return } let imageData // 進捗表示エリア const progressArea = document.createElement("div") progressArea.style = "position: fixed; top: 0; right: 0; margin: 1rem; padding: 1rem; background: #FFF; color: 000; z-index: 9999;" progressArea.innerText = "ツイートの画像を取得中..." document.body.appendChild(progressArea) try { const req = await window.get_tweet_card(`${tweetcard}/${m[2]}.jpg`) if (req.status !== 200) { alert("Image fetch failed(!=200)") return } imageData = req.response } catch (e) { console.error(e) alert("ツイート画像の取得に失敗しました") document.body.removeChild(progressArea) return } const tweetUrl = `https://x.com/${m[1]}/status/${m[2]}` // upload to gyazo try { progressArea.innerText = "Gyazoをチェックしています" let token = window.gyazoOAuthToken if (!token) { const project = await fetch( `https://scrapbox.io/api/projects/${scrapbox.Project.name}` ) const { gyazoTeamsName } = await project.json() if (gyazoTeamsName) { alert( "Gyazo Teamsを使ったことがないのでアップロードがおかしくなるかもしれません(可能であればTwitter@ci7lusまで動作確認報告お願いします)" ) } const gyazoOAuthToken = await fetch( `https://scrapbox.io/api/login/gyazo/oauth-upload/token?gyazoTeamsName=${ gyazoTeamsName || "" }`, { headers: { accept: "application/json, text/plain, */*", }, method: "GET", } ) const tokenResult = await gyazoOAuthToken.json() token = tokenResult.token window.gyazoOAuthToken = token } if (token) { progressArea.innerText = "Gyazoにアップロードしています…(OAuth)" const formData = new FormData() formData.append("access_token", token) formData.append("referer_url", tweetUrl) formData.append("title", tweetUrl) formData.append("imagedata", imageData) const upload = await fetch("https://upload.gyazo.com/api/upload", { headers: { accept: "application/json, text/plain, */*", }, referrerPolicy: "same-origin", body: formData, method: "POST", mode: "cors", credentials: "omit", }) const { permalink_url } = await upload.json() console.log(`${tweetUrl} -> ${permalink_url}`) insertText({ text: `[${permalink_url} ${tweetUrl}]` }) } else { progressArea.innerText = "Gyazoにアップロードしています…(EasyAuth)" const imageB64Data = await new Promise((res, rej) => { const reader = new FileReader() reader.onerror = rej reader.onload = () => { res(reader.result) } reader.readAsDataURL(imageData) }) const formData = new FormData() formData.append("client_id", gyazoClientId) formData.append("referer_url", tweetUrl) formData.append("imagedata", imageB64Data) const easyAuth = await fetch( `https://upload.gyazo.com/api/upload/easy_auth`, { method: "POST", mode: "cors", credentials: "include", body: formData, } ) const uploadResult = await easyAuth.json() const getImage = await fetch(uploadResult.get_image_url, { mode: "cors", credentials: "include", }) progressArea.innerText = "done!" console.log(`${tweetUrl} -> ${getImage.url}`) insertText({ text: `[${getImage.url} ${tweetUrl}]` }) } } catch (e) { console.error(e) alert("アップロードに失敗しました…") } finally { document.body.removeChild(progressArea) } }, })

style.css
a#tweet2image.tool-btn:hover { text-decoration: none; } a#tweet2image.tool-btn::before { position: absolute; left: calc(46px / 3 - 1px); content: "\f099"; font: 21px/46px "Font Awesome 5 Free"; font-weight: 900; }