mirror of
https://github.com/hexastack/hexabot
synced 2024-11-24 04:53:41 +00:00
feat: add permanent option context var (unit tests fail)
This commit is contained in:
parent
7115426432
commit
6e8a2a3d48
@ -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 = {
|
||||||
|
@ -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 })
|
||||||
|
3
api/src/chat/schemas/types/subscriberContext.ts
Normal file
3
api/src/chat/schemas/types/subscriberContext.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface SubscriberContext {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user