diff --git a/packages/@liexp/backend/src/providers/tg/tg.provider.ts b/packages/@liexp/backend/src/providers/tg/tg.provider.ts index de58151fc0..f7a7fd3d9a 100644 --- a/packages/@liexp/backend/src/providers/tg/tg.provider.ts +++ b/packages/@liexp/backend/src/providers/tg/tg.provider.ts @@ -10,16 +10,16 @@ export interface TGBotProvider { upsertPinnedMessage: ( text: string, ) => TE.TaskEither; - post: (text: string) => TE.TaskEither; + post: (text: string, replyToMessageId?: number) => TE.TaskEither; postPhoto: ( imageUrl: string | Stream, caption: string, - ) => TE.TaskEither; + ) => TE.TaskEither; postVideo: ( videoUrl: string | Stream, caption: string, opts?: TelegramBot.SendVideoOptions, - ) => TE.TaskEither; + ) => TE.TaskEither; postMediaGroup: ( text: string, media: readonly TelegramBot.InputMedia[], @@ -99,9 +99,10 @@ export const TGBotProvider = ( }), ); }, - post: (text) => { + post: (text, replyToMessageId) => { return liftTGTE(() => api.sendMessage(opts.chat, text, { + reply_to_message_id: replyToMessageId, parse_mode: "HTML", disable_web_page_preview: false, }), diff --git a/services/api/src/flows/events/postToTG.flow.ts b/services/api/src/flows/events/postToTG.flow.ts index 7505973554..4d1f2d1a68 100644 --- a/services/api/src/flows/events/postToTG.flow.ts +++ b/services/api/src/flows/events/postToTG.flow.ts @@ -1,14 +1,14 @@ import { type Stream } from "stream"; import { fp, pipe } from "@liexp/core/lib/fp"; import { - type SocialPostBodyMultipleMedia, SocialPostPhoto, SocialPostVideo, type CreateSocialPost, + type SocialPostBodyMultipleMedia, } from "@liexp/shared/lib/io/http/SocialPost"; import * as t from "io-ts"; import { type UUID } from "io-ts-types/lib/UUID"; -import { type EventV2Entity } from "@entities/Event.v2.entity"; +import type TelegramBot from "node-telegram-bot-api"; import { type Flow, type TEFlow } from "@flows/flow.types"; import { ServerError } from "@io/ControllerError"; @@ -64,7 +64,25 @@ const writeText: Flow<[CreateSocialPost], string> = (ctx) => (body) => { ].join("\n"); }; -export const postToTG: TEFlow<[UUID, CreateSocialPost], EventV2Entity> = +const getMessageTexts = ( + post: CreateSocialPost, + text: string +): { mediaText: string; messageText: string; useReply: boolean } => { + if (text.length > 300) { + return { + mediaText: post.title, + messageText: text, + useReply: true, + }; + } + return { + mediaText: text, + messageText: text, + useReply: false, + }; +}; + +export const postToTG: TEFlow<[UUID, CreateSocialPost], TelegramBot.Message> = (ctx) => (id, body) => { return pipe( writeText(ctx)(body), @@ -75,6 +93,8 @@ export const postToTG: TEFlow<[UUID, CreateSocialPost], EventV2Entity> = ? [{ type: "photo", media: body.media }] : body.media; + const { mediaText, messageText, useReply } = getMessageTexts(body, text); + return pipe( media, fp.TE.right, @@ -82,7 +102,7 @@ export const postToTG: TEFlow<[UUID, CreateSocialPost], EventV2Entity> = if (media.length === 1) { const m = media[0]; if (SocialPostPhoto.is(m)) { - return ctx.tg.postPhoto(m.media, text); + return ctx.tg.postPhoto(m.media, mediaText); } if (SocialPostVideo.is(m)) { return pipe( @@ -90,15 +110,20 @@ export const postToTG: TEFlow<[UUID, CreateSocialPost], EventV2Entity> = responseType: "stream", }), fp.TE.chain((stream) => - ctx.tg.postVideo(stream, text, { + ctx.tg.postVideo(stream, mediaText, { duration: m.duration, }), ), ); } } - return ctx.tg.postMediaGroup(text, media); + return ctx.tg.postMediaGroup(mediaText, media); }), + fp.TE.chain((message) => + useReply + ? ctx.tg.post(messageText, message.message_id) + : fp.TE.right(message), + ), ); }), fp.TE.mapLeft((e) => ServerError([e.message])), diff --git a/services/api/src/routes/social-posts/createSocialPost.controller.ts b/services/api/src/routes/social-posts/createSocialPost.controller.ts index 936362eb1d..02ccda1bd0 100644 --- a/services/api/src/routes/social-posts/createSocialPost.controller.ts +++ b/services/api/src/routes/social-posts/createSocialPost.controller.ts @@ -45,9 +45,6 @@ export const MakeCreateSocialPostRoute: Route = (r, ctx) => { ? postToTG(ctx)(id, { ...p.content, platforms }) : TE.right(undefined), }), - ctx.logger.info.logInTaskEither( - `Posting ${id} with caption %O`, - ), TE.chain((result) => ctx.db.save(SocialPostEntity, [ { diff --git a/services/api/src/routes/social-posts/publishSocialPost.controller.ts b/services/api/src/routes/social-posts/publishSocialPost.controller.ts index 3c15dda023..a6320af497 100644 --- a/services/api/src/routes/social-posts/publishSocialPost.controller.ts +++ b/services/api/src/routes/social-posts/publishSocialPost.controller.ts @@ -15,7 +15,7 @@ export const MakePublishSocialPostRoute: Route = (r, ctx) => { }, }), TE.chain((p) => postToTG(ctx)(id, { ...p.content })), - ctx.logger.info.logInTaskEither(`Posting ${id} with caption %O`), + ctx.logger.info.logInTaskEither((r) => [`Posting ${id} with caption %O`, r.text]), TE.chain((result) => ctx.db.save(SocialPostEntity, [ {