* feat: add group and conversation types to contacts and conversations, and implement conversation group membership model * chore: add factory and specs for conversation group member model * chore: add group type checks and associations for contacts and conversations * refactor: remove scopes from ConversationGroupMember model * refactor: remove scopes from ConversationGroupMember model specs * refactor: enhance conversation type migration with concurrent indexing * feat: add is_active index and scopes to ConversationGroupMember model * feat: implement GroupConversationHandler for managing group conversations * feat: add group_type attribute to contact creation * fix: update WHATSAPP_CHANNEL_REGEX to allow up to 20 digits to handle group jid * feat: handle group JID format in remote_jid method * chore: update group contact info when finding or creating group contact * chore: refactor and implement contact message handling and message creation logic for baileys single contact conversation * feat: implement group message handling and metadata fetching in WhatsApp service * chore: add spec for group type handling in contact creation for individual and group contacts * chore: add specs for test scopes in conversation group members * chore: update documentation for sender phone extraction in group conversation handler * chore: move GroupConversationHandler concern to correct dir * chore: implement specs for recipient_id handling to individual and group contacts * chore: add group message handling specs for incoming messages * chore: enhance group message handling to prevent race conditions * chore: add group_metadata method to with error handling * chore: add test for sending messages to group recipients in WhatsappBaileysService * chore: raise error for unsuccessful response in group_metadata method * chore: adds tests for group metadata retrieval and error handling * chore: refactor build_sender_contact_attributes to avoid double call methods * chore: update error handling for attachment download failure in message creation * chore: optimize update_contact_info method to use compact hash for updates * chore: simplify find_or_create_sender_contact method return values * chore: rename group and individual contact message handlers * chore: remove pointless comments from group contact message handler methods * chore: refine sender JID extraction logic to remove unnecessary checks * chore: remove phone number in spec for group contact attributes * chore: implement sync_group route * chore: implement get group_members route * fix: sync_group participants creation handling * chore: update contact avatar handling in group message processing * chore: move sync_group functionality for conversation model * feat: add sync_group action to ConversationsController and route * fix: set contact name to phone in group message processing * chore: refine group member retrieval logic in sync_group service and view * feat: implement group participants update handling * feat: implement group updates handling and localization for group activities * chore: add handling for group membership requests and icon changes * chore: add authorization for sync_group action in ContactsController * chore: add sync_group endpoint specs for contact management * chore: add authorization for sync_group action in ConversationsController * chore: add specs for sync_group endpoint in ConversationsController * chore: refactor index action in GroupMembersController for improved conversation filtering * chore: add request specs for group_members endpoint in ContactsController * chore: add specs for sync_group method in Conversation model * chore: add specs for sync_group method in Channel::Whatsapp model * chore: remove comments in find_or_create_group_conversation method * chore: add specs for Contacts::SyncGroupService to validate group contact behavior * chore: add specs for Whatsapp::BaileysHandlers::GroupsUpdate to validate group updates * chore: add specs for Whatsapp::BaileysHandlers::GroupParticipantsUpdate to handle group participant actions * chore: add fallback for identifier when contact has no phone_number in SendOnWhatsappService * chore: add specs for group membership request and icon change handling in MessagesUpsert * chore: add specs for sync_group method to handle group metadata and participant updates * chore: update sync_group method to retrieve group members and adjust JSON response * chore: update conversation query to filter by group type in GroupMembersController * chore: update conversation creation in group_members_controller_spec to specify conversation_type as group * chore: update find_or_create_group_conversation to include pending conversations * chore: refactor sync_group method and enhance specs for group conversation handling * feat: add GroupEventHelper module for managing group activities and contacts * chore: refactor group contact inbox and conversation creation methods in group handlers * chore: remove unnecessary check for blank participant contacts in sync_group_members method * feat: implement message receipt update handling for WhatsApp integration * chore: resolve rubocop rule for update_last_seen_at method * chore: update swagger with endpoints for syncing group information and listing group members * chore: integrate Contacts::SyncGroupService in group members controller, enhance error handling and update swagger * chore: include participant information in reaction and quoted message keys for send message in group conversations * chore: enhance whatsapp_baileys_service with participant handling for message keys * feat: add skill for writing RSpec tests in the project * fix: update recipient_id logic to directly use contact identifier for group contacts * chore: implement group stub message handling for membership requests and icon changes * fix: update whatsapp inbox source_id validation regex spec * chore: fix spec for contact syncing group * chore: remove readTimestamp handling and related tests for message read updates in group * Cayo oliveira/cu 86af01932/4 backend gerenciamento dos grupos (#221) * feat: add is_active index and scopes to ConversationGroupMember model * feat: implement GroupConversationHandler for managing group conversations * feat: add group_type attribute to contact creation * fix: update WHATSAPP_CHANNEL_REGEX to allow up to 20 digits to handle group jid * feat: handle group JID format in remote_jid method * chore: update group contact info when finding or creating group contact * chore: refactor and implement contact message handling and message creation logic for baileys single contact conversation * feat: implement group message handling and metadata fetching in WhatsApp service * chore: add spec for group type handling in contact creation for individual and group contacts * chore: add specs for test scopes in conversation group members * chore: update documentation for sender phone extraction in group conversation handler * chore: move GroupConversationHandler concern to correct dir * chore: implement specs for recipient_id handling to individual and group contacts * chore: add group message handling specs for incoming messages * chore: enhance group message handling to prevent race conditions * chore: add group_metadata method to with error handling * chore: add test for sending messages to group recipients in WhatsappBaileysService * chore: raise error for unsuccessful response in group_metadata method * chore: adds tests for group metadata retrieval and error handling * chore: refactor build_sender_contact_attributes to avoid double call methods * chore: update error handling for attachment download failure in message creation * chore: optimize update_contact_info method to use compact hash for updates * chore: simplify find_or_create_sender_contact method return values * chore: rename group and individual contact message handlers * chore: remove pointless comments from group contact message handler methods * chore: refine sender JID extraction logic to remove unnecessary checks * chore: remove phone number in spec for group contact attributes * chore: implement sync_group route * chore: implement get group_members route * fix: sync_group participants creation handling * chore: update contact avatar handling in group message processing * chore: move sync_group functionality for conversation model * feat: add sync_group action to ConversationsController and route * fix: set contact name to phone in group message processing * chore: refine group member retrieval logic in sync_group service and view * feat: implement group participants update handling * feat: implement group updates handling and localization for group activities * chore: add handling for group membership requests and icon changes * chore: add authorization for sync_group action in ContactsController * chore: add sync_group endpoint specs for contact management * chore: add authorization for sync_group action in ConversationsController * chore: add specs for sync_group endpoint in ConversationsController * chore: refactor index action in GroupMembersController for improved conversation filtering * chore: add request specs for group_members endpoint in ContactsController * chore: add specs for sync_group method in Conversation model * chore: add specs for sync_group method in Channel::Whatsapp model * chore: remove comments in find_or_create_group_conversation method * chore: add specs for Contacts::SyncGroupService to validate group contact behavior * chore: add specs for Whatsapp::BaileysHandlers::GroupsUpdate to validate group updates * chore: add specs for Whatsapp::BaileysHandlers::GroupParticipantsUpdate to handle group participant actions * chore: add fallback for identifier when contact has no phone_number in SendOnWhatsappService * chore: add specs for group membership request and icon change handling in MessagesUpsert * chore: add specs for sync_group method to handle group metadata and participant updates * chore: update sync_group method to retrieve group members and adjust JSON response * chore: update conversation query to filter by group type in GroupMembersController * chore: update conversation creation in group_members_controller_spec to specify conversation_type as group * chore: update find_or_create_group_conversation to include pending conversations * chore: refactor sync_group method and enhance specs for group conversation handling * feat: add GroupEventHelper module for managing group activities and contacts * chore: refactor group contact inbox and conversation creation methods in group handlers * chore: remove unnecessary check for blank participant contacts in sync_group_members method * chore: update swagger with endpoints for syncing group information and listing group members * chore: integrate Contacts::SyncGroupService in group members controller, enhance error handling and update swagger * fix: update recipient_id logic to directly use contact identifier for group contacts * chore: implement group stub message handling for membership requests and icon changes * fix: update whatsapp inbox source_id validation regex spec * chore: fix spec for contact syncing group * fix: optimize update_last_seen_at method to use update_columns * feat: Implement full frontend and backend support for group conversations - Added PRD for group conversations detailing frontend and backend requirements. - Created new Baileys TypeScript definitions for group-related functions. - Renamed `conversation_type` to `group_type` in the database and updated all references. - Implemented API serialization for `group_type` in conversation and contact responses. - Developed Vuex store module for managing group members. - Created UI components for group management, including group creation, member management, and metadata editing. - Integrated @mention functionality for group conversations and real-time updates via ActionCable. * feat: [US-001] - Rename conversation_type to group_type on conversations - Add migration to rename column and indexes - Update Conversation model enum to group_type - Update GroupConversationHandler concern - Update controllers (contacts, group_members) - Update all backend specs * chore: mark US-001 complete, update progress log, fix rubocop annotation * feat: [US-002] - Serialize group_type fields in API responses * feat: [US-003] - Add group_type filter to conversations index * feat: [US-004] - Add group_type to filter_keys.yml and FilterService * feat: US-005 - Backend group creation endpoint - Add POST /api/v1/accounts/:account_id/groups endpoint - Add Groups::CreateService to orchestrate Baileys group creation - Extend WhatsappBaileysService and BaseService with group management methods - Add routes for group members, metadata, invite, and join requests - Returns 403 when agent lacks inbox access, 422 when provider is unavailable * feat: US-006 - Backend add/remove members and role management endpoints - Add create/destroy/update actions to GroupMembersController - Delegate group management methods from Channel::Whatsapp to provider_service - create adds members via Baileys and creates ConversationGroupMember records - destroy removes a member by ID and sets is_active false - update promotes/demotes a member and updates their role * feat: US-007 - Backend group metadata update endpoint - Add PATCH /contacts/:id/group_metadata endpoint - Updates group subject via Baileys and syncs contact name - Updates group description via Baileys and syncs additional_attributes.description - Returns 422 when provider is unavailable * feat: US-008 - Backend invite link management endpoints - Add GET /contacts/:id/group_invite to retrieve current invite code/url - Add POST /contacts/:id/group_invite/revoke to revoke and get new invite code/url - Returns 422 when provider is unavailable * feat: US-009 - Backend join request management endpoints - Add GET /contacts/:id/group_join_requests to list pending join requests - Add POST /contacts/:id/group_join_requests/handle to approve/reject requests - Uses request_action param to avoid conflict with Rails reserved params[:action] - Returns 422 when provider is unavailable * feat: US-010 - Extend MentionService for contact mentions - Extract mention://contact/ID/Name URIs from message content - Store mentioned contact IDs in message.content_attributes[mentioned_contacts] - Existing user/team mention handling unchanged * feat: US-011 - Frontend API clients for all group endpoints - Add app/javascript/dashboard/api/groupMembers.js - Exports 11 methods: getGroupMembers, syncGroup, createGroup, updateGroupMetadata, addMembers, removeMembers, updateMemberRole, getInviteLink, revokeInviteLink, getPendingRequests, handleJoinRequest * feat: US-012 - Frontend Vuex store module groupMembers - Add groupMembers store module with fetch, sync, addMembers, removeMembers, updateMemberRole actions - Add SET_GROUP_MEMBERS and SET_GROUP_MEMBERS_UI_FLAG mutation types - Register module in store index * feat: US-013 - Frontend i18n keys for group features - Add groups.json with keys for group info, filter, creation modal, metadata editing, invite link, member management, join requests, and mention dropdown - Register groups.json in i18n locale en/index.js Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: US-014 - Frontend group_type filter in ConversationBasicFilter - Add chatGroupTypeFilter state, getter, mutation, and action to conversations store - Add getChatGroupTypeFilter getter - Add group_type param to ConversationApi.get() - Add Type filter section to ConversationBasicFilter with All/Individual/Group options - Persist group_type to UI settings under conversations_filter_by.group_type - Restore group_type from UI settings on page load - Include groupType in conversationFilters and pass as group_type param to API Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: US-013 - Frontend — i18n keys for group features (en + pt-BR) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: [US-014] - Frontend — add group_type filter to ConversationBasicFilter All implementation was already in place from prior work: - ConversationBasicFilter.vue has Type section with All/Individual/Group options - ChatList.vue handles group_type in conversationFilters and restores from UI settings - Store has setChatGroupTypeFilter action, getChatGroupTypeFilter getter - API maps groupType → group_type query param Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-015 - Frontend — add group_type to advanced filter system - Add GROUP_TYPE to CONVERSATION_ATTRIBUTES in filterHelper.js - Add group_type filter definition in provider.js (components-next) - Add group_type to legacy advancedFilterItems/index.js and filterAttributeGroups - Add group_type to automationHelper conditionFilterMaps - Add group_type to customViewsHelper getValuesForFilter - Add group_type options to ChatList setParamsForEditFolderModal - Add GROUP_TYPE i18n key in en and pt_BR advancedFilters.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-016 - Frontend — GroupContactInfo basic display Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-017 - Frontend — GroupContactInfo sync button Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-018 - integrate GroupContactInfo in ContactPanel - Import GroupContactInfo component - Conditionally render GroupContactInfo when group_type === 'group' - Keep ContactInfo for individual conversations (no regression) - Dynamic sidebar title: 'Group' for groups, 'Contact' for individual - contact_notes and contact_attributes accordion sections unchanged Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-019 - Frontend — group creation UI modal Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-020 - Frontend — member management UI in GroupContactInfo Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-021 - Frontend — group metadata editing UI Add inline editing for group name, description, and avatar in GroupContactInfo: - Click group name to edit inline, save on Enter/blur - Click description to edit inline with textarea, save on blur - Click avatar to open file picker for upload via contacts/update - Loading states on all fields during save - Success/error alerts for all operations - updateGroupMetadata action added to groupMembers store Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-022 - Frontend — invite link management UI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-023 - Frontend — join request management UI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-024 - Frontend — group message bubbles: sender name with color - Add sender name display above incoming message bubbles in group conversations - Deterministic color per sender using AVATAR_COLORS palette (name.length % 6) - Sender name hidden for consecutive messages from the same sender - Individual conversation bubbles unchanged - Pass groupWithPrevious and isGroupConversation props through MessageList → Message Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-025 - Frontend — group message bubbles: sender avatar Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: Add Ralph Wiggum AI agent script for managing tool execution and progress tracking * feat: US-026 - Frontend — @mention dropdown for group conversations - Create TagGroupMembers.vue component for group member mention suggestions - Modify Editor.vue: add isGroupConversation/groupContactId props, render TagGroupMembers for group non-private context - Modify ReplyBox.vue: compute isGroupConversation and groupContactId from currentChat, pass to WootMessageEditor - @ mention plugin isAllowed now triggers for group conversations - In individual conversations or private notes, existing behavior unchanged Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-027 - Frontend — mention rendering in group message bubbles Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-028 - Frontend ActionCable handler for contact.group_synced event - Backend: Include group_members data in contact.group_synced ActionCable payload - Frontend: Register contact.group_synced handler in ActionCableConnector - Frontend: Add setGroupMembers action to groupMembers store for direct commits - Tests: ActionCable handler spec + groupMembers store spec for new action Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: Update progress tracking for group conversations feature - mark tests as passing * fix: sender click case mismatch and filter dropdown spacing - Message.vue: use case-insensitive comparison for sender type check (Contact.push_event_data returns 'contact' but SENDER_TYPES.CONTACT is 'Contact') - ConversationBasicFilter.vue: replace last:mt-4 with flex-col gap-4 for consistent spacing between all three filter sections * fix: four bugs found during manual testing review - ContactPanel.vue: fix i18n key GROUP.INFO.SIDEBAR_TITLE → GROUP.SIDEBAR_TITLE - groupMembers.js API: fix syncGroup HTTP method GET → POST to match backend route - group_members_controller.rb: remove SyncGroupService from index action - filterHelpers.js: add missing group_type case to getValueFromConversation * docs: update progress with bug fix learnings * chore: implement group creation functionality in UI components * chore: add copy invite link functionality and update UI components * feat: US-041 - Backend — ensure group_type is set on existing contacts and conversations GroupConversationHandler#update_group_contact_info now sets group_type: :group on contacts that are incorrectly typed as individual. GroupConversationHandler#find_or_create_group_conversation updates existing conversation's group_type to :group if it is currently :individual. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: mark US-041 as complete Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-029 - i18n keys for You badge and group settings (en + pt-BR) All i18n keys already existed from prior iterations. Verified presence and updated PRD status. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-030 - fix Baileys API route/method mismatches Fix on_whatsapp to dig('data') before accessing first element. Update spec stubs to match { data: [...] } response envelope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-031 - group_leave, group_setting_update, group_join_approval_mode methods All methods, delegates, and error handling already implemented. Verified specs pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-032 - persist group settings, invite code, and profile picture during sync Add try_update_group_avatar to fetch and attach group profile picture during sync_group. Update spec stubs for profile-picture-url endpoint. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-033 - GroupSettingsController with leave, update, toggle Controller and routes already implemented. Verified rubocop passes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-034 - remove inbox_contact_id from provider_config and jbuilder Already removed in prior iterations. Verified no references remain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-035 - refactor TagGroupMembers to phone_number matching Already implemented. Verified excludePhoneNumber prop and filtering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-036 - remove InboxContact.vue and settings tab Already removed in prior iterations. Verified no references remain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-037 - add You badge in GroupContactInfo member list Already implemented with isOwnMember check and blue badge styling. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-038 - fix inline edit for group name and description Already implemented with phone number normalization. Verified code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-039 - group settings section UI with toggles Already implemented. Settings toggles, API calls, and i18n verified. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-040 - leave group UI with confirmation and auto-resolve Already implemented. Leave button, confirmation, and API call verified. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-050 - Create GroupMember model and migration New group_members table with group_contact_id, contact_id, role, is_active. Unique index on (group_contact_id, contact_id). Associations added to Contact. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-064 - Helper method to find channel from group contact Add Contact#group_channel to decouple channel lookup from conversations. Update GroupMembersController and GroupSettingsController to use it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-052 - Update GroupConversationHandler to use GroupMember Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-057 - Update GroupMembersController to query GroupMember Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-058 - Update GroupSettingsController to not depend on conversations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-060 - Update group_members jbuilder views Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-059 - Remove group_members association from Conversation model Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: US-051 - Remove ConversationGroupMember model and table Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: mark all stories complete, update progress Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(groups): real-time group panel, avatar refresh on icon change, editable name/description - Add group_type to Conversations::EventDataPresenter#push_data and Contact#push_event_data so WebSocket events carry the field, enabling the frontend to switch to GroupContactInfo in real-time - Update handle_icon_change_stub to call try_update_group_avatar with force: true, purging the cached avatar and fetching the new one - Add force parameter to try_update_group_avatar to support re-fetching - Remove isInboxAdmin gate from name/description editing in GroupContactInfo so any user can click to edit (server validates) * fix(groups): rewrite SyncGroupService and simplify group metadata channel lookup - Rewrite SyncGroupService to use contact.group_channel directly instead of iterating conversations; find or create a conversation for sync - Simplify GroupMetadataController to use @contact.group_channel instead of querying conversations; remove local contact/attribute updates since the Baileys API handles persistence via webhook events * feat(groups): resolve conversations when inbox phone leaves or is removed - Add resolve_conversations_if_inbox_left to GroupParticipantsUpdate - Resolves all open/pending conversations when the inbox phone number is removed from or leaves a group * feat(groups): add paginated member list with infinite scroll - Backend: add pagination to GroupMembersController (page/per_page, default 10, ordered admins first); add meta with pagination info to the jbuilder response - Frontend: update groupMembers API to accept page param; add APPEND_GROUP_MEMBERS and SET_GROUP_MEMBERS_META mutations; implement paginated fetch with append and isFetchingMore flag in store * feat(groups): support Ctrl+Click on group message sender to open in new tab - navigateToGroupSender now accepts the event and checks for Ctrl/Cmd+Click to open the sender contact in a new tab * chore(i18n): update leave group confirmation text in en and pt_BR * fix(groups): handle phone format differences in You badge and admin detection - Extract phonesMatch helper that compares last 8 digits as fallback, handling Brazilian 9th digit discrepancy (e.g. +5587988465072 vs +558788465072) - Apply to both isOwnMember and isInboxAdmin computed properties * feat(groups): auto-sync members on mount, show existing members immediately - On mount, fetch existing DB members first so they display instantly - Then silently attempt a background sync to refresh from WhatsApp - If sync fails (e.g. WhatsApp disconnected), existing members remain displayed without any user-facing error * fix(groups): pin own member on first page and return inbox phone in meta The "You" badge was not appearing because the inbox's own member could be missing from the first paginated page in large groups (admins sorted first). Backend: - Pin the inbox's own member at the top of page 1 regardless of sort order - Return inbox_phone_number in the group members meta response - Use last-8-digit SQL fallback for Brazilian 9th-digit phone mismatches Frontend: - Use meta.inbox_phone_number for the inboxPhone computed - Fix declaration order to satisfy no-use-before-define lint rule * fix(groups): fix member action dropdown clipped by overflow container The promote/demote/remove dropdown menu was invisible because the member list had `overflow-y-auto max-h-80`, clipping any absolutely-positioned dropdown rendered inside it. - Remove overflow container from member list; let the sidebar scroll - Replace scroll-based infinite loading with IntersectionObserver on a sentinel element for cleaner pagination trigger - All member action logic (promote, demote, remove) was already wired; the dropdown is now visible on hover * fix(groups): keep member action dropdown visible when menu is open The opacity-0/group-hover classes on the action menu wrapper caused the DropdownMenu to become invisible as soon as the mouse left the row. Now the wrapper stays fully opaque while the menu is active. * fix(groups): move clickaway to member list wrapper to prevent instant close v-on-clickaway was bound to every member's action div individually. Clicking the three-dot button on one member fired closeMemberMenu from all other members' clickaway handlers, closing the menu instantly. Moved the directive to the single member list container instead. * feat: add WhatsApp mention conversion (incoming + outgoing) - New MentionConverterService for bidirectional mention handling - Incoming: converts @phone/mentionedJid to mention://contact/ URIs - Outgoing: extracts mention://contact/ URIs into WhatsApp mentions array - Supports @everyone/todos group mentions - WhatsApp renderer preserves mention display text instead of raw URI * fix: preserve mention display text in WhatsApp renderer mention:// URIs now render as display name text instead of the raw URL when converting markdown to WhatsApp format * feat: add @everyone mention option in group conversations - Everyone item shown at top of mention dropdown - Searchable by 'all', 'todos', 'everyone' keywords - i18n keys added for en and pt-BR * refactor: use Switch component for group settings toggles - Add disabled prop to Switch component - Replace custom toggle buttons in GroupContactInfo with Switch - Loading spinner shown alongside toggle while toggling * feat(whatsapp): add group sync status tracking (group_left, group_last_synced_at) * feat(whatsapp): hide group management UI when group_left is true * fix(groupMembers): include inbox phone number in group members state and sync event * feat(whatsapp): wrap group settings and leave in Accordion component * feat(groupMembers): handle group creator modification errors and update error messages * feat(groupMembers): enhance invite link functionality and clean up UI state after copying * refactor: remove sync_group functionality from conversations and related specs * feat(GroupContactInfo): implement scroll-based loading for group members * docs(swagger): add group API endpoints and remove conversation sync_group - Remove dead conversation/{id}/sync_group swagger entry and file - Update group_members.yml with pagination params, POST operation, and $ref schema - Add swagger for: group_members_member (PATCH/DELETE), group_metadata, group_invite, group_invite_revoke, group_join_requests, group_join_requests_handle, group_settings, group_settings_leave, group_settings_toggle_join_approval, groups/create - Add group_member schema definition - Add Groups tag to application tag_groups - Register all 12 group endpoints in paths/index.yml * feat(WhatsappBaileysService): enhance mention handling by replacing @DisplayName with @lid/@phone in outgoing text * feat(groups): move group sync to background job with 15-min cooldown - Create Contacts::SyncGroupJob that checks group_last_synced_at before calling SyncGroupService (skips if < 15 min) - Controller sync_group now enqueues the job and returns 202 Accepted - Delete sync_group.json.jbuilder (no longer needed) - Frontend sync action is fire-and-forget; results via ActionCable - Auto-trigger sync on conversation select and panel mount - Remove manual sync button from GroupContactInfo * fix: show group members list even after leaving group\n\nKeep the members section visible in read-only mode when\ngroup_left is true. Admin actions (add member, promote,\ndemote, remove) remain hidden. Pending Join Requests and\nAdvanced Options also stay hidden. * fix: disable group name/description/avatar editing when group_left is true * fix: remove @all mention and fix Enter key in group mention dropdown\n\n- Remove the @all/everyone special mention from TagGroupMembers since\n no channel provider currently supports mentioning all participants\n- Fix Enter key sending message instead of inserting selected mention\n in group conversations. The root cause was Editor.vue only emitting\n toggleUserMention=true for private notes (isPrivate), leaving\n ReplyBox unaware the group mention dropdown was open. Now also\n emits for isGroupConversation.\n- Add TagGroupMembers spec covering filtering, exclusion, and emission" * fix: address PR review feedback for group conversations - Fix nil safety in group_invites and group_join_requests controllers by replacing group_conversation.inbox.channel with @contact.group_channel - Add before_action guard in group_members_controller to validate contact is a group with identifier before create/update/destroy - Persist metadata locally in group_metadata_controller after provider calls (subject -> name, description -> additional_attributes) - Add server-side allow_group_creation? check in groups_controller - Add word boundary to mention regex to prevent matching inside words - Remove useless catch clauses in groupMembers store (try/finally only) - Default groupType to [] in customViewsHelper to prevent crash - Fix swagger parameter name mismatch (contact_id -> id) across all group endpoint YML files for consistency * fix: address PR #228 review feedback - strong params, guards, and safety fixes * fix: dispatch real-time events for Baileys group participant and metadata updates Both group-participants.update and groups.update handlers were updating backend data (GroupMember records, Contact attributes) but never dispatching ActionCable events, leaving the frontend member list and group metadata stale until manual sync. Changes: - Add dispatch_group_synced_event helper to GroupEventHelper concern - Dispatch CONTACT_GROUP_SYNCED after participant add/remove/promote/demote - Dispatch CONTACT_GROUP_SYNCED after group subject/description/settings changes - Frontend: onContactGroupSynced also dispatches contacts/updateContact to refresh group name, description and settings in the sidebar * fix: enhance member menu positioning and close behavior on sidebar scroll * feat: implement group property updates and enhance toast notifications * fix: update WhatsApp channel regex to allow optional hyphenated numbers * feat: implement group admin functionalities including leave, update properties, and toggle join approval * refactor: simplify group message handling by removing metadata fetching and syncing methods * chore: remove raph files * feat: update Portuguese translations for 'Read More' and 'Insert Read More' phrases * feat: enhance group admin functionalities with join approval and member add modes * feat: enhance group join request handling by adding removal of handled requests and updating pending join requests * feat: restrict message sending in announcement mode groups When a Baileys WhatsApp group has announcement mode enabled (announce=true), only admin members can send messages. This adds: - Frontend: disabled editor + banner for non-admin inbox in announcement groups - Backend: validation in SendOnWhatsappService to reject messages - Shared phone helper utility extracted from GroupContactInfo - i18n keys for en and pt_BR * feat: add group sync job enqueueing and improve avatar update handling * feat: add functionality to reset invite link and confirm member addition restrictions * feat: update group name extraction logic to handle nil values * feat: add inbox admin status handling and update related components * feat: remove group conversation resolution on leave action * feat: enhance group sender avatar interaction with tooltip and cursor pointer * feat: add force option to SyncGroupJob and update related specs * feat: enhance invite link handling and avatar update logic in group conversations * chore: remove prd.json * fix: change group sender name display from block to inline-block for better layout * feat: add group members loading check and fetch logic in MessagesView and ReplyBox components * feat: allow id and firstUnreadId props to accept both Number and String types feat: add vOnClickOutside import to Editor component feat: enhance Portuguese translations for integrations and settings fix: change button color in GroupContactInfo component from green to teal * feat: soft-disabled group conversations with activity tracking Groups start in a soft-disabled state by default when using Baileys. Chatwoot still creates group conversations but does not process every incoming message. Instead, Baileys accumulates group messages and sends periodic groups.activity webhook events to update last_activity_at. Backend: - Add WHATSAPP_GROUPS_ENABLED env var and groups_enabled? class method - Send groupsEnabled in Baileys connection setup - Create groups.activity handler to update conversation last_activity_at - Gate group message processing behind groups_enabled? check - Expose groups_enabled via inbox API Frontend: - Add warning banner with CTA to app.fazer.ai on disabled group conversations - Disable reply editor for non-private-note mode when groups disabled - Add i18n strings for en and pt_BR Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use method for groups disabled banner action to avoid window scope issue Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: broadcast conversation update after groups.activity event update_columns bypasses ActiveRecord callbacks, so the ActionCable broadcast was never triggered when last_activity_at changed. Dispatch a CONVERSATION_UPDATED event explicitly so the sidebar updates in real-time. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: show unread dot for soft-disabled group conversations with activity Since soft-disabled groups don't create messages, unread_count is always 0 and the standard badge won't show. Detect unread state by comparing last_activity_at > agent_last_seen_at for these groups and display a teal dot indicator instead of a count badge. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: clear unread dot when agent opens soft-disabled group conversation The update_last_seen endpoint skipped updating agent_last_seen_at when there were no unread messages (the throttle path). For soft-disabled groups that never create messages, this meant the dot indicator could never be cleared. Add an unseen_activity? check that bypasses the throttle when last_activity_at > agent_last_seen_at. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: group avatar upload to provider and fix icon change sync - Route avatar upload through GroupMetadataController to push to WhatsApp provider before saving locally - Add update_group_picture to baileys service and base service - Fix buildContactFormData crash when social_profiles is undefined - Make try_update_group_avatar public so GROUP_CHANGE_ICON stub handler can call it from outside the service class Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update specs for group conversations feature changes - Add groupsEnabled param to setup_channel_provider and handle_channel_error WebMock stubs - Add group-request-participants-list stub for sync_group tests - Add group_type to push_event_data expected hash - Set last_activity_at in throttle tests to prevent unseen_activity? bypass - Update sync_group delegation expectation to include soft: false - Stub groups_enabled? in group message handling tests - Update WhatsApp source_id regex expectation for group contact IDs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add settings file for additional directories configuration * chore: undo unrelated changes * chore: remove planning doc, fix migration version, fix swagger param consistency - Remove planejamento-chat-interno.md (unrelated planning document) - Fix CreateGroupMembers migration API version from 7.0 to 7.1 - Fix swagger.json: normalize group endpoint paths from {contact_id} to {id} to match YAML sources and existing contact sub-resource conventions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CayoPOliveira <cayoproliveira@gmail.com> Co-authored-by: Cayo P. R. Oliveira <cayo@fazer.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
999 lines
45 KiB
JSON
999 lines
45 KiB
JSON
{
|
|
"INTEGRATION_SETTINGS": {
|
|
"SHOPIFY": {
|
|
"DELETE": {
|
|
"TITLE": "Delete Shopify Integration",
|
|
"MESSAGE": "Are you sure you want to delete the Shopify integration?"
|
|
},
|
|
"STORE_URL": {
|
|
"TITLE": "Connect Shopify Store",
|
|
"LABEL": "Store URL",
|
|
"PLACEHOLDER": "your-store.myshopify.com",
|
|
"HELP": "Enter your Shopify store's myshopify.com URL",
|
|
"CANCEL": "Cancelar",
|
|
"SUBMIT": "Connect Store"
|
|
},
|
|
"ERROR": "There was an error connecting to Shopify. Please try again or contact support if the issue persists."
|
|
},
|
|
"HEADER": "Integrações",
|
|
"DESCRIPTION": "Chatwoot se integra com várias ferramentas e serviços para melhorar a eficiência de seu time. Explore a lista abaixo para configurar seus aplicativos favoritos.",
|
|
"LEARN_MORE": "Aprenda mais sobre integrações",
|
|
"LOADING": "Obtendo integrações",
|
|
"CAPTAIN": {
|
|
"DISABLED": "O capitão não está ativado na sua conta.",
|
|
"CLICK_HERE_TO_CONFIGURE": "Clique aqui para configurar",
|
|
"LOADING_CONSOLE": "Carregando console do Capitão...",
|
|
"FAILED_TO_LOAD_CONSOLE": "Falha ao carregar o Console do Capitão. Atualize e tente novamente."
|
|
},
|
|
"WEBHOOK": {
|
|
"SUBSCRIBED_EVENTS": "Eventos Inscritos",
|
|
"LEARN_MORE": "Saiba mais sobre webhooks",
|
|
"FORM": {
|
|
"CANCEL": "Cancelar",
|
|
"DESC": "Webhook Os eventos fornecem informações em tempo real sobre o que está acontecendo na sua conta do Chatwoot. Digite um URL válido para configurar um retorno de chamada.",
|
|
"SUBSCRIPTIONS": {
|
|
"LABEL": "Eventos",
|
|
"EVENTS": {
|
|
"CONVERSATION_CREATED": "Conversa Criada",
|
|
"CONVERSATION_STATUS_CHANGED": "Status de conversa alterado",
|
|
"CONVERSATION_UPDATED": "Conversa Atualizada",
|
|
"MESSAGE_CREATED": "Mensagem criada",
|
|
"MESSAGE_INCOMING": "Mensagem recebida",
|
|
"MESSAGE_OUTGOING": "Mensagem enviada",
|
|
"MESSAGE_UPDATED": "Mensagem atualizada",
|
|
"WEBWIDGET_TRIGGERED": "Widget de chat aberto pelo usuário",
|
|
"CONTACT_CREATED": "Contato criado",
|
|
"CONTACT_UPDATED": "Contato atualizado",
|
|
"CONVERSATION_TYPING_ON": "Status de Digitação ativado",
|
|
"CONVERSATION_TYPING_OFF": "Status de Digitação desativado",
|
|
"PROVIDER_EVENT_RECEIVED": "Evento do Provedor Recebido"
|
|
}
|
|
},
|
|
"NAME": {
|
|
"LABEL": "Nome do Webhook",
|
|
"PLACEHOLDER": "Insira o nome do webhook"
|
|
},
|
|
"INBOX": {
|
|
"LABEL": "Caixa de Entrada",
|
|
"TITLE": "Selecione a caixa de entrada",
|
|
"PLACEHOLDER": "Todas as caixas de entrada",
|
|
"NO_RESULTS": "Nenhuma caixa de entrada encontrada",
|
|
"INPUT_PLACEHOLDER": "Buscar caixa de entrada"
|
|
},
|
|
"END_POINT": {
|
|
"LABEL": "URL do Webhook",
|
|
"PLACEHOLDER": "Exemplo: {webhookExampleURL}",
|
|
"ERROR": "Por favor, insira uma URL válida"
|
|
},
|
|
"EDIT_SUBMIT": "Atualizar webhook",
|
|
"ADD_SUBMIT": "Criar webhook"
|
|
},
|
|
"TITLE": "Webhook",
|
|
"CONFIGURE": "Configurar",
|
|
"HEADER": "Configurações do Webhook",
|
|
"HEADER_BTN_TXT": "Adicionar novo Webhook",
|
|
"LOADING": "Buscando Webhooks anexados",
|
|
"SEARCH_404": "Não existem itens correspondentes a esta consulta",
|
|
"SIDEBAR_TXT": "<p><b>Webhooks</b> </p> <p>Webhooks são retornos de chamada HTTP que podem ser definidos para todas as contas. Eles são acionados por eventos como a criação de mensagens no Chatwoot. Você pode criar mais de um webhook para esta conta. <br /> <br /> Para criar um <b> webhook </b>, clique no botão <b> Adicionar novo webhook </b>. Você também pode remover qualquer webhook existente clicando no botão Excluir.</p>",
|
|
"LIST": {
|
|
"404": "Não há webhooks configurados para esta conta.",
|
|
"TITLE": "Gerenciar webhooks",
|
|
"TABLE_HEADER": {
|
|
"WEBHOOK_ENDPOINT": "Webhook URL (endpoint)",
|
|
"ACTIONS": "Ações"
|
|
}
|
|
},
|
|
"EDIT": {
|
|
"BUTTON_TEXT": "Alterar",
|
|
"TITLE": "Editar webhook",
|
|
"API": {
|
|
"SUCCESS_MESSAGE": "Configuração de Webhook atualizada com sucesso",
|
|
"ERROR_MESSAGE": "Não foi possível conectar ao servidor Woot, por favor tente novamente mais tarde"
|
|
}
|
|
},
|
|
"ADD": {
|
|
"CANCEL": "Cancelar",
|
|
"TITLE": "Adicionar novo webhook",
|
|
"API": {
|
|
"SUCCESS_MESSAGE": "Configuração de Webhook adicionada com sucesso",
|
|
"ERROR_MESSAGE": "Não foi possível conectar ao servidor Woot, por favor tente novamente mais tarde"
|
|
}
|
|
},
|
|
"DELETE": {
|
|
"BUTTON_TEXT": "Excluir",
|
|
"API": {
|
|
"SUCCESS_MESSAGE": "Webhook excluído com sucesso",
|
|
"ERROR_MESSAGE": "Não foi possível conectar ao servidor Woot, por favor tente novamente mais tarde"
|
|
},
|
|
"CONFIRM": {
|
|
"TITLE": "Confirmar exclusão",
|
|
"MESSAGE": "Tem certeza que deseja excluir o webhook? ({webhookURL})",
|
|
"YES": "Sim, excluir ",
|
|
"NO": "Não, mantenha"
|
|
}
|
|
}
|
|
},
|
|
"SLACK": {
|
|
"DELETE": "Excluir",
|
|
"DELETE_CONFIRMATION": {
|
|
"TITLE": "Excluir integração",
|
|
"MESSAGE": "Tem certeza que deseja excluir a integração? Isso resultará na perda de acesso a conversas no seu espaço de trabalho Slack."
|
|
},
|
|
"HELP_TEXT": {
|
|
"TITLE": "Usando a integração com Slack",
|
|
"BODY": "Com essa integração, todas as suas conversas recebidas serão sincronizadas com o canal ***{selectedChannelName}*** em seu espaço de trabalho Slack. Você pode gerenciar todas as suas conversas com clientes diretamente no canal e nunca perder uma mensagem.\n\nAqui estão os principais recursos da integração:\n\n**Responda a conversas de dentro do Slack:** Para responder a uma conversa no canal ***{selectedChannelName}*** Slack, simplesmente digite a sua mensagem e envie-a como um tópico. Isso criará uma resposta ao cliente através do Chatwoot. É tão simples!\n\n **Crie notas privadas:** Se você quiser criar notas privadas em vez de respostas, inicie sua mensagem com ***`nota:`***. Isso garante que sua mensagem seja privada e não seja visível para o cliente.\n\n**Associar um perfil de agente:** Se a pessoa que respondeu no Slack tem um perfil de agente no Chatwoot sob o mesmo e-mail, as respostas serão associadas automaticamente com esse perfil de agente. Isso significa que você pode facilmente controlar quem disse o quê e quando. Por outro lado, quando o respondente não tiver um perfil de agente associado, as respostas aparecerão do perfil do bot para o cliente.",
|
|
"SELECTED": "selecionar"
|
|
},
|
|
"SELECT_CHANNEL": {
|
|
"OPTION_LABEL": "Selecione um canal",
|
|
"UPDATE": "Atualizar",
|
|
"BUTTON_TEXT": "Conectar canal",
|
|
"DESCRIPTION": "Seu espaço de trabalho Slack agora está ligado com o Chatwoot. No entanto, a integração está inativa no momento. Para ativar a integração e conectar um canal ao Chatwoot, por favor, clique no botão abaixo.\n\n**Nota:** Se você está tentando conectar-se a um canal privado, adicione o aplicativo Chatwoot no canal do Slack antes de prosseguir com esta etapa.",
|
|
"ATTENTION_REQUIRED": "Atenção necessária",
|
|
"EXPIRED": "Sua integração com o Slack expirou. Para continuar recebendo mensagens no Slack, exclua a integração e conecte seu espaço de trabalho novamente."
|
|
},
|
|
"UPDATE_ERROR": "Ocorreu um erro ao atualizar a integração, por favor, tente novamente",
|
|
"UPDATE_SUCCESS": "O canal foi conectado com sucesso",
|
|
"FAILED_TO_FETCH_CHANNELS": "Ocorreu um erro ao obter os canais do Slack, por favor, tente novamente"
|
|
},
|
|
"DYTE": {
|
|
"CLICK_HERE_TO_JOIN": "Clique aqui para entrar",
|
|
"LEAVE_THE_ROOM": "Sair da sala",
|
|
"START_VIDEO_CALL_HELP_TEXT": "Iniciar uma nova chamada de vídeo com o cliente",
|
|
"JOIN_ERROR": "Houve um erro ao entrar na chamada, por favor tente novamente",
|
|
"CREATE_ERROR": "Houve um erro ao criar o link da reunião, por favor tente novamente"
|
|
},
|
|
"OPEN_AI": {
|
|
"AI_ASSIST": "Inteligência Artificial",
|
|
"WITH_AI": " {option} com IA ",
|
|
"OPTIONS": {
|
|
"REPLY_SUGGESTION": "Sugestão de resposta",
|
|
"SUMMARIZE": "Resumir",
|
|
"REPHRASE": "Melhorar Escrita",
|
|
"FIX_SPELLING_GRAMMAR": "Corrigir Ortografia e Gramática",
|
|
"SHORTEN": "Encurtar",
|
|
"EXPAND": "Expandir",
|
|
"MAKE_FRIENDLY": "Alterar o tom de mensagem para amigável",
|
|
"MAKE_FORMAL": "Usar tom formal",
|
|
"SIMPLIFY": "Simplificar",
|
|
"CONFIDENT": "Usar tom confiante",
|
|
"PROFESSIONAL": "Usar tom profissional",
|
|
"CASUAL": "Usar tom casual",
|
|
"STRAIGHTFORWARD": "Usar tom direto"
|
|
},
|
|
"ASSISTANCE_MODAL": {
|
|
"DRAFT_TITLE": "Conteúdo do rascunho",
|
|
"GENERATED_TITLE": "Conteúdo gerado",
|
|
"AI_WRITING": "A Inteligência Artificial está escrevendo",
|
|
"BUTTONS": {
|
|
"APPLY": "Use esta sugestão",
|
|
"CANCEL": "Cancelar"
|
|
}
|
|
},
|
|
"CTA_MODAL": {
|
|
"TITLE": "Integração com o OpenAI",
|
|
"DESC": "Traga funcionalidades avançadas de IA para o seu painel com os modelos GPT da OpenAI. Para começar, insira a chave API da sua conta OpenAI.",
|
|
"KEY_PLACEHOLDER": "Insira sua chave de API da OpenAI",
|
|
"BUTTONS": {
|
|
"NEED_HELP": "Precisa de ajuda?",
|
|
"DISMISS": "Recusar",
|
|
"FINISH": "Concluir Configuração"
|
|
},
|
|
"DISMISS_MESSAGE": "Você pode configurar a integração com o OpenAI mais tarde.",
|
|
"SUCCESS_MESSAGE": "Integração com o OpenAI configurada com sucesso"
|
|
},
|
|
"TITLE": "Melhorar com IA",
|
|
"SUMMARY_TITLE": "Resumir com IA",
|
|
"REPLY_TITLE": "Responder sugestão com IA",
|
|
"SUBTITLE": "Uma resposta melhor será gerada usando IA, com base no seu rascunho atual.",
|
|
"TONE": {
|
|
"TITLE": "Tom",
|
|
"OPTIONS": {
|
|
"PROFESSIONAL": "Profissional",
|
|
"FRIENDLY": "Amigável",
|
|
"CASUAL": "Casual",
|
|
"STRAIGHTFORWARD": "Direto",
|
|
"CONFIDENT": "Confiante"
|
|
}
|
|
},
|
|
"BUTTONS": {
|
|
"GENERATE": "Gerar",
|
|
"GENERATING": "Gerando...",
|
|
"CANCEL": "Cancelar"
|
|
},
|
|
"GENERATE_ERROR": "Ocorreu um erro ao processar o conteúdo, por favor, tente novamente"
|
|
},
|
|
"DELETE": {
|
|
"BUTTON_TEXT": "Excluir",
|
|
"API": {
|
|
"SUCCESS_MESSAGE": "Integração excluída com sucesso"
|
|
}
|
|
},
|
|
"CONNECT": {
|
|
"BUTTON_TEXT": "Conectar"
|
|
},
|
|
"DASHBOARD_APPS": {
|
|
"TITLE": "Painel de Aplicativos",
|
|
"HEADER_BTN_TXT": "Adicionar um novo aplicativo",
|
|
"SIDEBAR_TXT": "<p><b>Painel de Aplicativos</b></p><p>O Painel de Aplicativos permite que as organizações incorporem um aplicativo dentro do Painel de Aplicativos do Chatwoot para fornecer o contexto para agentes de suporte ao cliente. Este recurso permite-lhe criar uma aplicação independente e incorporá-la dentro da dashboard para fornecer informações do usuário, seus pedidos ou seu histórico de pagamentos anteriores.</p><p>Quando você incorpora seu aplicativo usando o Painel de Aplicativos do Chatwoot, sua aplicação irá obter o contexto da conversa e entrar em contato como um evento de janela. Implementar um ouvinte para o evento de mensagem em sua página receber o contexto.</p><p>Para adicionar um novo aplicativo no Painel de Aplicativos, clique no botão 'Adicionar um novo aplicativo'.</p>",
|
|
"DESCRIPTION": "O Painel de Aplicativos permite que organizações incorporem um aplicativo dentro do painel para fornecer o contexto para agentes de suporte ao cliente. Este recurso permite que você crie uma aplicação independente e incorpore para fornecer informações de usuário, seus pedidos ou seu histórico de pagamentos anteriores.",
|
|
"LEARN_MORE": "Saiba mais sobre o Painel de Aplicativos",
|
|
"LIST": {
|
|
"404": "Ainda não há aplicativos nesta conta",
|
|
"LOADING": "Buscando aplicativos...",
|
|
"TABLE_HEADER": {
|
|
"NAME": "Nome",
|
|
"ENDPOINT": "Endpoint"
|
|
},
|
|
"EDIT_TOOLTIP": "Alterar aplicativo",
|
|
"DELETE_TOOLTIP": "Excluir aplicativo"
|
|
},
|
|
"VIEW": {
|
|
"NOT_FOUND": "Não encontramos este aplicativo do painel."
|
|
},
|
|
"FORM": {
|
|
"TITLE_LABEL": "Nome",
|
|
"TITLE_PLACEHOLDER": "Digite um nome para o aplicativo",
|
|
"TITLE_ERROR": "É necessário um nome para o aplicativo",
|
|
"URL_LABEL": "Endpoint",
|
|
"URL_PLACEHOLDER": "Digite a URL do endpoint onde seu aplicativo está hospedado",
|
|
"URL_ERROR": "É necessário uma URL válida",
|
|
"SHOW_ON_SIDEBAR_LABEL": "Mostrar na barra lateral"
|
|
},
|
|
"CREATE": {
|
|
"HEADER": "Adicionar um novo aplicativo",
|
|
"FORM_SUBMIT": "Enviar",
|
|
"FORM_CANCEL": "Cancelar",
|
|
"API_SUCCESS": "Aplicativo configurado com sucesso",
|
|
"API_ERROR": "Não conseguimos criar um aplicativo. Por favor, tente novamente mais tarde"
|
|
},
|
|
"UPDATE": {
|
|
"HEADER": "Alterar aplicativo",
|
|
"FORM_SUBMIT": "Atualizar",
|
|
"FORM_CANCEL": "Cancelar",
|
|
"API_SUCCESS": "Aplicativo atualizado com sucesso",
|
|
"API_ERROR": "Não conseguimos atualizar o aplicativo. Por favor, tente novamente mais tarde"
|
|
},
|
|
"DELETE": {
|
|
"CONFIRM_YES": "Sim, exclua-o",
|
|
"CONFIRM_NO": "Não, mantenha-o",
|
|
"TITLE": "Confirmar exclusão",
|
|
"MESSAGE": "Tem certeza que deseja excluir o aplicativo - {appName}?",
|
|
"API_SUCCESS": "Aplicativo excluído com sucesso",
|
|
"API_ERROR": "Não conseguimos excluir o aplicativo. Por favor, tente novamente mais tarde"
|
|
}
|
|
},
|
|
"LINEAR": {
|
|
"ADD_OR_LINK_BUTTON": "Criar/Ligar Issue Linear",
|
|
"LOADING": "Buscando problemas lineares...",
|
|
"LOADING_ERROR": "Houve um erro ao buscar as entidades do time, por favor, tente novamente",
|
|
"CREATE": "Criar",
|
|
"LINK": {
|
|
"SEARCH": "Pesquisar issues",
|
|
"SELECT": "Selecionar problema",
|
|
"TITLE": "Link",
|
|
"EMPTY_LIST": "Nenhum problema linear encontrado",
|
|
"LOADING": "Carregando",
|
|
"ERROR": "Houve um erro ao buscar as questões lineares, por favor, tente novamente",
|
|
"LINK_SUCCESS": "Questão vinculada com sucesso",
|
|
"LINK_ERROR": "Houve um erro ao vincular a questão, tente novamente mais tarde",
|
|
"LINK_TITLE": "Conversa (#{conversationId}) com {name}"
|
|
},
|
|
"ADD_OR_LINK": {
|
|
"TITLE": "Criar/ligar questão linear",
|
|
"DESCRIPTION": "Crie issues no Linear a partir de conversas, ou vincule às existentes para um rastreamento integrado.",
|
|
"FORM": {
|
|
"TITLE": {
|
|
"LABEL": "Título",
|
|
"PLACEHOLDER": "Insira o título",
|
|
"REQUIRED_ERROR": "Título é obrigatório"
|
|
},
|
|
"DESCRIPTION": {
|
|
"LABEL": "Descrição",
|
|
"PLACEHOLDER": "Insira a descrição"
|
|
},
|
|
"TEAM": {
|
|
"LABEL": "Times",
|
|
"PLACEHOLDER": "Selecionar time",
|
|
"SEARCH": "Pesquisar time",
|
|
"REQUIRED_ERROR": "O time é obrigatório"
|
|
},
|
|
"ASSIGNEE": {
|
|
"LABEL": "Responsável",
|
|
"PLACEHOLDER": "Selecione o atribuído",
|
|
"SEARCH": "Pesquisar atribuído"
|
|
},
|
|
"PRIORITY": {
|
|
"LABEL": "Prioridade",
|
|
"PLACEHOLDER": "Selecionar prioridade",
|
|
"SEARCH": "Pesquisar prioridade"
|
|
},
|
|
"LABEL": {
|
|
"LABEL": "Nome do campo",
|
|
"PLACEHOLDER": "Selecione a etiqueta",
|
|
"SEARCH": "Pesquisar etiqueta"
|
|
},
|
|
"STATUS": {
|
|
"LABEL": "Status",
|
|
"PLACEHOLDER": "Selecione Status",
|
|
"SEARCH": "Pesquisar status"
|
|
},
|
|
"PROJECT": {
|
|
"LABEL": "Projeto",
|
|
"PLACEHOLDER": "Selecionar projeto",
|
|
"SEARCH": "Pesquisar projeto"
|
|
}
|
|
},
|
|
"CREATE": "Criar",
|
|
"CANCEL": "Cancelar",
|
|
"CREATE_SUCCESS": "Pasta criada com sucesso",
|
|
"CREATE_ERROR": "Houve um erro ao criar a questão, por favor, tente novamente",
|
|
"LOADING_TEAM_ERROR": "Houve um erro ao buscar os times, por favor, tente novamente",
|
|
"LOADING_TEAM_ENTITIES_ERROR": "Houve um erro ao buscar as entidades do time, por favor, tente novamente"
|
|
},
|
|
"ISSUE": {
|
|
"STATUS": "Status",
|
|
"PRIORITY": "Prioridade",
|
|
"ASSIGNEE": "Responsável",
|
|
"LABELS": "Etiquetas",
|
|
"CREATED_AT": "Criado em {createdAt}"
|
|
},
|
|
"UNLINK": {
|
|
"TITLE": "Desvincular",
|
|
"SUCCESS": "Issue desvinculada com sucesso",
|
|
"ERROR": "Houve um erro ao desvincular o atributo, por favor, tente novamente"
|
|
},
|
|
"NO_LINKED_ISSUES": "Nenhuma tarefa vinculada foi encontrada",
|
|
"DELETE": {
|
|
"TITLE": "Tem certeza que deseja excluir esta integração?",
|
|
"MESSAGE": "Tem certeza que deseja excluir esta integração?",
|
|
"CONFIRM": "Sim, excluir",
|
|
"CANCEL": "Cancelar"
|
|
},
|
|
"CTA": {
|
|
"TITLE": "Conectar ao Linear",
|
|
"AGENT_DESCRIPTION": "O espaço de trabalho do Linear não está conectado. Solicite ao seu administrador para conectar um espaço de trabalho para usar essa integração.",
|
|
"DESCRIPTION": "O espaço de trabalho do Linear não está conectado. Clique no botão abaixo para conectar seu espaço de trabalho para usar essa integração.",
|
|
"BUTTON_TEXT": "Conectar espaço de trabalho do Linear"
|
|
}
|
|
},
|
|
"NOTION": {
|
|
"DELETE": {
|
|
"TITLE": "Você tem certeza que deseja excluir a integração com Notion?",
|
|
"MESSAGE": "Excluir essa integração removerá o acesso ao seu espaço de trabalho Notion e encerrará todas as funcionalidades relacionadas.",
|
|
"CONFIRM": "Sim, excluir",
|
|
"CANCEL": "Cancelar"
|
|
}
|
|
}
|
|
},
|
|
"CAPTAIN": {
|
|
"NAME": "Capitão",
|
|
"HEADER_KNOW_MORE": "Know more",
|
|
"ASSISTANT_SWITCHER": {
|
|
"ASSISTANTS": "Assistentes",
|
|
"SWITCH_ASSISTANT": "Switch between assistants",
|
|
"NEW_ASSISTANT": "Create Assistant",
|
|
"EMPTY_LIST": "No assistants found, please create one to get started"
|
|
},
|
|
"COPILOT": {
|
|
"TITLE": "Copiloto",
|
|
"TRY_THESE_PROMPTS": "Experimente estes comandos",
|
|
"PANEL_TITLE": "Comece a usar o Copiloto",
|
|
"KICK_OFF_MESSAGE": "Precisa de um resumo rápido, quer verificar conversas passadas ou redigir uma resposta melhor? O Copiloto está aqui para acelerar as coisas.",
|
|
"SEND_MESSAGE": "Enviar mensagem...",
|
|
"EMPTY_MESSAGE": "Houve um erro ao gerar a resposta. Por favor, tente novamente.",
|
|
"LOADER": "Capitão está pensando",
|
|
"YOU": "Você",
|
|
"USE": "Use isto",
|
|
"RESET": "Reiniciar",
|
|
"SHOW_STEPS": "Mostrar etapas",
|
|
"SELECT_ASSISTANT": "Selecione o Assistente",
|
|
"PROMPTS": {
|
|
"SUMMARIZE": {
|
|
"LABEL": "Resumir esta conversa",
|
|
"CONTENT": "Resuma os pontos-chave discutidos entre o cliente e o agente de suporte, incluindo as preocupações do cliente, as questões e as soluções ou respostas dadas pelo agente de suporte"
|
|
},
|
|
"SUGGEST": {
|
|
"LABEL": "Sugerir uma resposta",
|
|
"CONTENT": "Analise a pergunta do cliente e elabore uma resposta que responda efetivamente às suas preocupações ou perguntas. Certifique-se de que a resposta seja clara, concisa e forneça informações úteis."
|
|
},
|
|
"RATE": {
|
|
"LABEL": "Avaliar esta conversa",
|
|
"CONTENT": "Revise a conversa para ver o quanto ela atende às necessidades do cliente. Compartilhe uma classificação de 0 a 5 com base em tom, clareza e eficácia."
|
|
},
|
|
"HIGH_PRIORITY": {
|
|
"LABEL": "Conversas de alta prioridade",
|
|
"CONTENT": "Dê um resumo de todas as conversas abertas com prioridade alta. Incluir o ID da conversa, nome do cliente (se disponível), o conteúdo da última mensagem e o agente atribuído. O grupo por status, se relevante."
|
|
},
|
|
"LIST_CONTACTS": {
|
|
"LABEL": "Listar contatos",
|
|
"CONTENT": "Mostre-me a lista dos 10 contatos mais frequentes. Inclua nome, e-mail ou número de telefone (se disponível), visto por última vez, etiquetas (se houver)."
|
|
}
|
|
}
|
|
},
|
|
"PLAYGROUND": {
|
|
"USER": "Você",
|
|
"ASSISTANT": "Assistente",
|
|
"MESSAGE_PLACEHOLDER": "Digite sua mensagem...",
|
|
"HEADER": "Playground",
|
|
"DESCRIPTION": "Use este playground para enviar mensagens para seu assistente e verificar se ele responde com precisão, rápido e no tom que você espera.",
|
|
"CREDIT_NOTE": "As mensagens enviadas aqui usam os créditos do seu Capitão."
|
|
},
|
|
"PAYWALL": {
|
|
"TITLE": "Atualize para usar o Capitão IA",
|
|
"AVAILABLE_ON": "O Capitão não está disponível no plano gratuito.",
|
|
"UPGRADE_PROMPT": "Atualize seu plano para ter acesso aos nossos assistentes, copilotos e muito mais.",
|
|
"UPGRADE_NOW": "Atualizar agora",
|
|
"CANCEL_ANYTIME": "Você pode alterar ou cancelar seu plano a qualquer momento"
|
|
},
|
|
"ENTERPRISE_PAYWALL": {
|
|
"UPGRADE_PROMPT": "Atualize seu plano para ter acesso aos nossos assistentes, copilotos e muito mais.",
|
|
"ASK_ADMIN": "Entre em contato com seu administrador para fazer a atualização."
|
|
},
|
|
"BANNER": {
|
|
"RESPONSES": "Você usou mais de 80% do seu limite de respostas. Para continuar usando o Capitão AI, faça o upgrade.",
|
|
"DOCUMENTS": "Limite de documentos atingido. Atualize para continuar usando o Capitão AI."
|
|
},
|
|
"FORM": {
|
|
"CANCEL": "Cancelar",
|
|
"CREATE": "Criar",
|
|
"EDIT": "Atualizar"
|
|
},
|
|
"ASSISTANTS": {
|
|
"HEADER": "Assistentes",
|
|
"NO_ASSISTANTS_AVAILABLE": "Não há assistentes disponíveis em sua conta.",
|
|
"ADD_NEW": "Criar um novo assistente",
|
|
"DELETE": {
|
|
"TITLE": "Tem certeza que deseja excluir o assistente?",
|
|
"DESCRIPTION": "Esta ação é permanente. Excluir este assistente irá removê-lo de todas as caixas de entrada conectadas e apagará permanentemente todo o conhecimento gerado.",
|
|
"CONFIRM": "Sim, excluir",
|
|
"SUCCESS_MESSAGE": "O assistente foi excluído com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao excluir o assistente, por favor tente novamente."
|
|
},
|
|
"FORM_DESCRIPTION": "Preencha os detalhes abaixo para nomear seu assistente, descrever sua finalidade e especificar o produto que ele oferecerá suporte.",
|
|
"CREATE": {
|
|
"TITLE": "Criar um assistente",
|
|
"SUCCESS_MESSAGE": "O assistente foi criado com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao criar o assistente, por favor tente novamente."
|
|
},
|
|
"FORM": {
|
|
"UPDATE": "Atualizar",
|
|
"SECTIONS": {
|
|
"BASIC_INFO": "Informações Básicas",
|
|
"SYSTEM_MESSAGES": "Mensagens do Sistema",
|
|
"INSTRUCTIONS": "Instruções",
|
|
"FEATURES": "Funcionalidades",
|
|
"TOOLS": "Ferramentas "
|
|
},
|
|
"NAME": {
|
|
"LABEL": "Nome",
|
|
"PLACEHOLDER": "Digite o nome do assistente",
|
|
"ERROR": "O nome é obrigatório"
|
|
},
|
|
"TEMPERATURE": {
|
|
"LABEL": "Temperatura da resposta",
|
|
"DESCRIPTION": "Ajuste o quão criativo ou restritivo as respostas do assistente devem ser. Valores mais baixos produzem respostas mais focadas e deterministas, enquanto valores mais altos permitem resultados mais criativos e variados."
|
|
},
|
|
"DESCRIPTION": {
|
|
"LABEL": "Descrição",
|
|
"PLACEHOLDER": "Digite a descrição do assistente",
|
|
"ERROR": "A descrição é obrigatória"
|
|
},
|
|
"PRODUCT_NAME": {
|
|
"LABEL": "Nome do Produto",
|
|
"PLACEHOLDER": "Digite o nome do produto",
|
|
"ERROR": "O nome do produto é obrigatório"
|
|
},
|
|
"WELCOME_MESSAGE": {
|
|
"LABEL": "Mensagem de boas-vindas",
|
|
"PLACEHOLDER": "Digite a mensagem de boas-vindas"
|
|
},
|
|
"HANDOFF_MESSAGE": {
|
|
"LABEL": "Mensagem de transferência",
|
|
"PLACEHOLDER": "Digite a mensagem de transferência"
|
|
},
|
|
"RESOLUTION_MESSAGE": {
|
|
"LABEL": "Mensagem de resolução",
|
|
"PLACEHOLDER": "Digite a mensagem de resolução"
|
|
},
|
|
"INSTRUCTIONS": {
|
|
"LABEL": "Instruções",
|
|
"PLACEHOLDER": "Digite as instruções para o assistente"
|
|
},
|
|
"FEATURES": {
|
|
"TITLE": "Funcionalidades",
|
|
"ALLOW_CONVERSATION_FAQS": "Gerar perguntas frequentes a partir de conversas resolvidas",
|
|
"ALLOW_MEMORIES": "Capture os principais detalhes como memórias de interações do cliente.",
|
|
"ALLOW_CITATIONS": "Incluir fonte de citações nas respostas"
|
|
}
|
|
},
|
|
"EDIT": {
|
|
"TITLE": "Atualizar o assistente",
|
|
"SUCCESS_MESSAGE": "O assistente foi criado com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao criar o assistente, por favor tente novamente.",
|
|
"NOT_FOUND": "Não foi possível encontrar o assistente. Tente novamente."
|
|
},
|
|
"SETTINGS": {
|
|
"HEADER": "Configurações",
|
|
"BASIC_SETTINGS": {
|
|
"TITLE": "Configurações básicas",
|
|
"DESCRIPTION": "Personalize o que o assistente diz quando termina uma conversa ou transfere para um humano."
|
|
},
|
|
"SYSTEM_SETTINGS": {
|
|
"TITLE": "Configurações do sistema",
|
|
"DESCRIPTION": "Personalize o que o assistente diz quando termina uma conversa ou transfere para um humano."
|
|
},
|
|
"CONTROL_ITEMS": {
|
|
"TITLE": "As Coisas Divertidas",
|
|
"DESCRIPTION": "Adicione mais controle ao assistente. (algo mais visual como uma história: Consulta → cenários → saída) Força o usuário para realmente utilizá-los.",
|
|
"OPTIONS": {
|
|
"GUARDRAILS": {
|
|
"TITLE": "Proteções",
|
|
"DESCRIPTION": "Mantém as coisas no caminho — apenas os tipos de perguntas que você quer que seu assistente responda, nada fora de limites ou fora do tópico."
|
|
},
|
|
"RESPONSE_GUIDELINES": {
|
|
"TITLE": "Diretrizes de resposta",
|
|
"DESCRIPTION": "O jeito e a estrutura das respostas do seu assistente — tranquilo e amigável? Curto e ágil? Detalhado e formal?"
|
|
}
|
|
}
|
|
},
|
|
"DELETE": {
|
|
"TITLE": "Excluir Assistente",
|
|
"DESCRIPTION": "Esta ação é permanente. Excluir este assistente irá removê-lo de todas as caixas de entrada conectadas e apagará permanentemente todo o conhecimento gerado.",
|
|
"BUTTON_TEXT": "Excluir {assistantName}"
|
|
}
|
|
},
|
|
"OPTIONS": {
|
|
"EDIT_ASSISTANT": "Editar Assistente",
|
|
"DELETE_ASSISTANT": "Excluir Assistente",
|
|
"VIEW_CONNECTED_INBOXES": "Ver caixas de entrada conectadas"
|
|
},
|
|
"EMPTY_STATE": {
|
|
"TITLE": "Não há assistentes disponíveis",
|
|
"SUBTITLE": "Crie um assistente para fornecer respostas rápidas e precisas aos seus usuários. Ele pode aprender com seus artigos de ajuda e conversas passadas.",
|
|
"FEATURE_SPOTLIGHT": {
|
|
"TITLE": "Captain Assistant",
|
|
"NOTE": "Captain Assistant engages directly with customers, learns from your help docs and past conversations, and delivers instant, accurate responses. It handles the initial queries, providing quick resolutions before transferring to an agent when needed."
|
|
}
|
|
},
|
|
"GUARDRAILS": {
|
|
"TITLE": "Proteções",
|
|
"DESCRIPTION": "Mantém as coisas no caminho — apenas os tipos de perguntas que você quer que seu assistente responda, nada fora de limites ou fora do tópico.",
|
|
"BULK_ACTION": {
|
|
"SELECTED": "{count} item selecionado | {count} itens selecionados",
|
|
"SELECT_ALL": "Selecionar todos ({count})",
|
|
"UNSELECT_ALL": "Desmarcar todos ({count})",
|
|
"BULK_DELETE_BUTTON": "Excluir"
|
|
},
|
|
"ADD": {
|
|
"SUGGESTED": {
|
|
"TITLE": "Exemplos de proteções",
|
|
"ADD": "Adicionar todos",
|
|
"ADD_SINGLE": "Adicionar este",
|
|
"SAVE": "Adicionar e salvar (↵)",
|
|
"PLACEHOLDER": "Escreva outra proteção"
|
|
},
|
|
"NEW": {
|
|
"TITLE": "Adicionar proteção",
|
|
"CREATE": "Criar",
|
|
"CANCEL": "Cancelar",
|
|
"PLACEHOLDER": "Escreva outra proteção",
|
|
"TEST_ALL": "Testar tudo"
|
|
}
|
|
},
|
|
"LIST": {
|
|
"SEARCH_PLACEHOLDER": "Pesquisar..."
|
|
},
|
|
"EMPTY_MESSAGE": "Nenhuma proteção encontrada. Crie uma ou adicione exemplos para começar.",
|
|
"SEARCH_EMPTY_MESSAGE": "Nenhuma proteção encontrada para essa pesquisa.",
|
|
"API": {
|
|
"ADD": {
|
|
"SUCCESS": "Proteções adicionadas com sucesso",
|
|
"ERROR": "Ocorreu um erro ao adicionar as proteções. Por favor, tente novamente."
|
|
},
|
|
"UPDATE": {
|
|
"SUCCESS": "Proteções atualizados com sucesso",
|
|
"ERROR": "Ocorreu um erro ao atualizar as proteções. Por favor, tente novamente."
|
|
},
|
|
"DELETE": {
|
|
"SUCCESS": "Proteções removidas com sucesso",
|
|
"ERROR": "Ocorreu um erro ao excluir as proteções, por favor, tente novamente."
|
|
}
|
|
}
|
|
},
|
|
"RESPONSE_GUIDELINES": {
|
|
"TITLE": "Diretrizes de Resposta",
|
|
"DESCRIPTION": "O jeito e a estrutura das respostas do seu assistente — tranquilo e amigável? Curto e ágil? Detalhado e formal?",
|
|
"BULK_ACTION": {
|
|
"SELECTED": "{count} item selecionado | {count} itens selecionados",
|
|
"SELECT_ALL": "Selecionar todos ({count})",
|
|
"UNSELECT_ALL": "Desmarcar todos ({count})",
|
|
"BULK_DELETE_BUTTON": "Excluir"
|
|
},
|
|
"ADD": {
|
|
"SUGGESTED": {
|
|
"TITLE": "Exemplos de diretrizes de resposta",
|
|
"ADD": "Adicionar todos",
|
|
"ADD_SINGLE": "Adicionar este",
|
|
"SAVE": "Adicionar e salvar (↵)",
|
|
"PLACEHOLDER": "Escreva uma outra diretriz de resposta..."
|
|
},
|
|
"NEW": {
|
|
"TITLE": "Adicione uma diretriz de resposta",
|
|
"CREATE": "Criar",
|
|
"CANCEL": "Cancelar",
|
|
"PLACEHOLDER": "Escreva uma outra diretriz de resposta...",
|
|
"TEST_ALL": "Testar tudo"
|
|
}
|
|
},
|
|
"LIST": {
|
|
"SEARCH_PLACEHOLDER": "Pesquisar..."
|
|
},
|
|
"EMPTY_MESSAGE": "Nenhuma diretriz de resposta encontrada. Crie uma ou adicione exemplos para começar.",
|
|
"SEARCH_EMPTY_MESSAGE": "Nenhuma diretriz de resposta encotrada para essa pesquisa.",
|
|
"API": {
|
|
"ADD": {
|
|
"SUCCESS": "Diretrizes de resposta adicionadas com sucesso",
|
|
"ERROR": "Houve um erro ao adicionar diretrizes de resposta, por favor, tente novamente."
|
|
},
|
|
"UPDATE": {
|
|
"SUCCESS": "Diretrizes de Resposta atualizadas com sucesso",
|
|
"ERROR": "Houve um erro ao atualizar as diretrizes de resposta, por favor, tente novamente."
|
|
},
|
|
"DELETE": {
|
|
"SUCCESS": "Diretrizes de resposta removidas com sucesso",
|
|
"ERROR": "Houve um erro ao excluir as diretrizes de resposta, por favor, tente novamente."
|
|
}
|
|
}
|
|
},
|
|
"SCENARIOS": {
|
|
"TITLE": "Cenários",
|
|
"DESCRIPTION": "Dê algum contexto ao seu assistente — como \"o que fazer quando um usuário estiver com problemas\", ou \"como agir durante uma solicitação de reembolso\".",
|
|
"BULK_ACTION": {
|
|
"SELECTED": "{count} item selecionado | {count} itens selecionados",
|
|
"SELECT_ALL": "Selecionar todos ({count})",
|
|
"UNSELECT_ALL": "Desmarcar todos ({count})",
|
|
"BULK_DELETE_BUTTON": "Excluir"
|
|
},
|
|
"ADD": {
|
|
"SUGGESTED": {
|
|
"TITLE": "Exemplos de cenários",
|
|
"ADD": "Adicionar todos",
|
|
"ADD_SINGLE": "Adicionar este",
|
|
"TOOLS_USED": "Ferramentas usadas :"
|
|
},
|
|
"NEW": {
|
|
"CREATE": "Adicionar um cenário",
|
|
"TITLE": "Criar um cenário",
|
|
"FORM": {
|
|
"TITLE": {
|
|
"LABEL": "Título",
|
|
"PLACEHOLDER": "Digite um nome para o cenário",
|
|
"ERROR": "O nome do cenário é obrigatório"
|
|
},
|
|
"DESCRIPTION": {
|
|
"LABEL": "Descrição",
|
|
"PLACEHOLDER": "Descreva como e onde este cenário será utilizado",
|
|
"ERROR": "Descrição do cenário é obrigatória"
|
|
},
|
|
"INSTRUCTION": {
|
|
"LABEL": "Como lidar",
|
|
"PLACEHOLDER": "Descreva como e onde este cenário será utilizado",
|
|
"ERROR": "Conteúdo do cenário é obrigatório"
|
|
},
|
|
"CREATE": "Criar",
|
|
"CANCEL": "Cancelar"
|
|
}
|
|
}
|
|
},
|
|
"UPDATE": {
|
|
"CANCEL": "Cancelar",
|
|
"UPDATE": "Atualizar alterações"
|
|
},
|
|
"LIST": {
|
|
"SEARCH_PLACEHOLDER": "Pesquisar..."
|
|
},
|
|
"EMPTY_MESSAGE": "Nenhum cenário encontrado. Crie ou adicione exemplos para começar.",
|
|
"SEARCH_EMPTY_MESSAGE": "Nenhum cenário encontrado para esta pesquisa.",
|
|
"API": {
|
|
"ADD": {
|
|
"SUCCESS": "Cenários adicionados com sucesso",
|
|
"ERROR": "Ocorreu um erro ao adicionar cenários, por favor tente novamente."
|
|
},
|
|
"UPDATE": {
|
|
"SUCCESS": "Cenários atualizados com sucesso",
|
|
"ERROR": "Ocorreu um erro ao atualizar cenários, por favor tente novamente."
|
|
},
|
|
"DELETE": {
|
|
"SUCCESS": "Cenários excluídos com sucesso",
|
|
"ERROR": "Ocorreu um erro ao excluir os cenários, por favor tente novamente."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"DOCUMENTS": {
|
|
"HEADER": "Documentos",
|
|
"ADD_NEW": "Criar um novo documento",
|
|
"RELATED_RESPONSES": {
|
|
"TITLE": "FAQs Relacionadas",
|
|
"DESCRIPTION": "Estes FAQs são gerados diretamente a partir do documento."
|
|
},
|
|
"FORM_DESCRIPTION": "Digite o URL do documento para adicioná-lo como fonte de conhecimento e escolha o assistente para associá-lo.",
|
|
"CREATE": {
|
|
"TITLE": "Adicionar um documento",
|
|
"SUCCESS_MESSAGE": "O documento foi criado com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao criar o documento, por favor, tente novamente."
|
|
},
|
|
"FORM": {
|
|
"TYPE": {
|
|
"LABEL": "Tipo do documento",
|
|
"URL": "URL:",
|
|
"PDF": "Arquivo PDF"
|
|
},
|
|
"URL": {
|
|
"LABEL": "URL:",
|
|
"PLACEHOLDER": "Insira a URL do documento",
|
|
"ERROR": "Por favor forneça uma URL válida para o documento"
|
|
},
|
|
"PDF_FILE": {
|
|
"LABEL": "Arquivo PDF",
|
|
"CHOOSE_FILE": "Escolher arquivo PDF",
|
|
"ERROR": "Por favor, selecione um arquivo PDF",
|
|
"HELP_TEXT": "Tamanho máximo do arquivo: 10 MB",
|
|
"INVALID_TYPE": "Por favor, selecione um arquivo PDF válido",
|
|
"TOO_LARGE": "O tamanho do arquivo excede o limite de 10 MB"
|
|
},
|
|
"NAME": {
|
|
"LABEL": "Nome do documento (opcional)",
|
|
"PLACEHOLDER": "Insira um nome para o documento"
|
|
}
|
|
},
|
|
"DELETE": {
|
|
"TITLE": "Tem certeza de que deseja excluir este documento?",
|
|
"DESCRIPTION": "Esta ação é permanente. Eliminar este documento irá apagar permanentemente todo o conhecimento gerado.",
|
|
"CONFIRM": "Sim, excluir",
|
|
"SUCCESS_MESSAGE": "O documento foi excluído com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao excluir o documento, por favor, tente novamente."
|
|
},
|
|
"OPTIONS": {
|
|
"VIEW_RELATED_RESPONSES": "Visualizar Respostas relacionadas",
|
|
"DELETE_DOCUMENT": "Excluir Documento"
|
|
},
|
|
"EMPTY_STATE": {
|
|
"TITLE": "Nenhum documento disponível",
|
|
"SUBTITLE": "Os documentos são usados pelo seu assistente para gerar perguntas frequentes. Pode importar documentos para fornecer um contexto para seu assistente.",
|
|
"FEATURE_SPOTLIGHT": {
|
|
"TITLE": "Captain Document",
|
|
"NOTE": "A document in Captain serves as a knowledge resource for the assistant. By connecting your help center or guides, Captain can analyze the content and provide accurate responses for customer inquiries."
|
|
}
|
|
}
|
|
},
|
|
"CUSTOM_TOOLS": {
|
|
"HEADER": "Ferramentas",
|
|
"ADD_NEW": "Criar ferramenta",
|
|
"EMPTY_STATE": {
|
|
"TITLE": "Não há ferramentas personalizadas disponíveis",
|
|
"SUBTITLE": "Crie ferramentas personalizadas para conectar com APIs e serviços externos, permitindo obter dados e agir por você.",
|
|
"FEATURE_SPOTLIGHT": {
|
|
"TITLE": "Ferramentas Personalizadas",
|
|
"NOTE": "Ferramentas personalizadas permitem seu assistente interagir com APIs e serviços externos. Crie ferramentas para obter dados, realizar ações ou integre com seus sistemas existentes para melhorar as capacidades do seu assistente."
|
|
}
|
|
},
|
|
"FORM_DESCRIPTION": "Configure your custom tool to connect with external APIs",
|
|
"OPTIONS": {
|
|
"EDIT_TOOL": "Edit tool",
|
|
"DELETE_TOOL": "Delete tool"
|
|
},
|
|
"CREATE": {
|
|
"TITLE": "Create Custom Tool",
|
|
"SUCCESS_MESSAGE": "Custom tool created successfully",
|
|
"ERROR_MESSAGE": "Failed to create custom tool"
|
|
},
|
|
"EDIT": {
|
|
"TITLE": "Edit Custom Tool",
|
|
"SUCCESS_MESSAGE": "Custom tool updated successfully",
|
|
"ERROR_MESSAGE": "Failed to update custom tool"
|
|
},
|
|
"DELETE": {
|
|
"TITLE": "Delete Custom Tool",
|
|
"DESCRIPTION": "Tem certeza que deseja excluir está ferramenta customizável? Está ação não pode ser desfeita.",
|
|
"CONFIRM": "Sim, excluir",
|
|
"SUCCESS_MESSAGE": "Custom tool deleted successfully",
|
|
"ERROR_MESSAGE": "Failed to delete custom tool"
|
|
},
|
|
"FORM": {
|
|
"TITLE": {
|
|
"LABEL": "Nome da Ferramenta",
|
|
"PLACEHOLDER": "Order Lookup",
|
|
"ERROR": "Nome da ferramente obrigatória"
|
|
},
|
|
"DESCRIPTION": {
|
|
"LABEL": "Descrição",
|
|
"PLACEHOLDER": "Looks up order details by order ID"
|
|
},
|
|
"HTTP_METHOD": {
|
|
"LABEL": "Method"
|
|
},
|
|
"ENDPOINT_URL": {
|
|
"LABEL": "Endpoint URL",
|
|
"PLACEHOLDER": "https://api.example.com/orders/{'{{'} order_id {'}}'}",
|
|
"ERROR": "Valid URL is required"
|
|
},
|
|
"AUTH_TYPE": {
|
|
"LABEL": "Authentication Type"
|
|
},
|
|
"AUTH_TYPES": {
|
|
"NONE": "Nenhuma",
|
|
"BEARER": "Bearer Token",
|
|
"BASIC": "Basic Auth",
|
|
"API_KEY": "Chave API"
|
|
},
|
|
"AUTH_CONFIG": {
|
|
"BEARER_TOKEN": "Bearer Token",
|
|
"BEARER_TOKEN_PLACEHOLDER": "Enter your bearer token",
|
|
"USERNAME": "Username",
|
|
"USERNAME_PLACEHOLDER": "Enter username",
|
|
"PASSWORD": "Senha",
|
|
"PASSWORD_PLACEHOLDER": "Enter password",
|
|
"API_KEY": "Header Name",
|
|
"API_KEY_PLACEHOLDER": "X-API-Key",
|
|
"API_VALUE": "Header Value",
|
|
"API_VALUE_PLACEHOLDER": "Enter API key value"
|
|
},
|
|
"PARAMETERS": {
|
|
"LABEL": "Parameters",
|
|
"HELP_TEXT": "Define the parameters that will be extracted from user queries"
|
|
},
|
|
"ADD_PARAMETER": "Add Parameter",
|
|
"PARAM_NAME": {
|
|
"PLACEHOLDER": "Parameter name (e.g., order_id)"
|
|
},
|
|
"PARAM_TYPE": {
|
|
"PLACEHOLDER": "Tipo"
|
|
},
|
|
"PARAM_TYPES": {
|
|
"STRING": "String",
|
|
"NUMBER": "Número",
|
|
"BOOLEAN": "Boolean",
|
|
"ARRAY": "Array",
|
|
"OBJECT": "Object"
|
|
},
|
|
"PARAM_DESCRIPTION": {
|
|
"PLACEHOLDER": "Description of the parameter"
|
|
},
|
|
"PARAM_REQUIRED": {
|
|
"LABEL": "Obrigatório"
|
|
},
|
|
"REQUEST_TEMPLATE": {
|
|
"LABEL": "Request Body Template (Optional)",
|
|
"PLACEHOLDER": "{'{'}\n \"order_id\": \"{'{{'} order_id {'}}'}\"\n{'}'}"
|
|
},
|
|
"RESPONSE_TEMPLATE": {
|
|
"LABEL": "Response Template (Optional)",
|
|
"PLACEHOLDER": "Order {'{{'} order_id {'}}'} status: {'{{'} status {'}}'}"
|
|
},
|
|
"ERRORS": {
|
|
"PARAM_NAME_REQUIRED": "Parameter name is required"
|
|
}
|
|
}
|
|
},
|
|
"RESPONSES": {
|
|
"HEADER": "FAQs",
|
|
"PENDING_FAQS": "Pending FAQs",
|
|
"ADD_NEW": "Criar nova FAQ",
|
|
"DOCUMENTABLE": {
|
|
"CONVERSATION": "Conversação #{id}"
|
|
},
|
|
"SELECTED": "{count} selecionado",
|
|
"SELECT_ALL": "Selecionar todos ({count})",
|
|
"UNSELECT_ALL": "Desmarcar todos ({count})",
|
|
"SEARCH_PLACEHOLDER": "Pesquisar FAQs...",
|
|
"BULK_APPROVE_BUTTON": "Aprovar",
|
|
"BULK_DELETE_BUTTON": "Excluir",
|
|
"BULK_APPROVE": {
|
|
"SUCCESS_MESSAGE": "Perguntas Frequentes aprovadas com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao aprovar as Perguntas Frequentes. Tente novamente."
|
|
},
|
|
"BULK_DELETE": {
|
|
"TITLE": "Excluir as Perguntas Frequentes?",
|
|
"DESCRIPTION": "Tem certeza que deseja excluir as Perguntas Frequentes selecionadas? Esta ação não pode ser desfeita.",
|
|
"CONFIRM": "Sim, excluir todas",
|
|
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso/",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao excluir as Perguntas Frequentes, por favor tente novamente."
|
|
},
|
|
"DELETE": {
|
|
"TITLE": "Tem certeza que deseja excluir o FAQ?",
|
|
"DESCRIPTION": "",
|
|
"CONFIRM": "Sim, excluir",
|
|
"SUCCESS_MESSAGE": "FAQ excluída com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao excluir a FAQ, por favor tente novamente."
|
|
},
|
|
"FILTER": {
|
|
"ASSISTANT": "Assistente: {selected}",
|
|
"STATUS": "Status: {selected}",
|
|
"ALL_ASSISTANTS": "Todos"
|
|
},
|
|
"STATUS": {
|
|
"TITLE": "Status",
|
|
"PENDING": "Pendentes",
|
|
"APPROVED": "Aceito",
|
|
"ALL": "Todos"
|
|
},
|
|
"PENDING_BANNER": {
|
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
|
"ACTION": "Click here to review"
|
|
},
|
|
"FORM_DESCRIPTION": "Adicione uma pergunta e sua resposta correspondente à base de conhecimento e selecione o assistente ao qual deve estar associado.",
|
|
"CREATE": {
|
|
"TITLE": "Adicionar uma FAQ",
|
|
"SUCCESS_MESSAGE": "A resposta foi adicionada com sucesso.",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao adicionar a resposta. Por favor, tente novamente."
|
|
},
|
|
"FORM": {
|
|
"QUESTION": {
|
|
"LABEL": "Pergunta",
|
|
"PLACEHOLDER": "Digite a pergunta aqui",
|
|
"ERROR": "Por favor, forneça uma pergunta válida."
|
|
},
|
|
"ANSWER": {
|
|
"LABEL": "Responder",
|
|
"PLACEHOLDER": "Digite a resposta aqui",
|
|
"ERROR": "Por favor, forneça uma resposta válida."
|
|
}
|
|
},
|
|
"EDIT": {
|
|
"TITLE": "Atualizar as Perguntas Frequentes",
|
|
"SUCCESS_MESSAGE": "As Perguntas Frequentes foram atualizadas com sucesso",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao atualizar as Perguntas Frequentes, por favor tente novamente",
|
|
"APPROVE_SUCCESS_MESSAGE": "As Perguntas Frequentes foram marcadas como aprovadas"
|
|
},
|
|
"OPTIONS": {
|
|
"APPROVE": "Aprovar",
|
|
"EDIT_RESPONSE": "Alterar",
|
|
"DELETE_RESPONSE": "Excluir"
|
|
},
|
|
"EMPTY_STATE": {
|
|
"TITLE": "Nenhuma FAQ encontrada",
|
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
|
"SUBTITLE": "Perguntas Frequentes ajudam seu assistente a fornecer respostas rápidas e precisas para perguntas de seus clientes. Eles podem ser gerados automaticamente a partir do seu conteúdo ou podem ser adicionados manualmente.",
|
|
"CLEAR_SEARCH": "Clear active filters",
|
|
"FEATURE_SPOTLIGHT": {
|
|
"TITLE": "Captain FAQ",
|
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
|
}
|
|
}
|
|
},
|
|
"INBOXES": {
|
|
"HEADER": "Caixas de entrada conectadas",
|
|
"ADD_NEW": "Conectar uma nova caixa de entrada",
|
|
"OPTIONS": {
|
|
"DISCONNECT": "Desconectar"
|
|
},
|
|
"DELETE": {
|
|
"TITLE": "Tem certeza que deseja desconectar a caixa de entrada?",
|
|
"DESCRIPTION": "",
|
|
"CONFIRM": "Sim, excluir",
|
|
"SUCCESS_MESSAGE": "A caixa de entrada foi desconectada com sucesso.",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao desconectar a caixa de entrada, por favor, tente novamente."
|
|
},
|
|
"FORM_DESCRIPTION": "Escolha uma caixa de entrada para conectar com o assistente.",
|
|
"CREATE": {
|
|
"TITLE": "Conecte uma caixa de entrada",
|
|
"SUCCESS_MESSAGE": "A caixa de entrada foi conectada com sucesso.",
|
|
"ERROR_MESSAGE": "Ocorreu um erro ao conectar à caixa de entrada. Por favor, tente novamente."
|
|
},
|
|
"FORM": {
|
|
"INBOX": {
|
|
"LABEL": "Caixa de Entrada",
|
|
"PLACEHOLDER": "Selecione a caixa de entrada para implantar o assistente.",
|
|
"ERROR": "É obrigatório selecionar uma caixa de entrada."
|
|
}
|
|
},
|
|
"EMPTY_STATE": {
|
|
"TITLE": "Caixa de entrada não conectada",
|
|
"SUBTITLE": "Conectar uma caixa de entrada permite ao assistente lidar com perguntas iniciais de seus clientes antes de transferi-las para você."
|
|
}
|
|
}
|
|
}
|
|
}
|