Description:
After onMessageSent
handler is registered on Twilio Conversation
object, when new message is sent using conversation.sendMessage(messageText)
sometimes handler is not called. This seems to happen randomly e.g:
I'm sending 4 messages A,B,C,D
in succession.
Handler is called for messages A,B and D
, but not for C
.
Also sometimes it seems to get stuck totally, so only refresh would help.
After reloading all sent messages appear in conversation
What I have ruled out:
- multiple Client references
- mutliple Conversation references
- handler removed in
useEffect
cleanup function - handler not attached to Conversation object (it's there under
Conversation._events.messageAdded
)
Code:
import React from "react";
import { Conversation, Message, Paginator } from "@twilio/conversations";
import { useTwilioClient } from "./Twilio.context";
const messagesPageSize = 50;
export const useTwilioConversation = (sid: string) => {
const twilioClient = useTwilioClient();
const [twilioConversation, setTwilioConversation] =
React.useState<Conversation | null>(null);
const [messages, setMessages] = React.useState<Message[]>([]);
const [paginator, setPaginator] = React.useState<Paginator<Message>>();
const [isLoading, setIsLoading] = React.useState(false);
const fetchMore = React.useCallback(() => {
if (!twilioConversation || !paginator) {
return;
}
paginator.prevPage().then((paginator) => {
setPaginator(paginator);
setMessages((prev) => paginator.items.concat(prev));
});
}, [paginator, twilioConversation]);
React.useEffect(() => {
if (!twilioClient) {
return;
}
setIsLoading(true);
const getTwilioConversation = async () => {
const conversation = await twilioClient.getConversationBySid(sid);
await conversation.setAllMessagesRead();
setTwilioConversation(conversation);
const paginator = await conversation.getMessages(messagesPageSize);
setPaginator(paginator);
setMessages(paginator.items);
};
getTwilioConversation().finally(() => {
setIsLoading(false);
});
}, [twilioClient, sid]);
React.useEffect(() => {
if (!twilioConversation) {
return;
}
const handleMessageAdded = (message: Message) => {
setMessages((prev) => [...prev, message]);
};
twilioConversation.on("messageAdded", handleMessageAdded);
return () => {
twilioConversation?.removeListener("messageAdded", handleMessageAdded);
};
}, [twilioConversation]);
return {
messages,
twilioConversation,
fetchMore,
hasMore: !!paginator?.hasPrevPage,
isLoading,
setMessages,
};
};