Chat widget attributes
Chat Widget Attributes
When using the Bird Chat Widget, you can pass contextual data into conversations using two different mechanisms:
- Contact Attributes — update the Contact Profile in BirdCRM (persistent across sessions)
- Conversation Attributes — attach metadata to a specific conversation (per-conversation)
Contact Attributes (via Bird Web SDK)
Contact attributes update the CRM profile for the identified contact. These persist across conversations and sessions.
Przykład kodu
// First, identify the contact
await Bird.contact.identify({
strategy: 'SignedIdentityClaims',
signedIdentity: signedIdentity,
});
// Then update their profile
await Bird.contact.putAttributes({
displayName: 'Jane Smith',
});Contact attributes are visible in the Contact Profile UI and can be used in:
- Journeys: Access via {{run.contact.attributes.<key>}}
- Flows: Use a "Fetch Contact" step, then access contact fields
- Audience segmentation: Filter contacts by attribute values
Supported Attributes
| Attribute | Type | Description |
|---|---|---|
| displayName | string | Contact's display name shown in CRM |
| Custom keys | any | Any key-value pair stored as a contact attribute |
Conversation Attributes (via Chat Widget API)
Conversation attributes attach metadata to the next conversation created through the chat widget. They are session-specific and do not persist on the contact record.
Przykład kodu
window.mbchat.setAttributes({
currentPage: window.location.pathname,
userPlan: 'premium',
cartValue: '149.99',
referrer: document.referrer,
});These attributes are:
- Sent automatically when the visitor creates a new conversation
- Stored on the conversation record
- Visible to agents in the conversation details
- Accessible in Flows via a Get Conversation step (not directly on the trigger)
- Not persisted on the Contact Profile
When to Use Each
| Data Type | Use | API |
|---|---|---|
| User identity (name, email) | Contact Attributes | Bird.contact.putAttributes() |
| Subscription tier, account info | Contact Attributes | Bird.contact.putAttributes() |
| Current page, referrer, UTM params | Conversation Attributes | window.mbchat.setAttributes() |
| Cart value, product being viewed | Conversation Attributes | window.mbchat.setAttributes() |
Complete Example
Here is the recommended integration pattern for a logged-in user:
Przykład kodu
<script
src="https://embeddables.p.mbirdcdn.net/sdk/v0/bird-sdk.js"
data-config-url="YOUR_CONFIG_URL"
></script>
<script>
async function initBirdChat(user) {
// 1. Get signed identity from your authenticated backend
// Your backend verifies the user's session and generates the JWT
// using their email/ID from YOUR database — not from client input
const resp = await fetch('/api/bird-identity', {
method: 'POST',
credentials: 'include', // sends session cookies for authentication
});
const { signedIdentity } = await resp.json();
// 2. Identify the contact (links to CRM record)
await Bird.contact.identify({
strategy: 'SignedIdentityClaims',
signedIdentity,
});
// 3. Update contact profile (persistent)
await Bird.contact.putAttributes({
displayName: user.fullName,
});
// 4. Set conversation context (per-conversation)
window.mbchat.setAttributes({
currentPage: window.location.pathname,
plan: user.plan,
});
}
</script>Anonymous Visitors
For visitors who haven't logged in, you can still pass conversation context:
Przykład kodu
// No signed identity needed — SDK auto-identifies as Visitor
window.mbchat.setAttributes({
landingPage: document.referrer,
currentPage: window.location.pathname,
utm_source: new URLSearchParams(window.location.search).get('utm_source'),
utm_campaign: new URLSearchParams(window.location.search).get('utm_campaign'),
});You can optionally set a display name on the anonymous contact:
Przykład kodu
await Bird.contact.identify({ strategy: 'Visitor' });
await Bird.contact.putAttributes({ displayName: 'Website Visitor' });Note: If the visitor later logs in and is identified with Signed Identity, Bird will link them to their real CRM record. The anonymous contact's attributes do not automatically transfer to the verified contact.
Visitor Logs In Mid-Session
If a visitor starts chatting anonymously and then logs in:
Przykład kodu
async function onUserLogin(user) {
// Get signed identity from your authenticated backend
// The backend verifies the login and looks up identifiers from its own records
const { signedIdentity } = await fetch('/api/bird-identity', {
method: 'POST',
credentials: 'include',
}).then(r => r.json());
// Re-identify — links contact to real CRM record
await Bird.contact.identify({
strategy: 'SignedIdentityClaims',
signedIdentity,
});
// Update the real contact profile
await Bird.contact.putAttributes({
displayName: user.fullName,
});
// Update conversation context for the next conversation
window.mbchat.setAttributes({
plan: user.plan,
authenticated: 'true',
});
}Important: The conversation that was already in progress keeps its original attributes. New setAttributes() values apply to the next conversation created.
Accessing Attributes in Flows
Both conversation attributes and contact profile data require an explicit step in your Flow to retrieve them.
| Attribute Source | Flow Step Required | Then Access Via |
|---|---|---|
| Conversation attributes | Get Conversation step | conversation.attributes.<key> (e.g. conversation.attributes.userPlan) |
| Contact profile | Fetch Contact step | contact.displayName, contact.attributes.<key> |
Example: Get Conversation step output
After adding a Get Conversation step to your Flow, the conversation attributes are available in the result:
Przykład kodu
{
"attributes": {
"currentPage": "https://example.com/pricing",
"userPlan": "premium",
"userEmail": "demo@example.com",
"source": "support-page"
},
"featuredParticipants": [
{
"displayName": "Demo User",
"type": "contact"
}
]
}Note: The trigger payload contains the conversationId and contactId, but not the full attribute data. Use a Get Conversation or Fetch Contact step to retrieve the details you need.
Signed Identity
Signed Identity is the recommended way to identify contacts in production. It uses a JWT signed by your backend server, ensuring that only your server can assert a visitor's identity.
Security: Always authenticate the user first. Your backend must verify the user's identity (e.g. validate their session token, check their login credentials) before generating a Signed Identity JWT. The signing key should never be exposed to the client. If your endpoint issues JWTs without authentication, any visitor could impersonate any contact.
Setup
To generate signed identities, you need the Signing Key and Issuer from your Bird dashboard:
- Go to Developer > Applications
- Select your application
- Find the Identity Signing Key section on the Overview tab
- Store the signing key securely on your backend (e.g. environment variable or secrets manager) -- never expose it in client-side code
Backend Implementation
Your backend endpoint should:
- Authenticate the request -- verify the user is who they claim to be (session token, cookie, OAuth token, etc.)
- Generate identifiers from your own records -- do not trust identifiers sent from the client
- Sign and return the JWT
Przykład kodu
const crypto = require('crypto');
const ISSUER = process.env.BIRD_ISSUER;
const SIGNING_KEY = process.env.BIRD_SIGNING_KEY;
function makeSignedIdentity(identifiers) {
const header = JSON.stringify({ alg: 'HS256', typ: 'JWT', kid: ISSUER });
const payload = JSON.stringify({ identifiers });
const headerB64 = Buffer.from(header).toString('base64url');
const payloadB64 = Buffer.from(payload).toString('base64url');
const signature = crypto
.createHmac('sha256', SIGNING_KEY)
.update(`${headerB64}.${payloadB64}`)
.digest('base64url');
return `${headerB64}.${payloadB64}.${signature}`;
}
// Express example
app.post('/api/bird-identity', async (req, res) => {
// Step 1: Authenticate the user using YOUR session/auth system
const user = await getUserFromSession(req);
if (!user) {
return res.status(401).json({ error: 'Not authenticated' });
}
// Step 2: Build identifiers from your own trusted user record
// DO NOT use identifiers sent from the client request body
const signedIdentity = makeSignedIdentity([
{ key: 'emailaddress', value: user.email },
{ key: 'externalid', value: user.id },
]);
// Step 3: Return the signed JWT
res.json({ signedIdentity });
});Client-Side Usage
Przykład kodu
async function identifyWithBird() {
// Call YOUR authenticated backend endpoint
const resp = await fetch('/api/bird-identity', {
method: 'POST',
credentials: 'include', // sends session cookies
});
if (!resp.ok) throw new Error('Not authenticated');
const { signedIdentity } = await resp.json();
// Pass the server-signed JWT to Bird
await Bird.contact.identify({
strategy: 'SignedIdentityClaims',
signedIdentity,
});
}For more details, see Signed Identity.
API Reference
Bird.contact.putAttributes(attributes)
Updates the Contact Profile in BirdCRM.
| Parameter | Type | Description |
|---|---|---|
| attributes | Record<string, any> | Key-value pairs to set on the contact |
Returns Promise<ContactResponse>.
Bird.contact.identify(claim)
Identifies the current visitor as a contact.
| Parameter | Type | Description |
|---|---|---|
| claim.strategy | 'Visitor' | 'SignedIdentityClaims' | Identification strategy |
| claim.signedIdentity | string | JWT from your backend (for SignedIdentityClaims) |
| claim.identifier | { key: string, value: string } | Optional identifier (for Visitor) |
Returns Promise<{ contactId: string, accessToken: string }>.
Bird.contact.getCurrent()
Returns the current contact's profile data.
Returns Promise<ContactResponse>.
Bird.contact.reset(options?)
Resets the current session and generates a new anonymous ID.
window.mbchat.setAttributes(attributes)
Sets conversation-level attributes on the chat widget.
| Parameter | Type | Description |
|---|---|---|
| attributes | Record<string, string> | Key-value pairs attached to the next conversation |
These are sent when a new conversation is created through the widget.