import { number, option, ord, readonlyArray } from "fp-ts"; import { flow, pipe } from "fp-ts/lib/function.js"; const RE_URL = /(http|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/; // getMessageUrl :: Message -> Option const getMessageUrl = (msg) => option.fromNullable(RE_URL.exec(msg.text)?.[0]); // getMessageEntities :: Message -> ReadonlyArray const getMessageEntities = (msg) => msg.entities ?? readonlyArray.empty; // isTextLink :: MessageEntity -> boolean const isTextLink = (msgEntity) => msgEntity.type === "text_link"; const ordStringLength = pipe( number.Ord, ord.contramap((s) => s.length), ); // getTextLink :: Message -> Option const getTextLink = flow( getMessageEntities, readonlyArray.filterMap( flow(option.fromPredicate(isTextLink), option.map((link) => link.url)), ), readonlyArray.sort(ordStringLength), readonlyArray.last, ); export const extractMessageLink = (msg) => pipe( getTextLink(msg), option.orElse(() => getMessageUrl(msg)), );