Skip to main content
Version: 2.0.0

Core

Core mainly provides a model of the dialog system and a plugin system. In the type definition, Core's data structure type is ContextModel, which is based on a Mobx4 (IE compatible) implementation. We'll look at each section in turn.

Plugin system

The plugin system is mainly responsible for managing plug-ins and implementing functions called between plug-ins and Core or other plug-ins. The way plugins and Core call each other is through the event mechanism. That is, when one party emits an event, all callbacks listening for that event are called simultaneously in the order of registration.

A plugin is a reusable set of code blocks that respond to specific events. Each piece of code uses the event mechanism provided by Core to listen for specific events, and implements business functions through apis and data provided by the model of the dialogue system in Core.

For example, regist LCMessager plugin. One of these blocks is to listen for a "sendUserMessage" event, add a user message through appendUserMessage, an API provided by Core, and call the LC platform's getReply interface. Retrieve the response and add it through the "appendReciveMessage" API provided by Core to show the dialogue.

Code comment Description

Code comments generally contain three blocks. The first block is the field name and its corresponding data type, usually in the first line of the code block, in the form of a comment. If you want to describe window.document.cookie as a string, then:

// window.document.cookie: string

If the data described is of a complex type, a second block is needed to clarify the specific definition of the advanced type, such as describing arr as an array of type TypeB:

// arr: TypeB[]
// The above line is the first block
// Then the second block
type TypeB = {
foo: string
bar: string
}

If the second block contains more complex types, a third block is needed to clarify the dependent types, usually beginning with the comment "// deps". For example, it describes on as an event-listening method that listens for an event and mounts a listener that processes data:

// on: EventStystemOn
// The above line is the first block
// Then the second block
type EventStystemOn = (eventName: string, handler: EventHandler) => void

// Then the third one
// deps
type EventHandler = (data: Record<string, any>) => void

pluginList

Contains a list of registered plugins.

// pluginList: Plugin[]
type Plugin = (context: ContextModel) => any

eventListeners

Record all event listeners.

// eventListeners: EventListeners
type EventListeners = Record<string, PluginHandler[]>

// deps
type PluginHandler = (context: ContextModel, payload?: PluginHandlerPayload) => (Promise<any> | any)

type PluginHandlerPayload = Record<string, any>

on

Listens for specified event. Handler is called when the event is emitted.

// on: PluginOn
type PluginOn = (eventName: string, handler: PluginHandler) => any

// deps
type PluginHandler = (context: ContextModel, payload?: PluginHandlerPayload) => (Promise<any> | any)

type PluginHandlerPayload = Record<string, any>

emit

Fires the specified event.

// emit: PluginEmit
type PluginEmit = (eventName: string, payload?: PluginHandlerPayload) => void

// deps
type PluginHandlerPayload = Record<string, any>

off

Unregisters the listener for the specified event. If no handler is passed, all listeners under this event are cleared. If the handler is passed in, only the corresponding listener is cleared.

// off: PluginOff
type PluginOff = (eventName: string, handler?: PluginHandler) => void

// deps
type PluginHandler = (context: ContextModel, payload?: PluginHandlerPayload) => (Promise<any> | any)

type PluginHandlerPayload = Record<string, any>

Dialog model

Dialog model, containing dialog related data and API, such as history message list, current message list, adding message, resetting session, rendering control of interface elements, and extension functions, such as custom data management, I18N translation, etc.

Message Specified message format

Core receives and sends a specified message format. detail:

  • comp is the component render of the message, and content is passed in as props.
  • When hasTime is true, the time of the message is displayed, and the format is configured using Time.formats in locales.
  • originMessage is used to record original messages. Multiple messages returned by some platforms may originate from a single JSON file.
type Message = {
_id: string
comp: string | React.ComponentClass<any, any> | React.FunctionComponent<any>
content: Record<string, any>

hasTime?: boolean
createdAt?: Moment | number
user?: UserInfo
position?: 'left' | 'right' | 'center'

originMessage?: any
}

type MessageList = Message[]

// deps
interface UserInfo {
name: string
avatar?: string
}

history History Message List

default: []

// history: MessageList
type MessageList = Message[]

currentMessages Messages in this round

default: []

// currentMessages: MessageList
type MessageList = Message[]

hasMoreHistory

Default: true

type hasMoreHistory: boolean

suffixMessages Messages after currentMessages

Messages after currentMessages. implement the need for quick replies to be displayed in the message list.

// suffixMessages: MessageList

messages【Read Only】Full message list

Contains history, currentMessages, suffixMessages and isTyping messages in sequence. note: The isTyping message is added only when ui.isTyping is true.

// messages: MessageList

