import got from "got"; import FormData from "form-data"; import fileType from "file-type"; import { nanoid } from "nanoid"; import config from "../../config"; export interface Attachment { id: string; } export interface Status { url: string; } export const client = got.extend({ prefixUrl: config.mastodon.instance, headers: { Authorization: `Bearer ${config.mastodon.token}`, }, }); export async function upload(buf: Buffer, filename: string) { const type = await fileType.fromBuffer(buf); if (!type) { throw new Error("Couldn't determine file type"); } const body = new FormData(); body.append("file", buf, { filename: `${filename}.${type.ext}`, contentType: type.mime }); return client.post("api/v1/media", { body }).json(); } export async function createStatus( postUrl: string, sourceUrls: readonly string[], spoiler: string[], attachmentId: string ) { let lines = [postUrl]; for (let i = 0; i < sourceUrls.length; ++i) { const url = sourceUrls[i].replace(/(https?):\/\/twitter.com\//, "$1://nitter.net/"); lines.push(`Source ${i + 1}: ${url}`); } const spoilerText = spoiler.length ? `CW: ${spoiler.join(", ")}` : undefined; return client .post("api/v1/statuses", { headers: { "Idempotency-Key": nanoid(), }, json: { status: lines.join("\n"), media_ids: [attachmentId], sensitive: !!spoilerText, spoiler_text: spoilerText, visibility: "unlisted", }, }) .json(); }