This topic describes FAQ and solutions for AI assistant integration.
Contents
Floating window integration
Include the SDK
Include the SDK script in your HTML page:
<script src="https://o.alicdn.com/appflow/chatbot/v1/AppflowChatSDK.js"></script>
Initialize the floating window
<script>
window.APPFLOW_CHAT_SDK.init({
integrateConfig: {
integrateId: 'your integration ID',
domain: {
requestDomain: 'https://xxx.appflow.aliyunnest.com'
}
}
});
</script>
Set user information
Use the setUser method to set the current user information, which is passed to the model via the useInfo field of the chat API.
Parameters
|
Parameter |
Type |
Required |
Description |
|
userId |
string |
No |
A unique identifier for the user. |
|
userName |
string |
No |
The name of the user. |
|
userAvatar |
string |
No |
The URL of the user's avatar. |
Send an initial message
To send a message to the chat box on initialization, configure the initialMessage and initialMessageAutoSend parameters.
<script>
window.APPFLOW_CHAT_SDK.init({
integrateConfig: {
integrateId: 'your integration ID',
domain: {
requestDomain: 'https://xxx.appflow.aliyunnest.com'
},
initialMessage: 'Hello, welcome!',
initialMessageAutoSend: false,
}
});
</script>
Parameters
|
Parameter |
Type |
Required |
Description |
|
initialMessage |
string |
Yes |
The content of the initial message. |
|
initialMessageAutoSend |
boolean |
No |
Determines if an AI response is triggered for the initial message. The default is |
Configure dragging and auto-open
The draggable parameter controls whether the floating window is draggable. The autoOpen parameter controls whether it opens automatically on page load.
<script>
window.APPFLOW_CHAT_SDK.init({
integrateConfig: {
integrateId: 'Your Integration ID',
domain: {
requestDomain: 'https://xxx.appflow.aliyunnest.com'
},
draggable: true,
autoOpen: true
},
});
</script>
Customize floating window style
Customize the floating window style by setting sub-properties of the customStyle field. Two sub-properties are available: containerStyle and botBubbleStyle.
-
Set the
customStyle.containerStylevalue to adjust the width and height of the floating window. Four parameters are available: width, height, maxWidth, and maxHeight.The floating window container includes the title bar, chat content area, and bottom input area. These four parameters control the overall size of the container.
-
Set the
customStyle.botBubbleStylevalue to adjust the width of the AI reply message bubble. Two parameters are available: width and maxWidth. The message bubble width renders according to the specified values.<script> window.APPFLOW_CHAT_SDK.init({ integrateConfig: { integrateId: 'Your integration ID', domain: { requestDomain: 'https://xxx.appflow.aliyunnest.com' }, customStyle: { containerStyle: { width: '800px', height: '90%', maxHeight: '700px', maxWidth: '800px' } } }, }); </script>
Set extra parameters
Use the setExtraInfo method to set extra parameters. These parameters are passed to the model through the extraInfo field in the Chat API.
Method signature
setExtraInfo(extraInfo: any, isGlobal?: boolean): void
Parameters
|
Parameter |
Type |
Required |
Default |
Description |
|
extraInfo |
object |
Yes |
- |
The object containing the extra parameters. |
|
isGlobal |
boolean |
No |
false |
Specifies if the parameters are global. |
Global vs. temporary parameters
The SDK supports two types of extra parameters: global parameters and temporary parameters.
Global parameters (isGlobal: true)
-
Persistence: Retained until overwritten by new global parameters.
-
Sent with every message: Automatically included in every message request.
-
Use case: For data that needs to be passed continuously, such as user identity information or session-level configurations.
// Set global parameters. These parameters are sent with every message.
window.APPFLOW_CHAT_SDK.setExtraInfo({
tenantId: 'tenant-001',
channel: 'web',
language: 'zh-CN',
}, true); // isGlobal = true
Temporary parameters (isGlobal: false or omitted)
-
Scope: Included with the next message only.
-
Use case: For message-specific context or one-time business data.
// Set temporary parameters. These are sent only with the next message.
window.APPFLOW_CHAT_SDK.setExtraInfo({
currentPage: '/product/detail',
productId: 'SKU-12345',
timestamp: Date.now(),
}); // isGlobal defaults to false
// Or, specify it explicitly
window.APPFLOW_CHAT_SDK.setExtraInfo({
orderId: 'ORDER-001',
}, false);
Parameter merging rules
When both global and temporary parameters are set, they are merged. If the same field exists in both, the temporary parameter overwrites the global parameter.
// First, set the global parameters
window.APPFLOW_CHAT_SDK.setExtraInfo({
userId: 'user-001',
source: 'global',
}, true);
// Then, set the temporary parameters
window.APPFLOW_CHAT_SDK.setExtraInfo({
source: 'temp',
orderId: 'ORDER-001',
});
// When a message is sent, the actual parameters passed are:
// {
// userId: 'user-001', // From global parameters
// source: 'temp', // The temporary parameter overwrites the global one
// orderId: 'ORDER-001', // From temporary parameters
// }
Best practices
// 1. Set global user information after the user logs in.
function onUserLogin(userInfo) {
window.APPFLOW_CHAT_SDK.setExtraInfo({
userId: userInfo.id,
userRole: userInfo.role,
tenantId: userInfo.tenantId,
}, true);
}
// 2. Set temporary context on a specific page.
function onPageEnter(pageInfo) {
window.APPFLOW_CHAT_SDK.setExtraInfo({
currentPage: pageInfo.path,
pageTitle: pageInfo.title,
enterTime: Date.now(),
});
}
Pre-send handler
Use the onBeforeSend method to register a handler that executes custom logic before a message is sent.
Method signature
onBeforeSend(
handler: (params: { userMessage: UserMessage }) => void | Promise<void>,
options?: { async?: boolean }
): void
Parameters
|
Parameter |
Type |
Required |
Description |
|
handler |
function |
Yes |
The handler function that receives an object containing the user message. |
|
options.async |
boolean |
No |
Specifies whether to execute the handler asynchronously. The default value is |
Handler parameters
The handler function receives a parameter object.
|
Parameter |
Type |
Description |
|
userMessage |
UserMessage |
The message that the user is about to send. |
Common UserMessage fields
All message types include the following common fields.
|
Parameter |
Type |
Required |
Description |
|
messageType |
string |
Yes |
The message type. Valid values are 'text', 'rich', 'audio', 'event', and 'card_call_back'. |
|
sessionId |
string |
Yes |
The current session ID. |
|
chatbotId |
string |
Yes |
The AI assistant ID. |
|
chatbotModelId |
string |
Yes |
The model ID. |
|
userInfo |
object |
No |
The user information object, set with |
|
extraInfo |
object |
No |
The extra parameters object, set with |
|
config |
object |
No |
Configuration information, such as web search settings. |
Fields by message type
text (plain text message)
{
messageType: 'text',
sessionId: string,
chatbotId: string,
chatbotModelId: string,
text: {
content: string // The text content entered by the user
},
userInfo?: object,
extraInfo?: object,
config?: object
}
rich (rich text message)
A message that contains multimedia content, such as text, images, and files.
{
messageType: 'rich',
sessionId: string,
chatbotId: string,
chatbotModelId: string,
richText: Array<{
type: 'text' | 'image' | 'file',
content?: string, // Text content if type='text'
mediaUrl?: string, // Media URL if type='image' or 'file'
mediaId?: string // Optional file ID if type='file'
}>,
userInfo?: object,
extraInfo?: object,
config?: object
}
audio (audio message)
{
messageType: 'audio',
sessionId: string,
chatbotId: string,
chatbotModelId: string,
audio: {
mediaUrl: string, // Audio file URL
mediaType: string // Audio type, for example, 'wav'
},
userInfo?: object,
extraInfo?: object,
config?: object
}
event (system event)
{
messageType: 'event',
sessionId: string,
chatbotModelId: string,
event: {
eventType: string, // Event type, for example, 'uploadFile'
content: string // Event content (a JSON string)
}
}
card_call_back (card callback)
Used for interactive scenarios, such as approvals.
{
messageType: 'card_call_back',
sessionId: string,
cardCallBack: {
data: any // Card callback data
}
}
Synchronous vs. asynchronous mode
Synchronous mode (default)
After the processor function executes, the SDK sends the message immediately. Even if the function returns a Promise, the SDK does not wait for it to resolve. This mode is suitable for non-blocking tasks like logging or analytics.
// Synchronous mode: The message is sent immediately after the handler executes.
window.APPFLOW_CHAT_SDK.onBeforeSend((params) => {
console.log('User is about to send a message:', params.userMessage);
// Track analytics (non-blocking).
analytics.track('message_send', {
content: params.userMessage,
timestamp: Date.now(),
});
});
Asynchronous mode (async: true)
If the processor function returns a Promise, the SDK waits for the Promise to resolve before sending the message. This mode is suitable for asynchronous operations that must complete before the message is sent, such as content moderation or data preprocessing.
// Asynchronous mode: The SDK waits for the handler to complete before sending the message.
window.APPFLOW_CHAT_SDK.onBeforeSend(async (params) => {
console.log('User is about to send a message:', params.userMessage);
// Asynchronous operation: content moderation.
const isValid = await contentModeration.check(params.userMessage);
if (!isValid) {
throw new Error('Message content is not compliant');
}
// Asynchronous operation: set dynamic parameters.
const contextData = await fetchUserContext();
window.APPFLOW_CHAT_SDK.setExtraInfo({
context: contextData,
});
}, { async: true });
Examples
Example 1: Simple logging
window.APPFLOW_CHAT_SDK.onBeforeSend((params) => {
console.log(`[${new Date().toISOString()}] Sending message: ${params.userMessage}`);
});
Example 2: Set dynamic parameters
window.APPFLOW_CHAT_SDK.onBeforeSend((params) => {
// Dynamically set parameters based on the message content.
const keywords = extractKeywords(params.userMessage);
window.APPFLOW_CHAT_SDK.setExtraInfo({
keywords: keywords,
messageLength: params.userMessage.length,
sendTime: Date.now(),
});
});
Example 3: Asynchronous preprocessing
window.APPFLOW_CHAT_SDK.onBeforeSend(async (params) => {
// Call a backend API to get the user context.
const response = await fetch('/api/user/context');
const userContext = await response.json();
// Set extra parameters.
window.APPFLOW_CHAT_SDK.setExtraInfo({
userContext: userContext,
processedAt: Date.now(),
});
}, { async: true });
Notes
-
Only one handler can be registered: Calling
onBeforeSendmultiple times overwrites the previously registered handler. -
Error handling in asynchronous mode: If the asynchronous handler throws an error, the message is not sent.
-
Performance considerations: Asynchronous mode delays message sending. Ensure that asynchronous operations complete as quickly as possible.
Post-send handler
Use the onAfterSend method to register a handler that executes custom logic when the AI reply completes or an error occurs.
Method signature
onAfterSend(
handler: (params: AfterSendParams) => void | Promise<void>,
options?: { async?: boolean }
): void
Parameters
|
Parameter |
Type |
Required |
Description |
|
handler |
function |
Yes |
A function that receives a parameter object containing the send result. |
|
options.async |
boolean |
No |
Specifies whether to use asynchronous execution. Defaults to |
Handler parameters
The handler function receives a parameter object whose structure depends on the send result:
Parameters on success
|
Parameter |
Type |
Description |
|
userMessage |
UserMessage |
The message sent by the user. |
|
assistantContent |
string |
The full content of the AI's reply. |
|
assistantReferences |
array |
A list of referenced documents or knowledge base entries. |
Parameters on failure
|
Parameter |
Type |
Description |
|
userMessage |
UserMessage |
The message sent by the user. |
|
error |
object |
The error object. |
|
message |
string |
The error description. |
|
code |
string |
The error code. |
Choosing between synchronous and asynchronous modes
Synchronous mode (default)
In synchronous mode, the handler executes and does not block subsequent operations. Even if the handler returns a Promise, the SDK does not wait for it to resolve. This mode is suitable for non-blocking tasks like logging, analytics tracking, or UI updates.
// Synchronous mode
window.APPFLOW_CHAT_SDK.onAfterSend((params) => {
if (params.success) {
console.log('Message sent successfully');
console.log('AI reply:', params.assistantContent);
} else {
console.error('Message sending failed:', params.error.message);
}
});
Asynchronous mode (async: true)
In asynchronous mode, if the handler function returns a Promise, the SDK waits for the Promise to resolve. This is ideal for scenarios requiring asynchronous operations after a reply is complete, such as data persistence or subsequent API calls.
// Asynchronous mode
window.APPFLOW_CHAT_SDK.onAfterSend(async (params) => {
if (params.success) {
// Asynchronously save the conversation history
await saveConversation({
question: params.userMessage,
answer: params.assistantContent,
references: params.assistantReferences,
});
}
}, { async: true });
Examples
Example 1: Basic logging
window.APPFLOW_CHAT_SDK.onAfterSend((params) => {
const timestamp = new Date().toISOString();
if (params.success) {
console.log(`[${timestamp}] Conversation completed`);
console.log(` User: ${params.userMessage}`);
console.log(` AI: ${params.assistantContent.substring(0, 100)}...`);
console.log(` Reference count: ${params.assistantReferences.length}`);
} else {
console.error(`[${timestamp}] Conversation failed`);
console.error(` User: ${params.userMessage}`);
console.error(` Error: [${params.error.code}] ${params.error.message}`);
}
});
Example 2: Analytics tracking
window.APPFLOW_CHAT_SDK.onAfterSend((params) => {
// Send analytics event
analytics.track('chat_completed', {
success: params.success,
userMessage: params.userMessage,
responseLength: params.success ? params.assistantContent.length : 0,
referenceCount: params.success ? params.assistantReferences.length : 0,
timestamp: Date.now(),
});
});
Example 3: Conversation history persistence (asynchronous)
window.APPFLOW_CHAT_SDK.onAfterSend(async (params) => {
try {
await fetch('/api/conversation/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
question: params.userMessage,
answer: params.success ? params.assistantContent : null,
references: params.success ? params.assistantReferences : [],
error: params.success ? null : params.error,
timestamp: Date.now(),
}),
});
} catch (error) {
console.error('Failed to save conversation history:', error);
}
}, { async: true });
Notes
-
Only one handler can be registered: Calling
onAfterSendmultiple times overwrites the previously registered handler. -
Error handling in asynchronous mode: Use
try-catchblocks in asynchronous handlers to manage potential errors and avoid disrupting the user experience. -
Performance considerations: Keep handler logic lightweight to avoid degrading the chat experience.
Close the floating window
Call the close method to close the chat floating window.
window.APPFLOW_CHAT_SDK.close();