I’ve been building a nextJS app and the final feature I need to add is to is allow conversational chat from the app’s users to SMS using the twilio conversations SDK.
I can interact with the SDK fully as expected in server components (create, join, load conversations, load the messages within those conversations, ect) but I need access to state to pull in new messages without the user having to refresh the page. Problem is that as soon as I try to do anything in a client component I run into trouble.
The objects from the SDK look something like this:
Message {
_events: [Object: null prototype] { updated: [Function (anonymous)] },
_eventsCount: 1,
_maxListeners: undefined,
eventHistory: Map(0) {},
conversation: Conversation {
_events: [Object: null prototype],
_eventsCount: 10,
_maxListeners: undefined,
eventHistory: [Map],
sid: 'AN ID',
_links: [Object],
_configuration: [Configuration],
_services: [ClientServices],
_entityName: 'AN ID',
_internalState: [Object],
_participants: [Map],
_participantsEntity: [Participants],
_messagesEntity: [Messages],
_entityPromise: [Promise],
_entity: [SyncDocument],
_messagesList: [SyncList],
_participantsMap: [SyncMap],
_dataSource: 'rest',
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false
},
configuration: Configuration {
typingIndicatorTimeoutDefault: 5000,
productId: 'ip_messaging',
links: [Object],
limits: [Object],
typingIndicatorTimeoutOverride: undefined,
backoffConfiguration: [Object],
retryWhenThrottled: true,
userInfosToSubscribe: 100,
reachabilityEnabled: false,
userIdentity: 'EMAIL',
userInfo: 'AN ID',
myConversations: 'EMAIL',
httpCacheInterval: 1,
consumptionReportInterval: 1,
channelMetadataCacheCapacity: 100,
messageRecipientsCacheCapacity: 1000
},
services: ClientServices {
twilsockClient: [_class],
transport: [_class],
notificationClient: [_class],
syncClient: [Client],
commandExecutor: [CommandExecutor],
contentClient: [ContentClient],
channelMetadataClient: [ChannelMetadataClient],
messageRecipientsClient: [MessageRecipientsClient],
typingIndicator: [TypingIndicator],
network: [Network],
users: [Users],
mcsClient: [_class]
},
state: {
sid: 'AN ID',
index: 21,
author: 'PHONE NUMBER',
subject: null,
contentSid: null,
body: 'Test message',
timestamp: 2024-11-21T14:24:32.545Z,
dateUpdated: 2024-11-21T14:24:32.545Z,
lastUpdatedBy: null,
attributes: {},
type: 'text',
media: null,
medias: null,
participantSid: 'AN ID',
aggregatedDeliveryReceipt: null,
hasChannelMetadata: false
},
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false
}
Twilios react example simply passes these objects as props to the the “conversation” component without issue. But when I try to pass this object from a server component to a client component in NextJS I get “Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.”
Tried using JSON.stringify before passing as props but it can’t be converted to JSON because “TypeError: Converting circular structure to JSON”.
I tried returning the SDK object from the route but next/response sends it as JSON so I run into the same issue with the “TypeError: Converting circular structure to JSON”.
I’ve tried getting the data from the SDK from within the client component but I can’t get it to do that either. I seem to only be able to do anything with the SDK exclusively in server components.
So far the closest I’ve gotten is to send a request to a route, which returns an array of the messages but then it’s just an array… I can’t interact with the SDK object to listen for new messages, get read receipts, ect.
I’m new to all this, learned quickly and have accomplished a lot in my app until this point. I’m sure there’s a simple answer but I need a shove in the right direction.
Thanks in advance!