feat: add permanent option context var (unit tests fail)

This commit is contained in:
medtaher 2024-09-23 00:27:15 +01:00
parent 7115426432
commit 6e8a2a3d48
4 changed files with 50 additions and 3 deletions

View File

@ -28,6 +28,12 @@ export class ContextVar extends BaseSchema {
match: /^[a-z_0-9]+$/, match: /^[a-z_0-9]+$/,
}) })
name: string; name: string;
@Prop({
type: Boolean,
default: false,
})
permanent?: boolean;
} }
export const ContextVarModel: ModelDefinition = { export const ContextVarModel: ModelDefinition = {

View File

@ -19,6 +19,7 @@ import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Label } from './label.schema'; import { Label } from './label.schema';
import { ChannelData } from './types/channel'; import { ChannelData } from './types/channel';
import { SubscriberContext } from './types/subscriberContext';
@Schema({ timestamps: true }) @Schema({ timestamps: true })
export class SubscriberStub extends BaseSchema { export class SubscriberStub extends BaseSchema {
@ -107,6 +108,12 @@ export class SubscriberStub extends BaseSchema {
default: null, default: null,
}) })
avatar?: unknown; avatar?: unknown;
@Prop({
type: Object,
default: { vars: {} }, //TODO: add this to the migration
})
context?: SubscriberContext;
} }
@Schema({ timestamps: true }) @Schema({ timestamps: true })

View File

@ -0,0 +1,3 @@
export interface SubscriberContext {
[key: string]: any;
}

View File

@ -7,16 +7,19 @@
* 3. SaaS Restriction: This software, or any derivative of it, may not be used to offer a competing product or service (SaaS) without prior written consent from Hexastack. Offering the software as a service or using it in a commercial cloud environment without express permission is strictly prohibited. * 3. SaaS Restriction: This software, or any derivative of it, may not be used to offer a competing product or service (SaaS) without prior written consent from Hexastack. Offering the software as a service or using it in a commercial cloud environment without express permission is strictly prohibited.
*/ */
import { Injectable } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { FilterQuery } from 'mongoose'; import { FilterQuery } from 'mongoose';
import EventWrapper from '@/channel/lib/EventWrapper'; import EventWrapper from '@/channel/lib/EventWrapper';
import { LoggerService } from '@/logger/logger.service'; import { LoggerService } from '@/logger/logger.service';
import { BaseService } from '@/utils/generics/base-service'; import { BaseService } from '@/utils/generics/base-service';
import { ContextVarService } from './context-var.service';
import { SubscriberService } from './subscriber.service';
import { VIEW_MORE_PAYLOAD } from '../helpers/constants'; import { VIEW_MORE_PAYLOAD } from '../helpers/constants';
import { ConversationRepository } from '../repositories/conversation.repository'; import { ConversationRepository } from '../repositories/conversation.repository';
import { Block, BlockFull } from '../schemas/block.schema'; import { Block, BlockFull } from '../schemas/block.schema';
import { ContextVar } from '../schemas/context-var.schema';
import { import {
Conversation, Conversation,
ConversationFull, ConversationFull,
@ -34,6 +37,8 @@ export class ConversationService extends BaseService<
constructor( constructor(
readonly repository: ConversationRepository, readonly repository: ConversationRepository,
private readonly logger: LoggerService, private readonly logger: LoggerService,
private readonly contextVarService: ContextVarService,
private readonly subscriberService: SubscriberService,
) { ) {
super(repository); super(repository);
} }
@ -79,6 +84,7 @@ export class ConversationService extends BaseService<
captureVars: boolean = false, captureVars: boolean = false,
) { ) {
const msgType = event.getMessageType(); const msgType = event.getMessageType();
const profile = event.getSender();
// Capture channel specific context data // Capture channel specific context data
convo.context.channel = event.getHandler().getChannel(); convo.context.channel = event.getHandler().getChannel();
convo.context.text = event.getText(); convo.context.text = event.getText();
@ -86,6 +92,18 @@ export class ConversationService extends BaseService<
convo.context.nlp = event.getNLP(); convo.context.nlp = event.getNLP();
convo.context.vars = convo.context.vars || {}; convo.context.vars = convo.context.vars || {};
const contextVars = (
await this.contextVarService.find({
name: { $in: next.capture_vars.map((c) => c.context_var) },
})
).reduce(
(acc, cv) => {
acc[cv.name] = cv;
return acc;
},
{} as Record<string, ContextVar>,
);
// Capture user entry in context vars // Capture user entry in context vars
if (captureVars && next.capture_vars && next.capture_vars.length > 0) { if (captureVars && next.capture_vars && next.capture_vars.length > 0) {
next.capture_vars.forEach((capture) => { next.capture_vars.forEach((capture) => {
@ -121,12 +139,18 @@ export class ConversationService extends BaseService<
contextValue = contextValue =
typeof contextValue === 'string' ? contextValue.trim() : contextValue; typeof contextValue === 'string' ? contextValue.trim() : contextValue;
convo.context.vars[capture.context_var] = contextValue; if (contextVars[capture.context_var]?.permanent) {
Logger.debug(
`Adding context var to subscriber: ${capture.context_var} = ${contextValue}`,
);
profile.context.vars[capture.context_var] = contextValue;
} else {
convo.context.vars[capture.context_var] = contextValue;
}
}); });
} }
// Store user infos // Store user infos
const profile = event.getSender();
if (profile) { if (profile) {
// @ts-expect-error : id needs to remain readonly // @ts-expect-error : id needs to remain readonly
convo.context.user.id = profile.id; convo.context.user.id = profile.id;
@ -182,6 +206,13 @@ export class ConversationService extends BaseService<
'Conversation Model : No conversation has been updated', 'Conversation Model : No conversation has been updated',
); );
} }
//TODO: add check if nothing changed don't update
this.subscriberService.updateOne(convo.sender, {
context: profile.context,
});
return updatedConversation; return updatedConversation;
} catch (err) { } catch (err) {
this.logger.error('Conversation Model : Unable to store context', err); this.logger.error('Conversation Model : Unable to store context', err);