Documentation Index
Fetch the complete documentation index at: https://docs.thena.ai/llms.txt
Use this file to discover all available pages before exploring further.
User events are published when users are mentioned in comments or when user-related activities occur. These events enable real-time notification systems and user engagement tracking. These events are delivered through the platform events system.
Developer quickstart
Minimal handler (mentions only)
app.post("/webhook/platform-events", async (req, res) => {
const event = req.body;
if (!event?.eventId || event?.eventType !== "user:mentioned") {
return res.status(200).send("OK");
}
res.status(200).send("OK");
await onUserMentioned(event.payload.user, event.metadata);
});
Checklist
- Respect user notification preferences and quiet hours when sending alerts.
- Enrich notifications with context (linked entity, comment excerpt) for UX.
- De-duplicate multiple mentions in the same comment before notifying.
Event types
user:mentioned
Triggered when a user is mentioned in a comment across any entity type (tickets, account tasks, activities, or notes).
Payload structure:
interface UserMentionEventPayload {
user: {
id: string;
email: string;
name: string;
userType: string;
status: string;
organization: {
id: string;
name: string | null;
};
teams: Array<{
id: string;
name: string;
}>;
metadata?: Record<string, unknown>;
};
}
Event metadata:
interface MentionMetadata {
mentionedUserId: string;
mentionedByUserId: string;
entityId: string;
entityType: string; // "TICKET", "ACCOUNT_TASK", "ACCOUNT_ACTIVITY", "ACCOUNT_NOTE"
commentId: string;
timestamp: string;
organizationId: string;
teamId?: string; // Present for ticket mentions
}
Event structure
User events follow the standard platform event structure:
interface UserEventEnvelope {
eventId: string;
eventType: string; // "user:mentioned"
timestamp: string;
orgId: string;
actor: {
id: string;
type: string;
email: string;
};
payload: UserMentionEventPayload;
metadata: MentionMetadata;
}
Mention context
Entity types
Users can be mentioned in comments on different entity types:
Ticket mentions
- Entity type:
TICKET
- Additional context:
teamId is included in metadata
- Common use cases: Agent collaboration, customer escalation, knowledge sharing
Account task mentions
- Entity type:
ACCOUNT_TASK
- Context: Task collaboration and assignment discussions
- Common use cases: Task handoffs, status updates, collaboration requests
Account activity mentions
- Entity type:
ACCOUNT_ACTIVITY
- Context: Activity discussions and follow-ups
- Common use cases: Activity reviews, next steps planning
Account note mentions
- Entity type:
ACCOUNT_NOTE
- Context: Note discussions and clarifications
- Common use cases: Knowledge sharing, note reviews, clarifications
Event processing
Mention detection
The system automatically detects mentions in comment content using patterns like:
@username
@user.email
@"Full Name"
Deduplication
Multiple users can be mentioned in a single comment, generating separate events for each mentioned user.
Self-mention filtering
Users mentioning themselves may be filtered out based on the ignoreSelf flag in the comment metadata.
Integration examples
Real-time notification system
function handleUserMention(payload) {
const { user, metadata } = payload;
// Get mention context
const context = getMentionContext(metadata.entityType, metadata.entityId);
// Create notification
const notification = {
userId: user.id,
type: 'mention',
title: `You were mentioned by ${payload.actor.name}`,
message: createMentionMessage(context, payload.actor),
actionUrl: generateActionUrl(metadata),
createdAt: new Date(payload.timestamp)
};
// Send real-time notification
sendRealtimeNotification(user.id, notification);
// Send email if user preferences allow
if (await shouldSendEmailNotification(user.id, 'mention')) {
sendMentionEmail(user, notification, context);
}
// Send mobile push notification
if (await shouldSendPushNotification(user.id, 'mention')) {
sendPushNotification(user.id, notification);
}
}
Mention analytics
function trackMentionMetrics(payload) {
const { metadata } = payload;
// Track mention frequency
trackEvent("user_mentioned", {
mentionedUserId: metadata.mentionedUserId,
mentionedByUserId: metadata.mentionedByUserId,
entityType: metadata.entityType,
organizationId: metadata.organizationId,
teamId: metadata.teamId,
timestamp: metadata.timestamp,
});
// Update user engagement scores
updateUserEngagement(metadata.mentionedUserId, {
type: "mention_received",
weight: 1,
});
updateUserEngagement(metadata.mentionedByUserId, {
type: "mention_sent",
weight: 0.5,
});
// Track cross-team collaboration
if (metadata.teamId) {
trackCrossTeamCollaboration(
metadata.mentionedByUserId,
metadata.mentionedUserId,
metadata.teamId,
);
}
}
Smart notification routing
function routeMentionNotification(payload) {
const { user, metadata } = payload;
// Check user availability
const availability = await getUserAvailability(user.id);
if (!availability.isAvailable) {
// User is out of office or busy
if (metadata.entityType === 'TICKET' && isPriorityTicket(metadata.entityId)) {
// Route to team lead for high-priority tickets
const teamLead = await getTeamLead(metadata.teamId);
notifyTeamLead(teamLead, payload, 'user_unavailable');
} else {
// Queue notification for later
queueNotificationForLater(user.id, payload, availability.returnTime);
}
} else {
// User is available, send normal notification
sendImmediateNotification(user.id, payload);
}
}
Mention context enhancement
function enhanceMentionContext(payload) {
const { metadata } = payload;
// Get rich context based on entity type
let context = {};
switch (metadata.entityType) {
case 'TICKET':
context = await getTicketContext(metadata.entityId);
break;
case 'ACCOUNT_TASK':
context = await getAccountTaskContext(metadata.entityId);
break;
case 'ACCOUNT_ACTIVITY':
context = await getAccountActivityContext(metadata.entityId);
break;
case 'ACCOUNT_NOTE':
context = await getAccountNoteContext(metadata.entityId);
break;
}
// Get comment context
const comment = await getComment(metadata.commentId);
// Create enhanced notification
const enhancedPayload = {
...payload,
context: {
entity: context,
comment: {
id: comment.id,
excerpt: truncateText(comment.content, 100),
author: comment.author
},
urgency: calculateUrgency(context, comment),
suggestedActions: generateSuggestedActions(context, comment)
}
};
return enhancedPayload;
}
User preference management
function handleMentionWithPreferences(payload) {
const { user } = payload;
// Get user notification preferences
const preferences = await getUserNotificationPreferences(user.id);
// Check if mentions are enabled
if (!preferences.mentions.enabled) {
logSkippedNotification(user.id, 'mentions_disabled');
return;
}
// Check time-based preferences
if (preferences.mentions.quietHours) {
const now = new Date();
const userTimezone = user.timezone || 'UTC';
if (isInQuietHours(now, preferences.mentions.quietHours, userTimezone)) {
queueNotificationForLater(user.id, payload,
getNextActiveTime(preferences.mentions.quietHours, userTimezone));
return;
}
}
// Check entity-specific preferences
const entityPrefs = preferences.mentions.entityTypes[payload.metadata.entityType];
if (!entityPrefs?.enabled) {
logSkippedNotification(user.id, `mentions_disabled_for_${payload.metadata.entityType}`);
return;
}
// Process mention with user preferences applied
processMentionWithPreferences(payload, preferences);
}
Mention patterns and best practices
Mention syntax support
The platform supports various mention formats:
// Standard username mention
@john.smith
// Email-based mention
@john.smith@company.com
// Display name mention (with quotes for spaces)
@"John Smith"
// Department/role mention (if supported)
@support-team
Integration best practices
- Deduplication: Handle duplicate mentions gracefully
- Rate limiting: Implement rate limiting for mention notifications
- Context preservation: Maintain mention context for better user experience
- Privacy: Respect user privacy settings and availability status
- Fallback handling: Handle cases where mentioned users don’t exist
function optimizeMentionProcessing(payload) {
// Batch process multiple mentions from same comment
const mentionBatch = groupMentionsByComment(payload.metadata.commentId);
// Pre-load user data for all mentions
const userIds = mentionBatch.map(m => m.mentionedUserId);
const users = await batchLoadUsers(userIds);
// Pre-load preferences
const preferences = await batchLoadPreferences(userIds);
// Process all mentions with cached data
mentionBatch.forEach(mention => {
processMentionWithCache(mention, users, preferences);
});
}
Error handling
Common error scenarios
function handleMentionErrors(payload, error) {
switch (error.type) {
case "USER_NOT_FOUND":
// Mentioned user doesn't exist
logInvalidMention(payload.metadata);
notifyCommentAuthor("invalid_mention", payload.metadata);
break;
case "USER_DEACTIVATED":
// Mentioned user is deactivated
logDeactivatedUserMention(payload.metadata);
// Don't send notification
break;
case "NOTIFICATION_SERVICE_DOWN":
// Notification service unavailable
queueMentionForRetry(payload);
break;
case "RATE_LIMIT_EXCEEDED":
// Too many notifications for user
queueMentionForLater(payload);
break;
default:
logMentionError(payload, error);
alertDevelopmentTeam("mention_processing_error", { payload, error });
}
}
Event frequency and scaling
Frequency characteristics
User mention events can vary greatly in frequency:
- Low-volume organizations: Few mentions per day
- High-collaboration teams: Hundreds of mentions per hour
- Customer support teams: Spike during business hours
Scaling considerations
- Batch processing: Group mentions for efficient processing
- Async processing: Handle mention notifications asynchronously
- Caching: Cache user data and preferences for better performance
- Rate limiting: Prevent notification spam
- Monitoring: Track mention processing latency and success rates
Future enhancements
Potential future enhancements to user events:
- Smart mentions: AI-suggested mentions based on context
- Group mentions: Mention entire teams or roles
- Mention threads: Track mention conversation threads
- Mention analytics: Advanced analytics for collaboration patterns
- Custom mention actions: Configurable actions when mentioned