* feat(whatsapp): show contact typing and recording indicators via baileys presence Subscribe to WhatsApp presence updates via the baileys-api provider to display real-time typing and recording indicators in the dashboard. - Handle presence.update webhook events (composing, recording, paused, available) and broadcast via ActionCable - Add conversation.recording event to ActionCable, webhook, and channel listeners for parity with typing_on/typing_off - Show "typing..." / "recording..." in green text on the chat list, replacing the message preview - Show "X is typing" / "X is recording audio" in the conversation view - Add presence_subscribe provider config option (default off) to gate all subscription calls to the baileys-api - Subscribe to presence on conversation open and periodically (1 min) for the top 10 chat list conversations - Consolidate contact LID from presence.update jidAlt payload - Prevent echo-back of contact typing events to the channel Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback - Filter chat list typing indicator to contact-only events - Add dedupe to presence subscribe bulk calls - Use strong parameters for conversation_ids - Remove redundant YAML quotes in swagger webhook enum Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback - Extract phone from data[:id] when JID is @s.whatsapp.net (fallback when jidAlt is absent) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback - Filter recording users in getTypingUsersText to show correct names - Add 10s timeout to presence_subscribe HTTP request Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: scope typing timer per user instead of per conversation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: make presence subscribe best-effort with rescue per channel Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback - Add messagePreviewClass to typing preview for consistent padding - Fix specs to use WebMock assertions instead of instance spying Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
148 lines
3.6 KiB
JSON
148 lines
3.6 KiB
JSON
{
|
|
"CHAT_LIST": {
|
|
"LOADING": "Fetching conversations",
|
|
"LOAD_MORE_CONVERSATIONS": "Load more conversations",
|
|
"EOF": "All conversations loaded 🎉",
|
|
"LIST": {
|
|
"404": "There are no active conversations in this group."
|
|
},
|
|
"FAILED_TO_SEND": "Failed to send",
|
|
"TAB_HEADING": "Conversations",
|
|
"MENTION_HEADING": "Mentions",
|
|
"UNATTENDED_HEADING": "Unattended",
|
|
"SEARCH": {
|
|
"INPUT": "Search for People, Chats, Saved Replies .."
|
|
},
|
|
"FILTER_ALL": "All",
|
|
"ASSIGNEE_TYPE_TABS": {
|
|
"me": "Mine",
|
|
"unassigned": "Unassigned",
|
|
"all": "All"
|
|
},
|
|
"CHAT_STATUS_FILTER_ITEMS": {
|
|
"open": {
|
|
"TEXT": "Open"
|
|
},
|
|
"resolved": {
|
|
"TEXT": "Resolved"
|
|
},
|
|
"pending": {
|
|
"TEXT": "Pending"
|
|
},
|
|
"snoozed": {
|
|
"TEXT": "Snoozed"
|
|
},
|
|
"all": {
|
|
"TEXT": "All"
|
|
}
|
|
},
|
|
"VIEW_FILTER": "View",
|
|
"SORT_TOOLTIP_LABEL": "Sort conversations",
|
|
"CHAT_SORT": {
|
|
"STATUS": "Status",
|
|
"ORDER_BY": "Order by"
|
|
},
|
|
"CHAT_TIME_STAMP": {
|
|
"CREATED": {
|
|
"LATEST": "Created",
|
|
"OLDEST": "Created at:"
|
|
},
|
|
"LAST_ACTIVITY": {
|
|
"NOT_ACTIVE": "Last activity:",
|
|
"ACTIVE": "Last activity"
|
|
}
|
|
},
|
|
"SORT_ORDER_ITEMS": {
|
|
"last_activity_at_asc": {
|
|
"TEXT": "Last activity: Oldest first"
|
|
},
|
|
"last_activity_at_desc": {
|
|
"TEXT": "Last activity: Newest first"
|
|
},
|
|
"created_at_desc": {
|
|
"TEXT": "Created at: Newest first"
|
|
},
|
|
"created_at_asc": {
|
|
"TEXT": "Created at: Oldest first"
|
|
},
|
|
"priority_desc": {
|
|
"TEXT": "Priority: Highest first"
|
|
},
|
|
"priority_asc": {
|
|
"TEXT": "Priority: Lowest first"
|
|
},
|
|
"waiting_since_asc": {
|
|
"TEXT": "Pending Response: Longest first"
|
|
},
|
|
"waiting_since_desc": {
|
|
"TEXT": "Pending Response: Shortest first"
|
|
},
|
|
"priority_desc_created_at_asc": {
|
|
"TEXT": "Priority: Highest first, Created: Oldest first"
|
|
}
|
|
},
|
|
"ATTACHMENTS": {
|
|
"image": {
|
|
"CONTENT": "Picture message"
|
|
},
|
|
"audio": {
|
|
"CONTENT": "Audio message"
|
|
},
|
|
"video": {
|
|
"CONTENT": "Video message"
|
|
},
|
|
"file": {
|
|
"CONTENT": "File Attachment"
|
|
},
|
|
"location": {
|
|
"CONTENT": "Location"
|
|
},
|
|
"ig_reel": {
|
|
"CONTENT": "Instagram Reel"
|
|
},
|
|
"fallback": {
|
|
"CONTENT": "has shared a url"
|
|
},
|
|
"contact": {
|
|
"CONTENT": "Shared contact"
|
|
},
|
|
"embed": {
|
|
"CONTENT": "Embedded content"
|
|
}
|
|
},
|
|
"CHAT_SORT_BY_FILTER": {
|
|
"TITLE": "Sort conversation",
|
|
"DROPDOWN_TITLE": "Sort by",
|
|
"ITEMS": {
|
|
"LATEST": {
|
|
"NAME": "Last activity at",
|
|
"LABEL": "Last activity"
|
|
},
|
|
"CREATED_AT": {
|
|
"NAME": "Created at",
|
|
"LABEL": "Created at"
|
|
},
|
|
"LAST_USER_MESSAGE_AT": {
|
|
"NAME": "Last user message at",
|
|
"LABEL": "Last message"
|
|
}
|
|
}
|
|
},
|
|
"RECEIVED_VIA_EMAIL": "Received via email",
|
|
"VIEW_TWEET_IN_TWITTER": "View tweet in Twitter",
|
|
"REPLY_TO_TWEET": "Reply to this tweet",
|
|
"LINK_TO_STORY": "Go to instagram story",
|
|
"SENT": "Sent successfully",
|
|
"READ": "Read successfully",
|
|
"DELIVERED": "Delivered successfully",
|
|
"NO_MESSAGES": "No Messages",
|
|
"TYPING": "typing...",
|
|
"RECORDING": "recording...",
|
|
"NO_CONTENT": "No content available",
|
|
"HIDE_QUOTED_TEXT": "Hide Quoted Text",
|
|
"SHOW_QUOTED_TEXT": "Show Quoted Text",
|
|
"MESSAGE_READ": "Read",
|
|
"SENDING": "Sending"
|
|
}
|
|
}
|