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, andcontent
is passed in as props.- When
hasTime
is true, the time of the message is displayed, and the format is configured usingTime.formats
inlocales
. 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.
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
}