Setting custom guest attributes via Web Messaging SDK in Go backend

Does anyone know the correct pattern for injecting custom guest attributes into the Genesys Cloud Web Messaging widget when the user authentication is handled by a separate Go service?

I am building a high-throughput Go service (America/Chicago timezone) that manages user sessions. When a user logs in, my Go backend fetches their profile and needs to pass specific attributes (like userId and tier) to the Web Messaging widget on the client side before the chat session initializes. I want to ensure these attributes are attached to the message payload sent to the Genesys Cloud platform.

Currently, I am generating a signed JWT in my Go service using the golang-jwt/jwt library. I then pass this token to the frontend React application. The frontend initializes the Web Messaging SDK as follows:

import { WebChatClient } from '@genesys/web-messaging-sdk';

const client = new WebChatClient({
 orgId: 'my-org-id',
 deploymentId: 'my-deployment-id',
 token: jwtTokenFromGoService,
 guest: {
 firstName: 'John',
 lastName: 'Doe',
 custom: {
 userId: '12345',
 tier: 'premium'
 }
 }
});

According to the Genesys Docs, this should work. However, when I inspect the message payload in the Genesys Cloud admin console, the custom object is empty. The standard fields like firstName populate correctly, but any nested or custom data seems to be stripped out during the SDK initialization.

I have verified that the JWT claims in my Go service contain the correct data. Is there a specific claim name required by the Web Messaging SDK to map to guest attributes? Or do I need to make a separate API call to /api/v2/conversations/messaging/messages to update the participant attributes after the session starts? I would prefer to set this at initialization time to avoid race conditions.

Any insights on how to properly structure the JWT or the SDK config to preserve these custom attributes would be appreciated.

if i remember correctly, pushing attributes from a go backend to the sdk is complex. better to use the setAttributes method in the client side js directly after auth. it avoids cors issues and keeps state local. the sdk handles the sync to the conversation automatically.

Have you tried injecting the attributes via the initOptions payload during the SDK initialization rather than calling setAttributes post-auth? The client-side approach mentioned above works for dynamic updates, but for static profile data fetched from your Go service, embedding it at load time prevents race conditions where the conversation starts before attributes are attached.

Configure the guestAttributes in the widget config JSON. This ensures the data is present in the initial conversation.start event. Here is the structure:

{
 "initOptions": {
 "guestAttributes": {
 "userId": "{{ .UserId }}",
 "tier": "{{ .Tier }}"
 }
 }
}

I use this pattern in my Django pipeline to guarantee analytics consistency. If you call setAttributes after the chat connects, you risk missing the initial routing logic that depends on those attributes.