import * as client from '@botpress/client'; import * as bot from '../../bot'; import * as workflowProxy from '../../bot/workflow-proxy'; import * as utils from '../../utils/type-utils'; import * as actionProxy from '../action-proxy'; import * as common from '../common'; import * as conversationProxy from '../conversation-proxy'; import * as eventProxy from '../event-proxy'; import * as messageProxy from '../message-proxy'; import * as stateProxy from '../state-proxy'; import * as userProxy from '../user-proxy'; type EnumeratePluginEvents = bot.EnumerateEvents & common.EnumerateInterfaceEvents; type _IncomingEvents = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }; type _IncomingMessages = { [K in utils.StringKeys>]: utils.Merge; payload: bot.GetMessages[K]; }>; }; type _IncomingStates = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }; type _OutgoingMessageRequests = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }; type _OutgoingMessageResponses = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }>; }; type _OutgoingCallActionRequests = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }; type _OutgoingCallActionResponses = { [K in utils.StringKeys>]: utils.Merge[K]; }>; }; type _IncomingCallActionRequests = { [K in utils.StringKeys]: { type: K; input: TPlugin['actions'][K]['input']; }; }; type _IncomingCallActionResponses = { [K in utils.StringKeys]: { type: K; output: TPlugin['actions'][K]['output']; }; }; export type AnyIncomingEvent<_TPlugin extends common.BasePlugin> = client.Event; export type AnyIncomingMessage<_TPlugin extends common.BasePlugin> = client.Message; export type AnyOutgoingMessageRequest<_TPlugin extends common.BasePlugin> = client.ClientInputs['createMessage']; export type AnyOutgoingMessageResponse<_TPlugin extends common.BasePlugin> = client.ClientOutputs['createMessage']; export type AnyOutgoingCallActionRequest<_TPlugin extends common.BasePlugin> = client.ClientInputs['callAction']; export type AnyOutgoingCallActionResponse<_TPlugin extends common.BasePlugin> = client.ClientOutputs['callAction'] & { type: string; }; export type AnyIncomingCallActionRequest<_TPlugin extends common.BasePlugin> = { type: string; input: Record; }; export type AnyIncomingCallActionResponse<_TPlugin extends common.BasePlugin> = { type: string; output: Record; }; export type IncomingEvents = _IncomingEvents & { '*': AnyIncomingEvent; }; export type IncomingMessages = _IncomingMessages & { '*': AnyIncomingMessage; }; export type IncomingStates<_TPlugin extends common.BasePlugin> = _IncomingStates<_TPlugin> & { '*': client.State; }; export type OutgoingMessageRequests = _OutgoingMessageRequests & { '*': AnyOutgoingMessageRequest; }; export type OutgoingMessageResponses = _OutgoingMessageResponses & { '*': AnyOutgoingMessageResponse; }; export type OutgoingCallActionRequests = _OutgoingCallActionRequests & { '*': AnyOutgoingCallActionRequest; }; export type OutgoingCallActionResponses = _OutgoingCallActionResponses & { '*': AnyOutgoingCallActionResponse; }; export type IncomingCallActionRequest = _IncomingCallActionRequests & { '*': AnyIncomingCallActionRequest; }; export type IncomingCallActionResponse = _IncomingCallActionResponses & { '*': AnyIncomingCallActionResponse; }; export type PluginClient<_TPlugin extends common.BasePlugin> = bot.BotSpecificClient; export type CommonHandlerProps = { ctx: bot.BotContext; logger: bot.BotLogger; /** * Please use the `users`, `conversations`, `actions`, `messages`, `states`, * `events`, `workflows` utilities instead of accessing the client directly. * * For example, you can replace `props.client.listUsers(...)` with * `props.users.list(...).take(n)` */ client: PluginClient; }; export type InjectedHandlerProps = { configuration: common.PluginConfiguration; /** * Mapping of plugin interface dependencies to the integrations that * implement them. */ interfaces: common.PluginInterfaceExtensions; /** * Mapping of plugin integration dependencies to the integrations that * implement them. */ integrations: common.PluginIntegrationExtensions; /** * Alias of the plugin within the bot. This is usually equal to the plugin's * name, but may be different if the bot has multiple instances of the same * plugin installed. */ alias: string; /** * Allows calling actions defined by the plugins's integration and interface * dependencies. */ actions: actionProxy.ActionProxy; /** * Allows querying and mutating states defined by the plugin. */ states: stateProxy.StateProxy; /** * Allows emitting events defined by the plugin. */ events: eventProxy.EventProxy; /** * Allows querying and mutating users. */ users: userProxy.UserFinder; /** * Allows querying and mutating conversations on channels defined by the * plugin's integration and interface dependencies. */ conversations: conversationProxy.ConversationFinder; /** * Allows querying and mutating individual messages. */ messages: messageProxy.MessageFinder; /** * # EXPERIMENTAL * This API is experimental and may change in the future. */ workflows: workflowProxy.WorkflowProxy; }; type _WithInjectedProps>, TPlugin extends common.BasePlugin, TMerge extends object = {}> = { [K in keyof T]: utils.Merge & InjectedHandlerProps; }; type _WithInjectedPropsFn any>, TPlugin extends common.BasePlugin, TMerge extends object = {}> = { [K in keyof T]: (args: utils.Merge[0], TMerge> & InjectedHandlerProps) => ReturnType; }; export type MessagePayloadsWithoutInjectedProps = { [TMessageName in utils.StringKeys>]: CommonHandlerProps & { message: IncomingMessages[TMessageName]; user: client.User; conversation: client.Conversation; event: client.Event; }; }; export type MessageHandlersWithoutInjectedProps = { [TMessageName in utils.StringKeys>]: (args: MessagePayloadsWithoutInjectedProps[TMessageName]) => Promise; }; export type MessageHandlers = _WithInjectedPropsFn, TPlugin, { user: userProxy.ActionableUser; conversation: conversationProxy.ActionableConversation; message: messageProxy.ActionableMessage; }>; export type EventPayloadsWithoutInjectedProps = { [TEventName in utils.StringKeys>]: CommonHandlerProps & { event: IncomingEvents[TEventName]; }; }; export type EventPayloads = _WithInjectedProps, TPlugin>; export type EventHandlersWithoutInjectedProps = { [TEventName in utils.StringKeys>]: (args: EventPayloadsWithoutInjectedProps[TEventName]) => Promise; }; export type EventHandlers = _WithInjectedPropsFn, TPlugin>; export type StateExpiredPayloadsWithoutInjectedProps = { [TSateName in utils.StringKeys>]: CommonHandlerProps & { state: IncomingStates[TSateName]; }; }; export type StateExpiredPayloads = _WithInjectedProps, TPlugin>; export type StateExpiredHandlersWithoutInjectedProps = { [TSateName in utils.StringKeys>]: (args: StateExpiredPayloadsWithoutInjectedProps[TSateName]) => Promise; }; export type StateExpiredHandlers = _WithInjectedPropsFn, TPlugin>; export type ActionHandlerPayloadsWithoutInjectedProps = { [TActionName in utils.StringKeys]: CommonHandlerProps & { type?: TActionName; input: TPlugin['actions'][TActionName]['input']; }; }; export type ActionHandlerPayloads = _WithInjectedProps, TPlugin>; export type ActionHandlersWithoutInjectedProps = { [TActionName in utils.StringKeys]: (props: ActionHandlerPayloadsWithoutInjectedProps[TActionName]) => Promise; }; export type ActionHandlers = _WithInjectedPropsFn, TPlugin>; export type WorkflowPayloadsWithoutInjectedProps = { [TWorkflowName in utils.StringKeys]: CommonHandlerProps & { conversation?: client.Conversation; user?: client.User; event: bot.WorkflowUpdateEvent; workflow: client.Workflow; }; }; export type WorkflowPayloads = _WithInjectedProps<{ [TWorkflowName in keyof WorkflowPayloadsWithoutInjectedProps]: utils.Merge[TWorkflowName], { /** * # EXPERIMENTAL * This API is experimental and may change in the future. */ workflow: workflowProxy.ActionableWorkflow; }>; }, TPlugin>; export type WorkflowHandlersWithoutInjectedProps = { [TWorkflowName in utils.StringKeys]: (props: WorkflowPayloadsWithoutInjectedProps[TWorkflowName]) => Promise; }; export type WorkflowHandlers = { [TWorkflowName in utils.StringKeys]: (props: utils.Merge[TWorkflowName], { workflow: workflowProxy.ActionableWorkflow; }>) => Promise; }; type BaseHookDefinition = { stoppable?: boolean; data: any; }; type HookDefinition = THookDef; /** * TODO: add hooks for: * - before_register * - after_register * - before_state_expired * - after_state_expired * - before_incoming_call_action * - after_incoming_call_action */ export type HookDefinitionType = keyof HookDefinitions; export type HookDefinitions = { before_incoming_event: HookDefinition<{ stoppable: true; data: _IncomingEvents & { '*': AnyIncomingEvent; }; }>; before_incoming_message: HookDefinition<{ stoppable: true; data: _IncomingMessages & { '*': AnyIncomingMessage; }; }>; before_outgoing_message: HookDefinition<{ stoppable: false; data: _OutgoingMessageRequests & { '*': AnyOutgoingMessageRequest; }; }>; before_outgoing_call_action: HookDefinition<{ stoppable: false; data: _OutgoingCallActionRequests & { '*': AnyOutgoingCallActionRequest; }; }>; before_incoming_call_action: HookDefinition<{ stoppable: true; data: _IncomingCallActionRequests & { '*': AnyIncomingCallActionRequest; }; }>; after_incoming_event: HookDefinition<{ stoppable: true; data: _IncomingEvents & { '*': AnyIncomingEvent; }; }>; after_incoming_message: HookDefinition<{ stoppable: true; data: _IncomingMessages & { '*': AnyIncomingMessage; }; }>; after_outgoing_message: HookDefinition<{ stoppable: false; data: _OutgoingMessageResponses & { '*': AnyOutgoingMessageResponse; }; }>; after_outgoing_call_action: HookDefinition<{ stoppable: false; data: _OutgoingCallActionResponses & { '*': AnyOutgoingCallActionResponse; }; }>; after_incoming_call_action: HookDefinition<{ stoppable: true; data: _IncomingCallActionResponses & { '*': AnyIncomingCallActionResponse; }; }>; }; export type HookData = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]['data']>]: HookDefinitions[THookType]['data'][THookDataName]; }; }; export type HookInputsWithoutInjectedProps = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]: CommonHandlerProps & { data: HookData[THookType][THookDataName]; }; }; }; export type HookInputs = { [THookType in utils.StringKeys>]: _WithInjectedProps[THookType], TPlugin>; }; export type HookOutputs = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]: { data?: HookData[THookType][THookDataName]; } & (HookDefinitions[THookType]['stoppable'] extends true ? { stop?: boolean; } : {}); }; }; export type HookHandlersWithoutInjectedProps = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]: (input: HookInputsWithoutInjectedProps[THookType][THookDataName]) => Promise[THookType][THookDataName] | undefined>; }; }; export type HookHandlers = { [THookType in utils.StringKeys>]: _WithInjectedPropsFn[THookType], TPlugin>; }; export type HookHandlersMap = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]?: HookHandlersWithoutInjectedProps[THookType][THookDataName][]; }; }; export type WorkflowHandlersMap = { [TWorkflowUpdateType in bot.WorkflowUpdateType]: { [TWorkflowName in utils.StringKeys]?: { handler: (props: Omit[TWorkflowName]>[0], 'workflow'> & { workflow: client.Workflow; }) => Promise; order: number; }[]; }; }; export type OrderedMessageHandlersMap = { [TMessageName in utils.StringKeys>]?: { handler: MessageHandlers[TMessageName]; order: number; }[]; }; export type OrderedEventHandlersMap = { [TEventName in utils.StringKeys>]?: { handler: EventHandlers[TEventName]; order: number; }[]; }; export type OrderedStateExpiredHandlersMap = { [TStateName in utils.StringKeys>]?: { handler: StateExpiredHandlers[TStateName]; order: number; }[]; }; export type OrderedHookHandlersMap = { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]?: { handler: HookHandlers[THookType][THookDataName]; order: number; }[]; }; }; export type OrderedWorkflowHandlersMap = { [TWorkflowUpdateType in bot.WorkflowUpdateType]: { [TWorkflowName in utils.StringKeys]?: { handler: WorkflowHandlers[TWorkflowName]; order: number; }[]; }; }; /** Plugin handlers without InjectedHandlerProps */ export type PluginHandlers = { actionHandlers: ActionHandlersWithoutInjectedProps; messageHandlers: { [TMessageName in utils.StringKeys>]?: MessageHandlersWithoutInjectedProps[TMessageName][]; }; eventHandlers: { [TEventName in utils.StringKeys>]?: EventHandlersWithoutInjectedProps[TEventName][]; }; stateExpiredHandlers: { [TStateName in utils.StringKeys>]?: StateExpiredHandlersWithoutInjectedProps[TStateName][]; }; hookHandlers: { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]?: HookHandlersWithoutInjectedProps[THookType][THookDataName][]; }; }; workflowHandlers: { [TWorkflowUpdateType in bot.WorkflowUpdateType]: { [TWorkflowName in utils.StringKeys]?: WorkflowHandlersWithoutInjectedProps[TWorkflowName][]; }; }; }; /** identical to PluginHandlers, but contains the injected properties */ export type InjectedPluginHandlers = { actionHandlers: ActionHandlers; messageHandlers: { [TMessageName in utils.StringKeys>]?: MessageHandlers[TMessageName][]; }; eventHandlers: { [TEventName in utils.StringKeys>]?: EventHandlers[TEventName][]; }; stateExpiredHandlers: { [TStateName in utils.StringKeys>]?: StateExpiredHandlers[TStateName][]; }; hookHandlers: { [THookType in utils.StringKeys>]: { [THookDataName in utils.StringKeys[THookType]>]?: HookHandlers[THookType][THookDataName][]; }; }; workflowHandlers: { [TWorkflowUpdateType in bot.WorkflowUpdateType]: { [TWorkflowName in utils.StringKeys]?: WorkflowHandlers[TWorkflowName][]; }; }; }; export {};