// deps
// isTyping messages
const TYPING_ID = "TYPING_ID"
const isTypingMessage = ({
_id: TYPING_ID,
type: 'typing',
position: 'left',
comp: () => {}
}

channelOption Channel of dialogue

Record the current chat channel, which is used when transferring to the human service or interconnecting with the IM. Default: PRESET_CHANNEL.LC

// channelOption: PRESET_CHANNEL
type ChannelOption = PRESET_CHANNEL.LC | PRESET_CHANNEL.HUMAN | string

inputType The input mode

Specify the input mode, such as text, audio, and more media files.

Default: UserInputTypes.TEXT
// inputType: UserInputType
type UserInputType = UserInputTypes.TEXT | UserInputTypes.AUDIO | string

inputValue The current value of the text input box

Default: ''

// inputValue: string

userInfo

If the avatar is empty, the user avatar is hidden.

// userInfo: UserInfo
interface UserInfo {
name: string
avatar?: string // some.com/avatar.png
}

botUserInfo

// botUserInfo: UserInfo
interface UserInfo {
name: string
avatar?: string // some.com/avatar.png
}

env Running enviroment

Default: "PRODUCT"

// env: "PRODUCT" | "SKETCH" | string

autoComplete

// autoComplete: Options
type Options = Option[]

type Option = TextOption | LinkOption | CustomOption

type TextOption = {
type: 'text',
content: string
}

type LinkOption = {
type: 'link',
content: string
href: string
target: '_blank' | '_parent' | '_self' | '_top' | string
}

type CustomOption = {
type: 'custom',
content: ReactNode
}

quickReplies

It is used to guide the user to reply to a preset answer.

// quickReplies: QuickReply
type QuickReply = Option & BasicQuickReplyOption

interface BasicQuickReplyOption {
isNew?: boolean
isHighlight?: boolean
}

type Option = TextOption | LinkOption | CustomOption

type TextOption = {
type: 'text',
content: string
}

type LinkOption = {
type: 'link',
content: string
href: string
target: '_blank' | '_parent' | '_self' | '_top' | string
}

type CustomOption = {
type: 'custom',
content: ReactNode
}

init

Initialize the core. init

appendMessage(message) Adding messages manually

Manually add a message to currentMessages, which is equivalent to currentMessages.push.

// appendMessage: AppendMessageFunc
type AppendMessageFunc = (messageData: Message) => void

prependHistoryMsg, appendHistoryMsg, prependMessage

similar to appendMessage

appendUserMessage(message) Adding user messages manually

// appendUserMessage: AppendMessageFunc
function appendUserMessage(message) {
message.user = message.user || this.userInfo
message.type = message.type || 'custom'
message.hasTime = message.hasTime ? true : false
message.createdAt = message.createdAt || Date.now()
message.position = message.position || 'right'

this.currentMessages.push(message)
}

appendReciveMessage(message) Adding received messages manually

// appendReciveMessage: AppendMessageFunc
function appendReciveMessage(message) {
this.currentMessages.push({
user: this.botUserInfo,
type: 'custom',
position: 'left',

...message
})
}

changeChannel(channel)

// changeChannel: ChangeChannel
type ChangeChannel = (channel: ChannelOption) => void

changeChannel(channel) {
const legacyChannel = this.channelOption
this.channelOption = channel

this.emit('changeChannel', { pre: legacyChannel, current: channel })
}

resetConversition()

// resetConversition: () => void
function resetConversition() {
this.history = []
this.currentMessages = []
this.autoComplete = []
this.quickReplies = []
this.inputValue = ''

this.emit('resetConversition')
}

instance ChatUI Instance

Just equals to ChatUI's messagesRef.

// instance: React.ReactNode

composerRef

Just equals to ChatUI's composerRef.

// composerRef?: React.RefObject<ComposerHandle>

Session data controller

Used to share data or information between plugins or to store it for use by plugins themselves.

sessionData

// sessionData: Record<string, any>

setSessionData(key, value)

// setSessionData: (key: string, value: any) => void

getSessionData(key)

// getSessionData: (key: string) => any

removeSessionData(key)

// removeSessionData: (key: string) => any

i18n

locale Current language

Current language. Locales should contain attribute that equal to locale.

// locale: string

locales Language infos

Default:

{
'en-US': {
input: {
placeholder: 'Your message...',
},
loadmore: 'load more messages',
download: 'Download',
confirm: 'confirm',
cancel: 'cancel',
Time: {
weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
formats: {
LT: 'HH:mm',
lll: 'M/D/YYYY HH:mm',
WT: 'dddd HH:mm',
YT: 'Yesterday HH:mm',
},
},
Composer: {
send: 'Send',
},
}
}

Type definition

// locales: Locales
type Locales = Record<string, LocaleDetail>

// deps
type LocaleDetail = Record<string, LocaleItem>
type LocaleItem = string | string[] | LocaleItemObj

trans(key)

Translate key with locales[locale].

// example
const model = {
// ... other data
locale: 'en-US',
locales: {
"en-US": {
"common": {
"hello": "hello world!"
}
}
}
}

model.trans('common.hello') // "hello world"

Core event list

beforeInitial

  • trigger: During init, before loading the config and plugin.
  • payload: config provided to init function

didInitial

  • trigger: During init, after loading the config and plugin.
  • payload: config provided to init function

changeChannel

  • trigger: after eval changeChannel
  • payload:
    {
    pre: legacyChannel,
    current: channel
    }

resetConversition

  • trigger: after eval resetConversition
  • payload: -

localeChange

  • trigger: after locale is changed
  • payload:
    {
    locale: newLocale
    }

log

  • trigger: Every event that is emited emits a "log" event, except "log" event itself.
    {
    eventName: string,
    payload: any
    }