import { reader, readerTaskEither as rte, readonlyArray, taskEither, } from "fp-ts"; import { flow, pipe } from "fp-ts/lib/function.js"; // parseJsonCont :: string -> string -> TaskEither string string const parseJsonCont = (attr) => (source) => { try { const data = JSON.parse(source)[attr]; if (!data) throw new Error(`Key '${attr}' doesn't exist`); return taskEither.right(data); } catch (e) { return taskEither.left(`Invalid json data: ${e}`); } }; const YANDEX_GPT_API_URL = "https://300.ya.ru/api/sharing-url"; // getYandexGptSharedUrl :: // string -> // ReaderTaskEither {yandexGptApiToken} string string const getYandexGptSharedUrl = (articleUrl) => pipe( reader.ask(), reader.map(({ yandexGptApiToken }) => pipe( taskEither.tryCatch( () => fetch(YANDEX_GPT_API_URL, { method: "POST", headers: new Headers({ "Content-Type": "application/json", "Authorization": `OAuth ${yandexGptApiToken}`, }), body: JSON.stringify({ article_url: articleUrl }), }), String, ), /* TODO: fix to many requests error { ok: false, error_code: 429, description: 'Too Many Requests: retry after 5', parameters: { retry_after: 5 } } */ taskEither.flatMap((res) => taskEither.tryCatch(() => res.json(), String) ), taskEither.flatMap((data) => data.status === "success" && data.sharing_url ? taskEither.right(data.sharing_url) : taskEither.left(`Invalid response: ${JSON.stringify(data)}`) ), ) ), ); // getYandexGptTesisesFromSharedUrl :: string -> TaskEither string[] string const getYandexGptTesisesFromSharedUrl = (sharingUrl) => pipe( taskEither.tryCatch(() => fetch(sharingUrl), String), taskEither.flatMap((res) => taskEither.tryCatch(() => res.text(), String)), taskEither.flatMap((html) => taskEither.fromNullable("Cannot find data in the shared url")( /([\s\S]+?)<\/script>/.exec( html, )[1], ) ), taskEither.flatMap(parseJsonCont("body")), taskEither.flatMap(parseJsonCont("thesis")), taskEither.map(readonlyArray.map((t) => t.content)), ); // describeArticle :: // string -> // ReaderTaskEither {yandexGptApiToken} string string export const describeArticle = flow( getYandexGptSharedUrl, rte.flatMapTaskEither(getYandexGptTesisesFromSharedUrl), );