RFC: Architecture of chat adapter and supporting different chat providers #3713
Labels
backlog
Out of scope for the current iteration but it will be evaluated in a future release.
feature-request
Azure report label
front-burner
Feature Request
To ready Web Chat into the future, I am proposing an architecture to allow Web Chat to operate on first party and third party chat providers.
Related issues:
Today
Today, Web Chat is quite coupled with the behavior of Direct Line protocol (implemented by Azure Bot Services). Especially, the following behaviors are built into Web Chat (non-exhaustive):
replyToID
is used to delay activity if its precedent is not received yetclientActivityID
as "client ID"These behaviors are built into Redux saga of Web Chat. We need to move them out into a separate Direct Line chat adapter.
Tomorrow
I am proposing a stateful approach of chat adapter. For stateful, I mean the chat adapter is responsible for storing all activities in the transcript. This includes: received activities, sending activities, and sent activities.
In this approach, Web Chat will not in the business of (non-exhaustive):
Also, core features of Web Chat will not requires "channel data". If the chat adapter support backchannel data, developer can use Web Chat to send backchannel data. However, it is up to the chat adapter on how to send these data:
Restrictions
To provide best user experience, there are restrictions on the design of chat adapter:
Potential chat adapter interface
Internally, it would work like this:
Although not required, a chat adapter should minimally implement both
activities
andsendMessage
. For example,Bridging to
DirectLineJS
interfaceInternally, if
directLine
object is passed, along with optionalstore
parameter, we will use the olderbotframework-webchat-core
to instantiate a Redux store, and use a<LegacyChatAdapterBridge>
to bridge it from Redux store to new chat adapter interface.Internally,
MVP for ACS chat adapter
Web Chat side change
activity.id
, useactivity.channelData['webchat:key']
activity.role
, useactivity.channelData['webchat:who']
to determines whether the message is fromself
,others
, orsystem
activity.channelData.sendState
, rename toactivity.channelData['webchat:send-state']
with value ofsent
orsending
bf-wc-component
should calluseEmitTypingIndicator()
, instead of by saga insidebf-wc-core
useEmitTypingIndicator()
hookhooks/useActiveTyping.js
styleOptions.typingAnimationDuration
because this value is now provided by chat adapteractivity
array is updated in an order not supported:Additional logics need to add on top of ACS chat adapter
Comments to ACS
General
endpointUrl
->endpointURL
, references from MDN:Id
is not an acronymencodeURIComponent
indexedDB
lastEventId
sinkId
{"error":{"code":"IdentityNotFound","message":"Provided identity doesn't exist."}}
Should somehow notify the end-developer that the token is invalid?communicationUserId
oridentity
?userId
Related to read receipts
useSendReadReceipt
is only needed for the very last message, not needed for every messages in the transcriptchatMessageId
reference is not in the transcriptchatMessageId
is not useful and should be ignored. ThereadOn
should be used as a way to determine which message in the transcript is read (comparereadOn
vs.createdOn
)readOn
is not be reliable way to determine the exact time a message is readRelated to
useChatMessages
(Some questions in this section is obsoleted as ACS is moving to another style of API.)
useChatMessages
is not exporteduseChatMessages
requires bothuseFetchMessages
anduseSubscribeMessage
IfuseFetchMessages
is not called, conversation history will not be fetched byuseChatMessages
IfuseSubscribeMessage
is not called, new incoming messages will not appears inuseChatMessages
useChatMessages
always creates a new instance ofArray
even if its content did not changeuseChatMessages
(oruseFetchMessages
) are downloading conversation history, the end-user sending a message may end up in a wrong position, repro:useChatMessages
is new or from conversation history?useChatMessages
callRelated to
useSendMessage
(Some questions in this section is obsoleted as ACS is moving to another style of API.)
useSendMessage
to send a message,useChatMessages
will have a new message appendedtype
field, it should haveevent
activityuseSendMessage
should know aboutidentity
without the need of passing it manuallyuseSendTypingNotification
does not requires any parameters includingidentity
Related to
useTypingUsers
anduseSendTypingNotification
(Some questions in this section is obsoleted as ACS is moving to another style of API.)
useTypingUsers
should automatically calluseThreadMembers
to get list of thread membersuseTypingUsers
is triggering re-render every 500 ms while anyone in the thread is typingdisplayName
? It's not in@azure/communication-common/CommunicationUser
useTypingUsers
only returnscommunicationUserId
withoutdisplayName
useSendTypingNotification
, how to stop it after the message has been sent? Repro:useSendTypingNotification()
useSendMessage()
useSendTypingNotification()
did return an empty arrayRelated to other hooks or providers
@azure/communication-common
supportsrefreshTokenCallback
withoutinitialToken
, but<ChatProvider>
does notUncaught TypeError: Cannot read property 'split' of undefined at getIdFromToken (SDKUtils.ts:74) at ChatProvider (ChatProvider.tsx:47)
Splash screen should not be provided by<ChatProvider>
(or<ChatThreadProvider>
)Instead, allowing developers to specify their own splash screen, probably usingchildren({ connected })
Seems<ChatThreadProvider>
is not needed as<ChatProvider>
will internally create ituseThreadMembers
requires to calluseFetchThreadMembers
useChatMessages
which requiresuseFetchChatMessages
anduseSubscribeChatMessages
useSubscribeThreadMembers
useThreadMembers
will not report it automaticallyimport { useUserId } from '@azure/acs-ui-sdk/dist/providers/ChatProvider';
Outgoing messages appended in the middle
If a message is being sent while fetching user messages, it could be added in the middle of the transcript
Perceived order of messages could differs between clients
This is probably SDK issue. Right-hand side is the sender, although it is sending from 1 to 0, the transcript was perceived in a random order. Left-hand side is the receiver.
After token refresh or reloading the conversation history, both sender and receiver perceive the conversation with a correct order.
(To be continued)
[feature-request]
The text was updated successfully, but these errors were encountered: