diff --git a/src/data/data.module.ts b/src/data/data.module.ts index 59b1b45..aebd0f2 100644 --- a/src/data/data.module.ts +++ b/src/data/data.module.ts @@ -2,11 +2,10 @@ import { Global, Module } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { MongooseModule, SchemaFactory } from '@nestjs/mongoose'; import { Community } from './community.entity'; -import { Message } from './message.entity'; -import { User } from './user.entity'; -import { Referral } from './referral.entity'; import { CommunityUser, CommunityUserSchema } from './communityUser.entity'; import { CommunityUserHistory, CommunityUserHistorySchema } from './communityUserHistory.entity'; +import { Message } from './message.entity'; +import { Referral } from './referral.entity'; import { Reward, RewardSchema } from './reward.entity'; import { TempImage, TempImageSchema } from './tempImage.entity'; @@ -38,10 +37,6 @@ import { TempImage, TempImageSchema } from './tempImage.entity'; name: Message.name, schema: SchemaFactory.createForClass(Message), }, - { - name: User.name, - schema: SchemaFactory.createForClass(User), - }, { name: Referral.name, schema: SchemaFactory.createForClass(Referral), diff --git a/src/data/message.entity.ts b/src/data/message.entity.ts index 65b7947..a5d6196 100644 --- a/src/data/message.entity.ts +++ b/src/data/message.entity.ts @@ -1,39 +1,22 @@ import { Prop, Schema } from '@nestjs/mongoose'; -export class Reaction { - @Prop() - userId?: number; - - @Prop() - emoji: string; - - @Prop() - type: string; -} - @Schema() export class Message { @Prop() chatId: number; @Prop() - messageId: number; - - @Prop() - creatorUserId: number; + forwardedFromChatId?: number; @Prop() - creatorUserName: string; + messageId: number; @Prop() - creatorFirstName: string; + creatorUserId: number; @Prop({ default: 0 }) points: number; - @Prop({ default: [] }) - reactions!: Reaction[]; - @Prop({ default: 0 }) totalReactionsForMsg: number; } diff --git a/src/data/user.entity.ts b/src/data/user.entity.ts deleted file mode 100644 index 3ac0a6c..0000000 --- a/src/data/user.entity.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Prop, Schema } from '@nestjs/mongoose'; - -@Schema() -export class User { - @Prop() - userId: number; - - @Prop() - points: number; -} diff --git a/src/telegram/messageHandler.service.ts b/src/telegram/messageHandler.service.ts index 28a4172..26738e6 100644 --- a/src/telegram/messageHandler.service.ts +++ b/src/telegram/messageHandler.service.ts @@ -17,45 +17,51 @@ export class MessageHandlerService { private readonly communityUserService: CommunityUserService, ) {} - async handle(update: NarrowedContext, Update.MessageUpdate>) { - this.logger.log(update.update); - if (update.update.message.hasOwnProperty('migrate_to_chat_id')) { - const newChatId = (update.update.message as any).migrate_to_chat_id; - const oldChatId = update.update.message.chat.id; + async handle(ctx: NarrowedContext, Update.MessageUpdate>) { + this.logger.log(ctx.update); + if (ctx.update.message.hasOwnProperty('migrate_to_chat_id')) { + const newChatId = (ctx.update.message as any).migrate_to_chat_id; + const oldChatId = ctx.update.message.chat.id; this.logger.log(`We are going to update community id from ${oldChatId} to ${newChatId}`); if (newChatId !== undefined && oldChatId !== undefined) { this.communityService.updateCommunityId(oldChatId, newChatId); this.communityUserService.updateCommunityUserId(oldChatId, newChatId); } return; - } else if (update.update.message.hasOwnProperty('group_chat_created')) { + } else if (ctx.update.message.hasOwnProperty('group_chat_created')) { // When user first time creates a chat with bot, the bot will recieve message with group_chat_created: true, property. // But in this case we will try to add user also by my_chat_member event. Because of it we may face race condition // This condition used to prevent this case of race condition this.logger.log('Received group chat created message'); return; - } else if (update.update.message.hasOwnProperty('migrate_from_chat_id')) { + } else if (ctx.update.message.hasOwnProperty('migrate_from_chat_id')) { // It could be also the case for race condition this.logger.log('Recieved migrate_from_chat_id message'); return; - } else if (update.update.message.hasOwnProperty('new_chat_participant')) { + } else if (ctx.update.message.hasOwnProperty('new_chat_participant')) { // Presumably this kind of message is causing race condition and two records using findOneAndUpdate and updateOne with upsert are created this.logger.log('Recieve new_chat_participant message'); return; - } else if (update.chat.type === 'private') { + } else if (ctx.chat.type === 'private') { this.logger.log('Skipping processing because chat type is private'); return; } + let forwardedFromChatId; + if (ctx.update.message.hasOwnProperty('reply_to_message')) { + const anyMessage = ctx.update.message as any; + forwardedFromChatId = anyMessage?.reply_to_message?.forward_from_chat?.id; + } + this.logger.log(`The sender chat is ${ctx.update.message.sender_chat} forwarded ${forwardedFromChatId}`); + const message = await this.msgModel.create({ - chatId: update.message.chat.id, - messageId: update.message.message_id, - creatorUserId: update.message.from.id, - creatorUserName: update.message.from.username, - creatorFirstName: update.message.from.first_name, + chatId: ctx.message.chat.id, + forwardedFromChatId: forwardedFromChatId, + messageId: ctx.message.message_id, + creatorUserId: ctx.message.from.id, }); - this.communityService.increaseMessageCounter(update.message.chat.id); - this.createCommunityUserIfNotExist(update.message.from.id, update.message.chat.id, update.telegram); + this.communityService.increaseMessageCounter(ctx.message.chat.id); + this.createCommunityUserIfNotExist(ctx.message.from.id, ctx.message.chat.id, ctx.telegram); this.logger.log('Message in DB:', JSON.stringify(message)); } diff --git a/src/telegram/reactionHandler.service.ts b/src/telegram/reactionHandler.service.ts index 578376f..1cca8e6 100644 --- a/src/telegram/reactionHandler.service.ts +++ b/src/telegram/reactionHandler.service.ts @@ -6,7 +6,8 @@ import { Community } from 'src/data/community.entity'; import { CommunityUser } from 'src/data/communityUser.entity'; import { CommunityUserHistory, MessageReactionData } from 'src/data/communityUserHistory.entity'; import { Message } from 'src/data/message.entity'; -import { MessageReactionUpdated } from 'telegraf/typings/core/types/typegram'; +import { Context, NarrowedContext } from 'telegraf'; +import { Update } from 'telegraf/typings/core/types/typegram'; import { inspect } from 'util'; @Injectable() @@ -21,7 +22,9 @@ export class ReactionHandlerService { private readonly communityService: CommunityService, ) {} - async handle(messageReaction: MessageReactionUpdated) { + async handle(ctx: NarrowedContext, Update.MessageReactionUpdate>) { + this.logger.log(ctx.update); + const messageReaction = ctx.messageReaction; const message = await this.messageModel.findOneAndUpdate( { chatId: messageReaction.chat.id, @@ -31,22 +34,6 @@ export class ReactionHandlerService { $inc: { totalReactionsForMsg: messageReaction.new_reaction.length - messageReaction.old_reaction.length, }, - // ToDo: either remove or replace with 2 DB calls - // It stores all reactions that user set for the message - /* - $push: { - reactions: messageReaction.new_reaction.map((reactionType) => ({ - ...reactionType, - userId: messageReaction.user?.id, - })), - }, - $pull: { - reactions: messageReaction.old_reaction.map((reactionType) => ({ - ...reactionType, - userId: messageReaction.user?.id, - })), - }, - */ }, { new: true, @@ -66,9 +53,9 @@ export class ReactionHandlerService { async makeReward(message: Message & { _id: Types.ObjectId }) { let triggers; - + const targetChatId = message.forwardedFromChatId ?? message.chatId; try { - triggers = (await this.communityModel.findOne({ chatId: message.chatId }, { triggers: 1 }))?.triggers; + triggers = (await this.communityModel.findOne({ chatId: targetChatId }, { triggers: 1 }))?.triggers; } catch (err) { this.logger.error(err); } @@ -99,7 +86,7 @@ export class ReactionHandlerService { let communityUser; try { communityUser = await this.communityUserModel.findOneAndUpdate( - { chatId: message.chatId, userId: message.creatorUserId }, + { chatId: targetChatId, userId: message.creatorUserId }, { $inc: { points: triggers.reaction.points } }, ); } catch (error) { @@ -110,7 +97,7 @@ export class ReactionHandlerService { try { await this.communityUserHistoryModel.create({ communityUserId: communityUser._id, - data: new MessageReactionData(message._id, message.chatId, triggers.reaction.points), + data: new MessageReactionData(message._id, targetChatId, triggers.reaction.points), }); } catch (error) { this.logger.error('Error while adding userHistory record', error); diff --git a/src/telegram/telegram.service.ts b/src/telegram/telegram.service.ts index 164f7de..2b4266b 100644 --- a/src/telegram/telegram.service.ts +++ b/src/telegram/telegram.service.ts @@ -19,9 +19,9 @@ export class TelegramService { } registerMessageReactionHandler(reactionHandlerService: ReactionHandlerService) { - this.bot.on('message_reaction', async (update) => { + this.bot.on('message_reaction', async (ctx) => { try { - await reactionHandlerService.handle(update.messageReaction); + await reactionHandlerService.handle(ctx); } catch (error) { this.logger.error('Error while reaction', error); }