diff --git a/deps/scrapbox.ts b/deps/scrapbox.ts index 0997c25..3bea20e 100644 --- a/deps/scrapbox.ts +++ b/deps/scrapbox.ts @@ -1,8 +1,10 @@ export type { + BadRequestError, ErrorLike, ExportedData, GuestUser, ImportedData, + InvalidURLError, MemberProject, MemberUser, NotFoundError, @@ -14,7 +16,9 @@ export type { PageList, Scrapbox, SearchedTitle, -} from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts"; -import type { Page } from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts"; + SessionError, + TweetInfo, +} from "https://raw.githubusercontent.com/scrapbox-jp/types/0.1.2/mod.ts"; +import type { Page } from "https://raw.githubusercontent.com/scrapbox-jp/types/0.1.2/mod.ts"; export * from "https://esm.sh/@progfay/scrapbox-parser@7.2.0"; export type Line = Page["lines"][0]; diff --git a/rest/getTweetInfo.ts b/rest/getTweetInfo.ts new file mode 100644 index 0000000..fe9c754 --- /dev/null +++ b/rest/getTweetInfo.ts @@ -0,0 +1,76 @@ +import type { + BadRequestError, + InvalidURLError, + SessionError, + TweetInfo, +} from "../deps/scrapbox.ts"; +import { cookie, getCSRFToken } from "./auth.ts"; +import { UnexpectedResponseError } from "./error.ts"; +import { tryToErrorLike } from "../is.ts"; +import { ExtendedOptions, Result, setDefaults } from "./util.ts"; + +/** 指定したTweetの情報を取得する + * + * @param url 取得したいTweetのURL + * @param init connect.sidなど + * @return tweetの中身とか + */ +export const getTweetInfo = async ( + url: string | URL, + init?: ExtendedOptions, +): Promise< + Result< + TweetInfo, + | SessionError + | InvalidURLError + | BadRequestError + > +> => { + const { sid, hostName, fetch, csrf } = setDefaults(init ?? {}); + const path = `https://${hostName}/api/embed-text/twitter?url=${ + encodeURIComponent(url.toString()) + }`; + + const res = await fetch( + path, + { + method: "POST", + headers: { + "Content-Type": "application/json;charset=utf-8", + "X-CSRF-TOKEN": csrf ?? await getCSRFToken(init), + ...(sid ? { Cookie: cookie(sid) } : {}), + }, + body: JSON.stringify({ timeout: 3000 }), + }, + ); + + if (!res.ok) { + if (res.status === 422) { + return { + ok: false, + value: { + name: "InvalidURLError", + message: (await res.json()).message as string, + }, + }; + } + const text = await res.json(); + const value = tryToErrorLike(text); + if (!value) { + throw new UnexpectedResponseError({ + path: new URL(path), + ...res, + body: await res.text(), + }); + } + return { + ok: false, + value: value as + | SessionError + | BadRequestError, + }; + } + + const tweet = (await res.json()) as TweetInfo; + return { ok: true, value: tweet }; +}; diff --git a/rest/getWebPageTitle.ts b/rest/getWebPageTitle.ts new file mode 100644 index 0000000..b3388b2 --- /dev/null +++ b/rest/getWebPageTitle.ts @@ -0,0 +1,75 @@ +import type { + BadRequestError, + InvalidURLError, + SessionError, +} from "../deps/scrapbox.ts"; +import { cookie, getCSRFToken } from "./auth.ts"; +import { UnexpectedResponseError } from "./error.ts"; +import { tryToErrorLike } from "../is.ts"; +import { ExtendedOptions, Result, setDefaults } from "./util.ts"; + +/** 指定したURLのweb pageのtitleをscrapboxのserver経由で取得する + * + * @param url 取得したいURL + * @param init connect.sidなど + * @return web pageのtilte + */ +export const getWebPageTitle = async ( + url: string | URL, + init?: ExtendedOptions, +): Promise< + Result< + string, + | SessionError + | InvalidURLError + | BadRequestError + > +> => { + const { sid, hostName, fetch, csrf } = setDefaults(init ?? {}); + const path = `https://${hostName}/api/embed-text/url?url=${ + encodeURIComponent(url.toString()) + }`; + + const res = await fetch( + path, + { + method: "POST", + headers: { + "Content-Type": "application/json;charset=utf-8", + "X-CSRF-TOKEN": csrf ?? await getCSRFToken(init), + ...(sid ? { Cookie: cookie(sid) } : {}), + }, + body: JSON.stringify({ timeout: 3000 }), + }, + ); + + if (!res.ok) { + if (res.status === 422) { + return { + ok: false, + value: { + name: "InvalidURLError", + message: (await res.json()).message as string, + }, + }; + } + const text = await res.json(); + const value = tryToErrorLike(text); + if (!value) { + throw new UnexpectedResponseError({ + path: new URL(path), + ...res, + body: await res.text(), + }); + } + return { + ok: false, + value: value as + | SessionError + | BadRequestError, + }; + } + + const { title } = (await res.json()) as { title: string }; + return { ok: true, value: title }; +};