Merge branch 'develop' into feat/new-auth-screens

This commit is contained in:
Muhsin Keloth 2022-03-21 17:19:36 +05:30 committed by GitHub
commit 21efdf5c56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 489 additions and 211 deletions

View file

@ -42,7 +42,7 @@ gem 'down', '~> 5.0'
gem 'aws-sdk-s3', require: false gem 'aws-sdk-s3', require: false
gem 'azure-storage-blob', require: false gem 'azure-storage-blob', require: false
gem 'google-cloud-storage', require: false gem 'google-cloud-storage', require: false
gem 'image_processing' gem 'image_processing', '~> 1.12.2'
##-- gems for database --# ##-- gems for database --#
gem 'groupdate' gem 'groupdate'

View file

@ -688,7 +688,7 @@ DEPENDENCIES
hairtrigger hairtrigger
hashie hashie
html2text html2text
image_processing image_processing (~> 1.12.2)
jbuilder jbuilder
json_refs json_refs
json_schemer json_schemer

View file

@ -34,7 +34,7 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
params.permit( params.permit(
:name, :description, :event_name, :account_id, :active, :name, :description, :event_name, :account_id, :active,
conditions: [:attribute_key, :filter_operator, :query_operator, { values: [] }], conditions: [:attribute_key, :filter_operator, :query_operator, { values: [] }],
actions: [:action_name, { action_params: [] }] actions: [:action_name, { action_params: [{}] }]
) )
end end

View file

@ -22,7 +22,7 @@
"is_not_present": "غير موجود", "is_not_present": "غير موجود",
"is_greater_than": "هو أكبر من", "is_greater_than": "هو أكبر من",
"is_less_than": "هو أقل من", "is_less_than": "هو أقل من",
"days_before": "Is x days before" "days_before": "قبل x أيام"
}, },
"ATTRIBUTE_LABELS": { "ATTRIBUTE_LABELS": {
"TRUE": "صحيح", "TRUE": "صحيح",
@ -44,7 +44,7 @@
"CUSTOM_ATTRIBUTE_NUMBER": "العدد", "CUSTOM_ATTRIBUTE_NUMBER": "العدد",
"CUSTOM_ATTRIBUTE_LINK": "الرابط", "CUSTOM_ATTRIBUTE_LINK": "الرابط",
"CUSTOM_ATTRIBUTE_CHECKBOX": "مربع", "CUSTOM_ATTRIBUTE_CHECKBOX": "مربع",
"CREATED_AT": "Created At", "CREATED_AT": "تم إنشاؤها في",
"LAST_ACTIVITY": "آخر نشاط" "LAST_ACTIVITY": "آخر نشاط"
}, },
"GROUPS": { "GROUPS": {

View file

@ -23,7 +23,7 @@
"is_not_present": "غير موجود", "is_not_present": "غير موجود",
"is_greater_than": "هو أكبر من", "is_greater_than": "هو أكبر من",
"is_lesser_than": "هو أقل من", "is_lesser_than": "هو أقل من",
"days_before": "Is x days before" "days_before": "قبل x أيام"
}, },
"ATTRIBUTES": { "ATTRIBUTES": {
"NAME": "الاسم", "NAME": "الاسم",
@ -37,7 +37,7 @@
"CUSTOM_ATTRIBUTE_NUMBER": "العدد", "CUSTOM_ATTRIBUTE_NUMBER": "العدد",
"CUSTOM_ATTRIBUTE_LINK": "الرابط", "CUSTOM_ATTRIBUTE_LINK": "الرابط",
"CUSTOM_ATTRIBUTE_CHECKBOX": "مربع", "CUSTOM_ATTRIBUTE_CHECKBOX": "مربع",
"CREATED_AT": "Created At", "CREATED_AT": "تم إنشاؤها في",
"LAST_ACTIVITY": "آخر نشاط" "LAST_ACTIVITY": "آخر نشاط"
}, },
"GROUPS": { "GROUPS": {

View file

@ -48,7 +48,7 @@
} }
}, },
"UPDATE_CHATWOOT": "يتوفر تحديث %{latestChatwootVersion} لـ Chatwoot. الرجاء التحديث.", "UPDATE_CHATWOOT": "يتوفر تحديث %{latestChatwootVersion} لـ Chatwoot. الرجاء التحديث.",
"LEARN_MORE": "Learn more" "LEARN_MORE": "اعرف المزيد"
}, },
"FORMS": { "FORMS": {
"MULTISELECT": { "MULTISELECT": {

View file

@ -186,7 +186,7 @@
"NO_CONTACTS": "There are no available contacts", "NO_CONTACTS": "There are no available contacts",
"TABLE_HEADER": { "TABLE_HEADER": {
"NAME": "Nome", "NAME": "Nome",
"PHONE_NUMBER": "Phone Number", "PHONE_NUMBER": "Numero di telefono",
"CONVERSATIONS": "Conversazioni", "CONVERSATIONS": "Conversazioni",
"LAST_ACTIVITY": "Last Activity", "LAST_ACTIVITY": "Last Activity",
"COUNTRY": "Country", "COUNTRY": "Country",

View file

@ -2,7 +2,7 @@
"GENERAL_SETTINGS": { "GENERAL_SETTINGS": {
"TITLE": "Impostazioni account", "TITLE": "Impostazioni account",
"SUBMIT": "Aggiorna le impostazioni", "SUBMIT": "Aggiorna le impostazioni",
"BACK": "Back", "BACK": "Indietro",
"UPDATE": { "UPDATE": {
"ERROR": "Impossibile aggiornare le impostazioni, riprova!", "ERROR": "Impossibile aggiornare le impostazioni, riprova!",
"SUCCESS": "Impostazioni account aggiornate con successo" "SUCCESS": "Impostazioni account aggiornate con successo"
@ -14,8 +14,8 @@
"NOTE": "" "NOTE": ""
}, },
"ACCOUNT_ID": { "ACCOUNT_ID": {
"TITLE": "Account ID", "TITLE": "ID Account",
"NOTE": "This ID is required if you are building an API based integration" "NOTE": "Questo ID è richiesto se si sta costruendo un'integrazione basata su API"
}, },
"NAME": { "NAME": {
"LABEL": "Nome account", "LABEL": "Nome account",
@ -28,8 +28,8 @@
"ERROR": "" "ERROR": ""
}, },
"DOMAIN": { "DOMAIN": {
"LABEL": "Incoming Email Domain", "LABEL": "Dominio email in entrata",
"PLACEHOLDER": "The domain where you will receive the emails", "PLACEHOLDER": "Il dominio in cui riceverai le email",
"ERROR": "" "ERROR": ""
}, },
"SUPPORT_EMAIL": { "SUPPORT_EMAIL": {
@ -38,95 +38,95 @@
"ERROR": "" "ERROR": ""
}, },
"AUTO_RESOLVE_DURATION": { "AUTO_RESOLVE_DURATION": {
"LABEL": "Number of days after a ticket should auto resolve if there is no activity", "LABEL": "Numero di giorni dopo che un ticket dovrebbe risolvere automaticamente se non c'è attività",
"PLACEHOLDER": "30", "PLACEHOLDER": "30",
"ERROR": "Please enter a valid auto resolve duration (minimum 1 day and maximum 999 days)" "ERROR": "Inserisci una durata di risoluzione automatica valida (minimo 1 giorno e massimo 999 giorni)"
}, },
"FEATURES": { "FEATURES": {
"INBOUND_EMAIL_ENABLED": "Conversation continuity with emails is enabled for your account.", "INBOUND_EMAIL_ENABLED": "La continuità della conversazione con le email è abilitata per il tuo account.",
"CUSTOM_EMAIL_DOMAIN_ENABLED": "You can receive emails in your custom domain now." "CUSTOM_EMAIL_DOMAIN_ENABLED": "Puoi ricevere email nel tuo dominio personalizzato ora."
} }
}, },
"UPDATE_CHATWOOT": "An update %{latestChatwootVersion} for Chatwoot is available. Please update your instance.", "UPDATE_CHATWOOT": "È disponibile un aggiornamento %{latestChatwootVersion} per Chatwoot. Aggiorna la tua istanza.",
"LEARN_MORE": "Learn more" "LEARN_MORE": "Scopri di più"
}, },
"FORMS": { "FORMS": {
"MULTISELECT": { "MULTISELECT": {
"ENTER_TO_SELECT": "Press enter to select", "ENTER_TO_SELECT": "Premi Invio per selezionare",
"ENTER_TO_REMOVE": "Press enter to remove", "ENTER_TO_REMOVE": "Premi Invio per rimuovere",
"SELECT_ONE": "Select one" "SELECT_ONE": "Selezionane uno"
} }
}, },
"NOTIFICATIONS_PAGE": { "NOTIFICATIONS_PAGE": {
"HEADER": "Notifiche", "HEADER": "Notifiche",
"MARK_ALL_DONE": "Mark All Done", "MARK_ALL_DONE": "Contrassegna tutto come fatto",
"LIST": { "LIST": {
"LOADING_MESSAGE": "Loading notifications...", "LOADING_MESSAGE": "Caricamento notifiche...",
"404": "No Notifications", "404": "Nessuna notifica",
"TABLE_HEADER": [ "TABLE_HEADER": [
"Nome", "Nome",
"Phone Number", "Numero di telefono",
"Conversazioni", "Conversazioni",
"Last Contacted" "Ultimo contattato"
] ]
}, },
"TYPE_LABEL": { "TYPE_LABEL": {
"conversation_creation": "New conversation", "conversation_creation": "Nuova conversazione",
"conversation_assignment": "Conversation Assigned", "conversation_assignment": "Conversazione assegnata",
"assigned_conversation_new_message": "New Message", "assigned_conversation_new_message": "Nuovo messaggio",
"conversation_mention": "Mention" "conversation_mention": "Menzione"
} }
}, },
"NETWORK": { "NETWORK": {
"NOTIFICATION": { "NOTIFICATION": {
"TEXT": "Disconnected from Chatwoot" "TEXT": "Disconnesso da Chatwoot"
}, },
"BUTTON": { "BUTTON": {
"REFRESH": "Refresh" "REFRESH": "Aggiorna"
} }
}, },
"COMMAND_BAR": { "COMMAND_BAR": {
"SEARCH_PLACEHOLDER": "Search or jump to", "SEARCH_PLACEHOLDER": "Cerca o salta a",
"SECTIONS": { "SECTIONS": {
"GENERAL": "General", "GENERAL": "Generale",
"REPORTS": "Segnalazioni", "REPORTS": "Segnalazioni",
"CONVERSATION": "Conversazioni", "CONVERSATION": "Conversazioni",
"CHANGE_ASSIGNEE": "Change Assignee", "CHANGE_ASSIGNEE": "Cambia assegnatario",
"CHANGE_TEAM": "Change Team", "CHANGE_TEAM": "Cambia Team",
"ADD_LABEL": "Add label to the conversation", "ADD_LABEL": "Aggiungi etichetta alla conversazione",
"REMOVE_LABEL": "Remove label from the conversation", "REMOVE_LABEL": "Rimuovi etichetta dalla conversazione",
"SETTINGS": "Impostazioni" "SETTINGS": "Impostazioni"
}, },
"COMMANDS": { "COMMANDS": {
"GO_TO_CONVERSATION_DASHBOARD": "Vai alla dashboard Conversazioni", "GO_TO_CONVERSATION_DASHBOARD": "Vai alla dashboard Conversazioni",
"GO_TO_CONTACTS_DASHBOARD": "Vai alla dashboard Contatti", "GO_TO_CONTACTS_DASHBOARD": "Vai alla dashboard Contatti",
"GO_TO_REPORTS_OVERVIEW": "Go to Reports Overview", "GO_TO_REPORTS_OVERVIEW": "Vai alla panoramica dei report",
"GO_TO_AGENT_REPORTS": "Go to Agent Reports", "GO_TO_AGENT_REPORTS": "Vai ai report degli agenti",
"GO_TO_LABEL_REPORTS": "Go to Label Reports", "GO_TO_LABEL_REPORTS": "Vai ai report delle etichette",
"GO_TO_INBOX_REPORTS": "Go to Inbox Reports", "GO_TO_INBOX_REPORTS": "Vai ai report delle caselle",
"GO_TO_TEAM_REPORTS": "Go to Team Reports", "GO_TO_TEAM_REPORTS": "Vai ai report dei team",
"GO_TO_SETTINGS_AGENTS": "Go to Agent Settings", "GO_TO_SETTINGS_AGENTS": "Vai alle impostazioni dell'agente",
"GO_TO_SETTINGS_TEAMS": "Go to Team Settings", "GO_TO_SETTINGS_TEAMS": "Vai alle impostazioni del team",
"GO_TO_SETTINGS_INBOXES": "Go to Inbox Settings", "GO_TO_SETTINGS_INBOXES": "Vai alle impostazioni delle caselle",
"GO_TO_SETTINGS_LABELS": "Go to Label Settings", "GO_TO_SETTINGS_LABELS": "Vai alle impostazioni delle etichette",
"GO_TO_SETTINGS_CANNED_RESPONSES": "Go to Canned Response Settings", "GO_TO_SETTINGS_CANNED_RESPONSES": "Vai alle impostazioni delle risposte predefinite",
"GO_TO_SETTINGS_APPLICATIONS": "Go to Application Settings", "GO_TO_SETTINGS_APPLICATIONS": "Vai alle impostazioni dell'applicazione",
"GO_TO_SETTINGS_ACCOUNT": "Go to Account Settings", "GO_TO_SETTINGS_ACCOUNT": "Vai alle impostazioni dell'account",
"GO_TO_SETTINGS_PROFILE": "Go to Profile Settings", "GO_TO_SETTINGS_PROFILE": "Vai alle impostazioni del profilo",
"GO_TO_NOTIFICATIONS": "Go to Notifications", "GO_TO_NOTIFICATIONS": "Vai alle notifiche",
"ADD_LABELS_TO_CONVERSATION": "Add label to the conversation", "ADD_LABELS_TO_CONVERSATION": "Aggiungi etichetta alla conversazione",
"ASSIGN_AN_AGENT": "Assign an agent", "ASSIGN_AN_AGENT": "Assegna un agente",
"ASSIGN_A_TEAM": "Assign a team", "ASSIGN_A_TEAM": "Assegna un team",
"MUTE_CONVERSATION": "Mute conversation", "MUTE_CONVERSATION": "Silenzia conversazione",
"UNMUTE_CONVERSATION": "Unmute conversation", "UNMUTE_CONVERSATION": "Riattiva conversazione",
"REMOVE_LABEL_FROM_CONVERSATION": "Remove label from the conversation", "REMOVE_LABEL_FROM_CONVERSATION": "Rimuovi etichetta dalla conversazione",
"REOPEN_CONVERSATION": "Riapri la conversazione", "REOPEN_CONVERSATION": "Riapri la conversazione",
"RESOLVE_CONVERSATION": "Risolvi la conversazione", "RESOLVE_CONVERSATION": "Risolvi la conversazione",
"SEND_TRANSCRIPT": "Send an email transcript", "SEND_TRANSCRIPT": "Invia una trascrizione email",
"SNOOZE_CONVERSATION": "Snooze Conversation", "SNOOZE_CONVERSATION": "Posticipa conversazione",
"UNTIL_NEXT_REPLY": "Until next reply", "UNTIL_NEXT_REPLY": "Fino alla prossima risposta",
"UNTIL_NEXT_WEEK": "Until next week", "UNTIL_NEXT_WEEK": "Fino alla prossima settimana",
"UNTIL_TOMORROW": "Until tomorrow" "UNTIL_TOMORROW": "Fino a domani"
} }
} }
} }

View file

@ -148,7 +148,7 @@
}, },
"BANDWIDTH": { "BANDWIDTH": {
"ACCOUNT_ID": { "ACCOUNT_ID": {
"LABEL": "Account ID", "LABEL": "ID Account",
"PLACEHOLDER": "Please enter your Bandwidth Account ID", "PLACEHOLDER": "Please enter your Bandwidth Account ID",
"ERROR": "Questo campo è obbligatorio" "ERROR": "Questo campo è obbligatorio"
}, },

View file

@ -22,11 +22,11 @@
"is_not_present": "Não está presente", "is_not_present": "Não está presente",
"is_greater_than": "É maior do que", "is_greater_than": "É maior do que",
"is_less_than": "É menor do que", "is_less_than": "É menor do que",
"days_before": "Is x days before" "days_before": "É x dias antes"
}, },
"ATTRIBUTE_LABELS": { "ATTRIBUTE_LABELS": {
"TRUE": "True", "TRUE": "Verdadeiro",
"FALSE": "False" "FALSE": "Falso"
}, },
"ATTRIBUTES": { "ATTRIBUTES": {
"STATUS": "SItuação", "STATUS": "SItuação",
@ -44,7 +44,7 @@
"CUSTOM_ATTRIBUTE_NUMBER": "Número", "CUSTOM_ATTRIBUTE_NUMBER": "Número",
"CUSTOM_ATTRIBUTE_LINK": "Endereço", "CUSTOM_ATTRIBUTE_LINK": "Endereço",
"CUSTOM_ATTRIBUTE_CHECKBOX": "Caixa de Seleção", "CUSTOM_ATTRIBUTE_CHECKBOX": "Caixa de Seleção",
"CREATED_AT": "Created At", "CREATED_AT": "Criado Em",
"LAST_ACTIVITY": "Última atividade" "LAST_ACTIVITY": "Última atividade"
}, },
"GROUPS": { "GROUPS": {

View file

@ -29,7 +29,7 @@
"PLACEHOLDER": "Por favor, selecione um tipo", "PLACEHOLDER": "Por favor, selecione um tipo",
"ERROR": "Tipo é obrigatório", "ERROR": "Tipo é obrigatório",
"LIST": { "LIST": {
"LABEL": "List Values", "LABEL": "Listar Valores",
"PLACEHOLDER": "Por favor insira um valor e pressione Enter", "PLACEHOLDER": "Por favor insira um valor e pressione Enter",
"ERROR": "Deve possuir pelo menos um valor" "ERROR": "Deve possuir pelo menos um valor"
} }
@ -42,7 +42,7 @@
} }
}, },
"API": { "API": {
"SUCCESS_MESSAGE": "Custom Attribute added successfully", "SUCCESS_MESSAGE": "Atributo Personalizado adicionado com sucesso",
"ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later" "ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later"
} }
}, },

View file

@ -1,38 +1,38 @@
{ {
"AUTOMATION": { "AUTOMATION": {
"HEADER": "Automations", "HEADER": "Automatizações",
"HEADER_BTN_TXT": "Add Automation Rule", "HEADER_BTN_TXT": "Adicionar Regra de Automação",
"LOADING": "Fetching automation rules", "LOADING": "Fetching automation rules",
"SIDEBAR_TXT": "<p><b>Automation Rules</b> <p>Automation can replace and automate existing processes that require manual effort. You can do many things with automation, including adding labels and assigning conversation to the best agent. So the team focuses on what they do best and spends more little time on manual tasks.</p>", "SIDEBAR_TXT": "<p><b>Automation Rules</b> <p>Automation can replace and automate existing processes that require manual effort. You can do many things with automation, including adding labels and assigning conversation to the best agent. So the team focuses on what they do best and spends more little time on manual tasks.</p>",
"ADD": { "ADD": {
"TITLE": "Add Automation Rule", "TITLE": "Adicionar Regra de Automação",
"SUBMIT": "Criar", "SUBMIT": "Criar",
"CANCEL_BUTTON_TEXT": "cancelar", "CANCEL_BUTTON_TEXT": "cancelar",
"FORM": { "FORM": {
"NAME": { "NAME": {
"LABEL": "Rule Name", "LABEL": "Nome da Regra",
"PLACEHOLDER": "Enter rule name", "PLACEHOLDER": "Insira nome da regra",
"ERROR": "Nome é obrigatório" "ERROR": "Nome é obrigatório"
}, },
"DESC": { "DESC": {
"LABEL": "Descrição", "LABEL": "Descrição",
"PLACEHOLDER": "Enter rule description", "PLACEHOLDER": "Insera descrição da regra",
"ERROR": "Descrição é obrigatória" "ERROR": "Descrição é obrigatória"
}, },
"EVENT": { "EVENT": {
"LABEL": "Event", "LABEL": "Evento",
"PLACEHOLDER": "Por favor selecione um", "PLACEHOLDER": "Por favor selecione um",
"ERROR": "Event is required" "ERROR": "Evento é necessário"
}, },
"CONDITIONS": { "CONDITIONS": {
"LABEL": "Conditions" "LABEL": "Condições"
}, },
"ACTIONS": { "ACTIONS": {
"LABEL": "Ações." "LABEL": "Ações."
} }
}, },
"CONDITION_BUTTON_LABEL": "Add Condition", "CONDITION_BUTTON_LABEL": "Adicionar Condição",
"ACTION_BUTTON_LABEL": "Add Action", "ACTION_BUTTON_LABEL": "Adicionar Ação",
"API": { "API": {
"SUCCESS_MESSAGE": "Automation rule added successfully", "SUCCESS_MESSAGE": "Automation rule added successfully",
"ERROR_MESSAGE": "Could not able to create a automation rule, Please try again later" "ERROR_MESSAGE": "Could not able to create a automation rule, Please try again later"
@ -43,12 +43,12 @@
"Nome:", "Nome:",
"Descrição", "Descrição",
"Ativa", "Ativa",
"Created on" "Criado em"
], ],
"404": "No automation rules found" "404": "Nenhuma regra de automação encontrada"
}, },
"DELETE": { "DELETE": {
"TITLE": "Delete Automation Rule", "TITLE": "Apagar Regra de Automação",
"SUBMIT": "excluir", "SUBMIT": "excluir",
"CANCEL_BUTTON_TEXT": "cancelar", "CANCEL_BUTTON_TEXT": "cancelar",
"CONFIRM": { "CONFIRM": {
@ -63,7 +63,7 @@
} }
}, },
"EDIT": { "EDIT": {
"TITLE": "Edit Automation Rule", "TITLE": "Editar Regra de Automação",
"SUBMIT": "Atualização", "SUBMIT": "Atualização",
"CANCEL_BUTTON_TEXT": "cancelar", "CANCEL_BUTTON_TEXT": "cancelar",
"API": { "API": {
@ -74,8 +74,8 @@
"CLONE": { "CLONE": {
"TOOLTIP": "Clone", "TOOLTIP": "Clone",
"API": { "API": {
"SUCCESS_MESSAGE": "Automation cloned successfully", "SUCCESS_MESSAGE": "Automação clonada com sucesso",
"ERROR_MESSAGE": "Could not clone automation rule, Please try again later" "ERROR_MESSAGE": "Não foi possível clonar regra de automação, por favor, tente novamente mais tarde"
} }
}, },
"FORM": { "FORM": {
@ -86,20 +86,20 @@
"RESET_MESSAGE": "Changing event type will reset the conditions and events you have added below" "RESET_MESSAGE": "Changing event type will reset the conditions and events you have added below"
}, },
"CONDITION": { "CONDITION": {
"DELETE_MESSAGE": "You need to have atleast one condition to save" "DELETE_MESSAGE": "É necessário ter pelo menos uma condição para salvar"
}, },
"ACTION": { "ACTION": {
"DELETE_MESSAGE": "You need to have atleast one action to save" "DELETE_MESSAGE": "É necessário ter pelo menos uma ação para salvar"
}, },
"TOGGLE": { "TOGGLE": {
"ACTIVATION_TITLE": "Activate Automation Rule", "ACTIVATION_TITLE": "Ativar Regra de Automação",
"DEACTIVATION_TITLE": "Deactivate Automation Rule", "DEACTIVATION_TITLE": "Desativar Regra de Automação",
"ACTIVATION_DESCRIPTION": "This action will activate the automation rule '{automationName}'. Are you sure you want to proceed?", "ACTIVATION_DESCRIPTION": "Esta ação irá ativar a regra de automação '{automationName}'. Tem a certeza que deseja continuar?",
"DEACTIVATION_DESCRIPTION": "This action will deactivate the automation rule '{automationName}'. Are you sure you want to proceed?", "DEACTIVATION_DESCRIPTION": "Esta ação irá desativar a regra de automação '{automationName}'. Tem a certeza que deseja continuar?",
"ACTIVATION_SUCCESFUL": "Automation Rule Activated Successfully", "ACTIVATION_SUCCESFUL": "Regra de Automação Ativada com Sucesso",
"DEACTIVATION_SUCCESFUL": "Automation Rule Deactivated Successfully", "DEACTIVATION_SUCCESFUL": "Regra de Automação Desativada com Sucesso",
"ACTIVATION_ERROR": "Could not Activate Automation, Please try again later", "ACTIVATION_ERROR": "Não foi possível Ativar a Automação, por favor, tente novamente mais tarde",
"DEACTIVATION_ERROR": "Could not Deactivate Automation, Please try again later", "DEACTIVATION_ERROR": "Não foi possível Desativar a Automação, por favor, tente novamente mais tarde",
"CONFIRMATION_LABEL": "Sim", "CONFIRMATION_LABEL": "Sim",
"CANCEL_LABEL": "Não" "CANCEL_LABEL": "Não"
} }

View file

@ -54,7 +54,7 @@
"ERROR": "O tempo na página é obrigatório" "ERROR": "O tempo na página é obrigatório"
}, },
"ENABLED": "Ativar a campanha", "ENABLED": "Ativar a campanha",
"TRIGGER_ONLY_BUSINESS_HOURS": "Trigger only during business hours", "TRIGGER_ONLY_BUSINESS_HOURS": "Ativar apenas durante o horário de trabalho",
"SUBMIT": "Adicionar Campanha" "SUBMIT": "Adicionar Campanha"
}, },
"API": { "API": {

View file

@ -1,15 +1,15 @@
{ {
"CONTACTS_FILTER": { "CONTACTS_FILTER": {
"TITLE": "Filter Contacts", "TITLE": "Filtrar Contactos",
"SUBTITLE": "Add filters below and hit 'Submit' to filter contacts.", "SUBTITLE": "Adicionar filtros abaixo e clicar 'Submeter' para filtrar contactos.",
"ADD_NEW_FILTER": "Adicionar Filtro", "ADD_NEW_FILTER": "Adicionar Filtro",
"CLEAR_ALL_FILTERS": "Clear All Filters", "CLEAR_ALL_FILTERS": "Limpar Todos os Filtros",
"FILTER_DELETE_ERROR": "Você deve ter pelo menos um filtro para guardar", "FILTER_DELETE_ERROR": "Você deve ter pelo menos um filtro para guardar",
"SUBMIT_BUTTON_LABEL": "submeter", "SUBMIT_BUTTON_LABEL": "submeter",
"CANCEL_BUTTON_LABEL": "cancelar", "CANCEL_BUTTON_LABEL": "cancelar",
"CLEAR_BUTTON_LABEL": "Limpar Filtros", "CLEAR_BUTTON_LABEL": "Limpar Filtros",
"EMPTY_VALUE_ERROR": "Valor obrigatório", "EMPTY_VALUE_ERROR": "Valor obrigatório",
"TOOLTIP_LABEL": "Filter contacts", "TOOLTIP_LABEL": "Filtrar contactos",
"QUERY_DROPDOWN_LABELS": { "QUERY_DROPDOWN_LABELS": {
"AND": "E", "AND": "E",
"OR": "OU" "OR": "OU"
@ -23,13 +23,13 @@
"is_not_present": "Não está presente", "is_not_present": "Não está presente",
"is_greater_than": "É maior do que", "is_greater_than": "É maior do que",
"is_lesser_than": "É menor do que", "is_lesser_than": "É menor do que",
"days_before": "Is x days before" "days_before": "É x dias antes"
}, },
"ATTRIBUTES": { "ATTRIBUTES": {
"NAME": "Nome:", "NAME": "Nome:",
"EMAIL": "e-mail", "EMAIL": "e-mail",
"PHONE_NUMBER": "Número de telefone", "PHONE_NUMBER": "Número de telefone",
"IDENTIFIER": "Identifier", "IDENTIFIER": "Identificador",
"CITY": "Cidade", "CITY": "Cidade",
"COUNTRY": "País", "COUNTRY": "País",
"CUSTOM_ATTRIBUTE_LIST": "Lista", "CUSTOM_ATTRIBUTE_LIST": "Lista",
@ -37,7 +37,7 @@
"CUSTOM_ATTRIBUTE_NUMBER": "Número", "CUSTOM_ATTRIBUTE_NUMBER": "Número",
"CUSTOM_ATTRIBUTE_LINK": "Endereço", "CUSTOM_ATTRIBUTE_LINK": "Endereço",
"CUSTOM_ATTRIBUTE_CHECKBOX": "Caixa de Seleção", "CUSTOM_ATTRIBUTE_CHECKBOX": "Caixa de Seleção",
"CREATED_AT": "Created At", "CREATED_AT": "Criado Em",
"LAST_ACTIVITY": "Última atividade" "LAST_ACTIVITY": "Última atividade"
}, },
"GROUPS": { "GROUPS": {

View file

@ -57,9 +57,9 @@
} }
}, },
"FOOTER": { "FOOTER": {
"MESSAGE_SIGN_TOOLTIP": "Message signature", "MESSAGE_SIGN_TOOLTIP": "Assinatura da mensagem",
"ENABLE_SIGN_TOOLTIP": "Enable signature", "ENABLE_SIGN_TOOLTIP": "Habilitar assinatura",
"DISABLE_SIGN_TOOLTIP": "Disable signature", "DISABLE_SIGN_TOOLTIP": "Desativar assinatura",
"MSG_INPUT": "Shift + enter para nova linha. Comece com '/' para selecionar uma Resposta Pronta.", "MSG_INPUT": "Shift + enter para nova linha. Comece com '/' para selecionar uma Resposta Pronta.",
"PRIVATE_MSG_INPUT": "Shift + Enter para a nova linha. Isto será visível apenas para Agentes", "PRIVATE_MSG_INPUT": "Shift + Enter para a nova linha. Isto será visível apenas para Agentes",
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.", "MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
@ -166,7 +166,7 @@
}, },
"ACCORDION": { "ACCORDION": {
"CONTACT_DETAILS": "Detalhes do Contacto", "CONTACT_DETAILS": "Detalhes do Contacto",
"CONVERSATION_ACTIONS": "Conversation Actions", "CONVERSATION_ACTIONS": "Ações de Conversa",
"CONVERSATION_LABELS": "Etiquetas da conversa", "CONVERSATION_LABELS": "Etiquetas da conversa",
"CONVERSATION_INFO": "Conversation Information", "CONVERSATION_INFO": "Conversation Information",
"CONTACT_ATTRIBUTES": "Atributos do Contato", "CONTACT_ATTRIBUTES": "Atributos do Contato",

View file

@ -48,7 +48,7 @@
} }
}, },
"UPDATE_CHATWOOT": "Está disponível uma nova atualização %{latestChatwootVersion} para o ChatWoot. Por favor, atualize a sua versão.", "UPDATE_CHATWOOT": "Está disponível uma nova atualização %{latestChatwootVersion} para o ChatWoot. Por favor, atualize a sua versão.",
"LEARN_MORE": "Learn more" "LEARN_MORE": "Saiba mais"
}, },
"FORMS": { "FORMS": {
"MULTISELECT": { "MULTISELECT": {
@ -79,7 +79,7 @@
}, },
"NETWORK": { "NETWORK": {
"NOTIFICATION": { "NOTIFICATION": {
"TEXT": "Disconnected from Chatwoot" "TEXT": "Desconectado do Chatwoot"
}, },
"BUTTON": { "BUTTON": {
"REFRESH": "Atualizar" "REFRESH": "Atualizar"
@ -116,17 +116,17 @@
"GO_TO_NOTIFICATIONS": "Ir para Notificações", "GO_TO_NOTIFICATIONS": "Ir para Notificações",
"ADD_LABELS_TO_CONVERSATION": "Adicionar etiqueta à conversa", "ADD_LABELS_TO_CONVERSATION": "Adicionar etiqueta à conversa",
"ASSIGN_AN_AGENT": "Atribuir um agente", "ASSIGN_AN_AGENT": "Atribuir um agente",
"ASSIGN_A_TEAM": "Assign a team", "ASSIGN_A_TEAM": "Atribuir uma equipa",
"MUTE_CONVERSATION": "Silenciar Conversa", "MUTE_CONVERSATION": "Silenciar Conversa",
"UNMUTE_CONVERSATION": "Unmute conversation", "UNMUTE_CONVERSATION": "Reativar conversa",
"REMOVE_LABEL_FROM_CONVERSATION": "Remover etiqueta da conversa", "REMOVE_LABEL_FROM_CONVERSATION": "Remover etiqueta da conversa",
"REOPEN_CONVERSATION": "Reopen conversation", "REOPEN_CONVERSATION": "Reabrir conversa",
"RESOLVE_CONVERSATION": "Resolve conversation", "RESOLVE_CONVERSATION": "Resolver conversa",
"SEND_TRANSCRIPT": "Send an email transcript", "SEND_TRANSCRIPT": "Enviar transcrição por e-mail",
"SNOOZE_CONVERSATION": "Snooze Conversation", "SNOOZE_CONVERSATION": "Snooze Conversation",
"UNTIL_NEXT_REPLY": "Until next reply", "UNTIL_NEXT_REPLY": "Até à próxima resposta",
"UNTIL_NEXT_WEEK": "Until next week", "UNTIL_NEXT_WEEK": "Até à próxima semana",
"UNTIL_TOMORROW": "Until tomorrow" "UNTIL_TOMORROW": "Até amanhã"
} }
} }
} }

View file

@ -61,7 +61,7 @@
}, },
"CHANNEL_WEBHOOK_URL": { "CHANNEL_WEBHOOK_URL": {
"LABEL": "URL do Webhook", "LABEL": "URL do Webhook",
"PLACEHOLDER": "Enter your Webhook URL", "PLACEHOLDER": "Introduza o seu URL Webhook",
"ERROR": "Por favor, insira uma URL válida" "ERROR": "Por favor, insira uma URL válida"
}, },
"CHANNEL_DOMAIN": { "CHANNEL_DOMAIN": {
@ -118,7 +118,7 @@
}, },
"CHANNEL_NAME": { "CHANNEL_NAME": {
"LABEL": "Nome Caixa de Entrada", "LABEL": "Nome Caixa de Entrada",
"PLACEHOLDER": "Please enter a inbox name", "PLACEHOLDER": "Por favor, insira um nome para a caixa de entrada",
"ERROR": "Este campo é obrigatório" "ERROR": "Este campo é obrigatório"
}, },
"PHONE_NUMBER": { "PHONE_NUMBER": {
@ -137,14 +137,14 @@
}, },
"SMS": { "SMS": {
"TITLE": "Canal SMS", "TITLE": "Canal SMS",
"DESC": "Start supporting your customers via SMS.", "DESC": "Comece a apoiar os seus clientes via SMS.",
"PROVIDERS": { "PROVIDERS": {
"LABEL": "API Provider", "LABEL": "API Provider",
"TWILIO": "Twilio", "TWILIO": "Twilio",
"BANDWIDTH": "Banda" "BANDWIDTH": "Banda"
}, },
"API": { "API": {
"ERROR_MESSAGE": "We were not able to save the SMS channel" "ERROR_MESSAGE": "Não conseguimos salvar o canal de SMS"
}, },
"BANDWIDTH": { "BANDWIDTH": {
"ACCOUNT_ID": { "ACCOUNT_ID": {
@ -469,7 +469,7 @@
"TITLE": "IMAP", "TITLE": "IMAP",
"SUBTITLE": "Defina os seus dados IMAP", "SUBTITLE": "Defina os seus dados IMAP",
"UPDATE": "Atualizar configurações IMAP", "UPDATE": "Atualizar configurações IMAP",
"TOGGLE_AVAILABILITY": "Enable IMAP configuration for this inbox", "TOGGLE_AVAILABILITY": "Ativar a configuração IMAP para esta caixa de entrada",
"TOGGLE_HELP": "Enabling IMAP will help the user to recieve email", "TOGGLE_HELP": "Enabling IMAP will help the user to recieve email",
"EDIT": { "EDIT": {
"SUCCESS_MESSAGE": "IMAP settings updated successfully", "SUCCESS_MESSAGE": "IMAP settings updated successfully",

View file

@ -30,7 +30,7 @@
}, },
"LIST": { "LIST": {
"FETCHING": "Procurando Hooks de integração", "FETCHING": "Procurando Hooks de integração",
"INBOX": "Recebidas", "INBOX": "Caixa de Entrada",
"DELETE": { "DELETE": {
"BUTTON_TEXT": "excluir" "BUTTON_TEXT": "excluir"
} }

View file

@ -240,7 +240,7 @@
"HEADER": "Visão Geral da Caixa de Entrada", "HEADER": "Visão Geral da Caixa de Entrada",
"LOADING_CHART": "Carregando dados da carta...", "LOADING_CHART": "Carregando dados da carta...",
"NO_ENOUGH_DATA": "Não recebemos pontos de dados suficientes para gerar o relatório. Por favor, tente novamente mais tarde.", "NO_ENOUGH_DATA": "Não recebemos pontos de dados suficientes para gerar o relatório. Por favor, tente novamente mais tarde.",
"DOWNLOAD_INBOX_REPORTS": "Download inbox reports", "DOWNLOAD_INBOX_REPORTS": "Descarregar relatórios de caixa de entrada",
"FILTER_DROPDOWN_LABEL": "Escolher caixa de entrada", "FILTER_DROPDOWN_LABEL": "Escolher caixa de entrada",
"METRICS": { "METRICS": {
"CONVERSATIONS": { "CONVERSATIONS": {
@ -300,11 +300,11 @@
} }
}, },
"TEAM_REPORTS": { "TEAM_REPORTS": {
"HEADER": "Team Overview", "HEADER": "Resumo de Equipa",
"LOADING_CHART": "Carregando dados da carta...", "LOADING_CHART": "Carregando dados da carta...",
"NO_ENOUGH_DATA": "Não recebemos pontos de dados suficientes para gerar o relatório. Por favor, tente novamente mais tarde.", "NO_ENOUGH_DATA": "Não recebemos pontos de dados suficientes para gerar o relatório. Por favor, tente novamente mais tarde.",
"DOWNLOAD_TEAM_REPORTS": "Download team reports", "DOWNLOAD_TEAM_REPORTS": "Descarregar relatórios de equipa",
"FILTER_DROPDOWN_LABEL": "Select Team", "FILTER_DROPDOWN_LABEL": "Escolher Equipa",
"METRICS": { "METRICS": {
"CONVERSATIONS": { "CONVERSATIONS": {
"NAME": "Conversas", "NAME": "Conversas",
@ -367,7 +367,7 @@
"NO_RECORDS": "Sem dados CSAT disponíveis para reposta.", "NO_RECORDS": "Sem dados CSAT disponíveis para reposta.",
"FILTERS": { "FILTERS": {
"AGENTS": { "AGENTS": {
"PLACEHOLDER": "Choose Agents" "PLACEHOLDER": "Escolher Agentes"
} }
}, },
"TABLE": { "TABLE": {

View file

@ -101,21 +101,21 @@
"PLACEHOLDER": "Por favor, digite a password atual" "PLACEHOLDER": "Por favor, digite a password atual"
}, },
"PASSWORD": { "PASSWORD": {
"LABEL": "New password", "LABEL": "Nova senha",
"ERROR": "Por favor, digite uma senha de comprimento 6 ou mais", "ERROR": "Por favor, digite uma senha de comprimento 6 ou mais",
"PLACEHOLDER": "Por favor, digite uma nova senha" "PLACEHOLDER": "Por favor, digite uma nova senha"
}, },
"PASSWORD_CONFIRMATION": { "PASSWORD_CONFIRMATION": {
"LABEL": "Confirme a nova senha", "LABEL": "Confirme a nova senha",
"ERROR": "Confirme a senha deve corresponder à senha", "ERROR": "Confirme a senha deve corresponder à senha",
"PLACEHOLDER": "Please re-enter your new password" "PLACEHOLDER": "Por favor, digite novamente a sua senha nova"
} }
} }
}, },
"SIDEBAR_ITEMS": { "SIDEBAR_ITEMS": {
"CHANGE_AVAILABILITY_STATUS": "Trocar", "CHANGE_AVAILABILITY_STATUS": "Trocar",
"CHANGE_ACCOUNTS": "Trocar de conta", "CHANGE_ACCOUNTS": "Trocar de conta",
"CONTACT_SUPPORT": "Contact Support", "CONTACT_SUPPORT": "Contactar Suporte",
"SELECTOR_SUBTITLE": "Escolha uma conta da lista a seguir", "SELECTOR_SUBTITLE": "Escolha uma conta da lista a seguir",
"PROFILE_SETTINGS": "Configurações do perfil", "PROFILE_SETTINGS": "Configurações do perfil",
"KEYBOARD_SHORTCUTS": "Atalhos do teclado", "KEYBOARD_SHORTCUTS": "Atalhos do teclado",
@ -124,7 +124,7 @@
"APP_GLOBAL": { "APP_GLOBAL": {
"TRIAL_MESSAGE": "dias de teste restantes.", "TRIAL_MESSAGE": "dias de teste restantes.",
"TRAIL_BUTTON": "Comprar agora", "TRAIL_BUTTON": "Comprar agora",
"DELETED_USER": "Deleted User" "DELETED_USER": "Usuário Excluído"
}, },
"COMPONENTS": { "COMPONENTS": {
"CODE": { "CODE": {
@ -164,15 +164,15 @@
"APPLICATIONS": "Aplicações", "APPLICATIONS": "Aplicações",
"LABELS": "Etiquetas", "LABELS": "Etiquetas",
"CUSTOM_ATTRIBUTES": "Atributos personalizados", "CUSTOM_ATTRIBUTES": "Atributos personalizados",
"AUTOMATION": "Automation", "AUTOMATION": "Automatização",
"TEAMS": "Equipas", "TEAMS": "Equipas",
"CUSTOM_VIEWS_FOLDER": "Folders", "CUSTOM_VIEWS_FOLDER": "Pastas",
"CUSTOM_VIEWS_SEGMENTS": "Segments", "CUSTOM_VIEWS_SEGMENTS": "Segmentos",
"ALL_CONTACTS": "Todos os contatos", "ALL_CONTACTS": "Todos os contatos",
"TAGGED_WITH": "Etiquetada com", "TAGGED_WITH": "Etiquetada com",
"NEW_LABEL": "New label", "NEW_LABEL": "Nova etiqueta",
"NEW_TEAM": "New team", "NEW_TEAM": "Nova equipa",
"NEW_INBOX": "New inbox", "NEW_INBOX": "Nova caixa de entrada",
"REPORTS_OVERVIEW": "Visão geral", "REPORTS_OVERVIEW": "Visão geral",
"CSAT": "CSAT", "CSAT": "CSAT",
"CAMPAIGNS": "Campanhas", "CAMPAIGNS": "Campanhas",
@ -181,8 +181,8 @@
"REPORTS_AGENT": "Agentes", "REPORTS_AGENT": "Agentes",
"REPORTS_LABEL": "Etiquetas", "REPORTS_LABEL": "Etiquetas",
"REPORTS_INBOX": "Caixa de Entrada", "REPORTS_INBOX": "Caixa de Entrada",
"REPORTS_TEAM": "Team", "REPORTS_TEAM": "Equipa",
"SET_AVAILABILITY_TITLE": "Set yourself as", "SET_AVAILABILITY_TITLE": "Defina-se como",
"BETA": "Beta" "BETA": "Beta"
}, },
"CREATE_ACCOUNT": { "CREATE_ACCOUNT": {
@ -215,7 +215,7 @@
"GO_TO_REPORTS_SIDEBAR": "Ir para barra lateral de Relatórios", "GO_TO_REPORTS_SIDEBAR": "Ir para barra lateral de Relatórios",
"MOVE_TO_NEXT_TAB": "Mover para próximo separador da lista de conversas", "MOVE_TO_NEXT_TAB": "Mover para próximo separador da lista de conversas",
"GO_TO_SETTINGS": "Ir para as configurações", "GO_TO_SETTINGS": "Ir para as configurações",
"SWITCH_CONVERSATION_STATUS": "Switch to the next conversation status", "SWITCH_CONVERSATION_STATUS": "Mudar para o próximo estado de conversa",
"SWITCH_TO_PRIVATE_NOTE": "Alterar para nota privada", "SWITCH_TO_PRIVATE_NOTE": "Alterar para nota privada",
"TOGGLE_RICH_CONTENT_EDITOR": "Ativar/desativar editor de conteúdo", "TOGGLE_RICH_CONTENT_EDITOR": "Ativar/desativar editor de conteúdo",
"SWITCH_TO_REPLY": "Mudar para resposta", "SWITCH_TO_REPLY": "Mudar para resposta",

View file

@ -80,7 +80,11 @@ export default {
return false; return false;
}, },
}, },
watch: {
conversationId() {
this.fetchConversationIfUnavailable();
},
},
mounted() { mounted() {
this.$store.dispatch('agents/get'); this.$store.dispatch('agents/get');
this.initialize(); this.initialize();

View file

@ -79,7 +79,7 @@ export const AUTOMATIONS = {
// { // {
// key: 'send_email_to_team', // key: 'send_email_to_team',
// name: 'Send an email to team', // name: 'Send an email to team',
// attributeI18nKey: 'SEND_MESSAGE', // attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
// }, // },
], ],
}, },
@ -186,7 +186,7 @@ export const AUTOMATIONS = {
// { // {
// key: 'send_email_to_team', // key: 'send_email_to_team',
// name: 'Send an email to team', // name: 'Send an email to team',
// attributeI18nKey: 'SEND_MESSAGE', // attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
// }, // },
{ {
key: 'assign_agent', key: 'assign_agent',

View file

@ -66,9 +66,6 @@ export const actions = {
id: contactId, id: contactId,
data: response.data.payload, data: response.data.payload,
}); });
commit(types.default.SET_ALL_CONVERSATION, response.data.payload, {
root: true,
});
commit(types.default.SET_CONTACT_CONVERSATIONS_UI_FLAG, { commit(types.default.SET_CONTACT_CONVERSATIONS_UI_FLAG, {
isFetching: false, isFetching: false,
}); });

View file

@ -19,7 +19,6 @@ describe('#actions', () => {
types.default.SET_CONTACT_CONVERSATIONS, types.default.SET_CONTACT_CONVERSATIONS,
{ id: 1, data: conversationList }, { id: 1, data: conversationList },
], ],
[types.default.SET_ALL_CONVERSATION, conversationList, { root: true }],
[ [
types.default.SET_CONTACT_CONVERSATIONS_UI_FLAG, types.default.SET_CONTACT_CONVERSATIONS_UI_FLAG,
{ isFetching: false }, { isFetching: false },

View file

@ -22,7 +22,7 @@
"IN_A_DAY": "عادة نقوم بالرد خلال يوم واحد" "IN_A_DAY": "عادة نقوم بالرد خلال يوم واحد"
}, },
"START_CONVERSATION": "ابدأ المحادثة", "START_CONVERSATION": "ابدأ المحادثة",
"END_CONVERSATION": "End Conversation", "END_CONVERSATION": "إنهاء المحادثة",
"CONTINUE_CONVERSATION": "متابعة المحادثة", "CONTINUE_CONVERSATION": "متابعة المحادثة",
"START_NEW_CONVERSATION": "ابدأ محادثة جديدة", "START_NEW_CONVERSATION": "ابدأ محادثة جديدة",
"UNREAD_VIEW": { "UNREAD_VIEW": {

View file

@ -22,7 +22,7 @@
"IN_A_DAY": "Normalmente respondemos num dia" "IN_A_DAY": "Normalmente respondemos num dia"
}, },
"START_CONVERSATION": "Iniciar Conversa", "START_CONVERSATION": "Iniciar Conversa",
"END_CONVERSATION": "End Conversation", "END_CONVERSATION": "Terminar Conversa",
"CONTINUE_CONVERSATION": "Continuar conversa", "CONTINUE_CONVERSATION": "Continuar conversa",
"START_NEW_CONVERSATION": "Iniciar uma nova conversa", "START_NEW_CONVERSATION": "Iniciar uma nova conversa",
"UNREAD_VIEW": { "UNREAD_VIEW": {

View file

@ -1,51 +1,58 @@
class AutomationRuleListener < BaseListener class AutomationRuleListener < BaseListener
def conversation_updated(event_obj) def conversation_updated(event_obj)
conversation = event_obj.data[:conversation] conversation = event_obj.data[:conversation]
return unless rule_present?('conversation_updated', conversation) account = conversation.account
return unless rule_present?('conversation_updated', account)
@rules.each do |rule| @rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present? AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
end end
end end
def conversation_status_changed(event_obj) def conversation_status_changed(event_obj)
conversation = event_obj.data[:conversation] conversation = event_obj.data[:conversation]
return unless rule_present?('conversation_status_changed', conversation) account = conversation.account
return unless rule_present?('conversation_status_changed', account)
@rules.each do |rule| @rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present? AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
end end
end end
def conversation_created(event_obj) def conversation_created(event_obj)
conversation = event_obj.data[:conversation] conversation = event_obj.data[:conversation]
return unless rule_present?('conversation_created', conversation) account = conversation.account
return unless rule_present?('conversation_created', account)
@rules.each do |rule| @rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
::AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present? ::AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
end end
end end
def message_created(event_obj) def message_created(event_obj)
message = event_obj.data[:message] message = event_obj.data[:message]
conversation = message.conversation account = message.try(:account)
return unless rule_present?('message_created', conversation)
return unless rule_present?('message_created', account)
@rules.each do |rule| @rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).message_conditions(message) conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation).message_conditions
::AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present? ::AutomationRules::ActionService.new(rule, account, message.conversation).perform if conditions_match.present?
end end
end end
def rule_present?(event_name, conversation) def rule_present?(event_name, account)
return if conversation.blank? return if account.blank?
@rules = AutomationRule.where( @rules = AutomationRule.where(
event_name: event_name, event_name: event_name,
account_id: conversation.account_id, account_id: account.id,
active: true active: true
) )
@rules.any? @rules.any?

View file

@ -4,50 +4,57 @@ class TeamNotifications::AutomationNotificationMailer < ApplicationMailer
@agents = team.team_members @agents = team.team_members
@conversation = conversation @conversation = conversation
@message = message @custom_message = message
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id) @action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_an_email_to_team send_an_email_to_team and return
end end
def conversation_updated(conversation, team) def conversation_updated(conversation, team, message)
return unless smtp_config_set_or_development? return unless smtp_config_set_or_development?
@agents = team.team_members @agents = team.team_members
@conversation = conversation @conversation = conversation
@message = message @custom_message = message
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id) @action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_an_email_to_team send_an_email_to_team and return
end end
def message_created(message, agent) def message_created(conversation, team, message)
return unless smtp_config_set_or_development? return unless smtp_config_set_or_development?
@agent = agent @agents = team.team_members
@conversation = message.conversation @conversation = conversation
@message = message @custom_message = message
subject = "#{@agent.available_name}, You have been mentioned in conversation [ID - #{@conversation.display_id}]"
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id) @action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_mail_with_liquid(to: @agent.email, subject: subject)
send_an_email_to_team and return
end end
private private
def send_an_email_to_team def send_an_email_to_team
@agents.each do |agent| @agents.each do |agent|
subject = "#{@agent.available_name}, A new conversation [ID - #{@conversation.display_id}] has been created in #{@conversation.inbox&.name}." subject = "#{agent.user.available_name}, This email has been sent via automation rule actions."
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id) @action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_mail_with_liquid(to: agent.email, subject: subject) @agent = agent
send_mail_with_liquid(to: @agent.user.email, subject: subject)
end end
end end
def liquid_droppables def liquid_droppables
super.merge({ super.merge!({
user: @agent, user: @agent.user,
conversation: @conversation, conversation: @conversation,
inbox: @conversation.inbox, inbox: @conversation.inbox
message: @message })
end
def liquid_locals
super.merge!({
custom_message: @custom_message
}) })
end end
end end

View file

@ -20,9 +20,9 @@
class AutomationRule < ApplicationRecord class AutomationRule < ApplicationRecord
belongs_to :account belongs_to :account
validates :account, presence: true
validate :json_conditions_format validate :json_conditions_format
validate :json_actions_format validate :json_actions_format
validates :account_id, presence: true
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }

View file

@ -210,6 +210,8 @@ class Conversation < ApplicationRecord
end end
def dispatcher_dispatch(event_name) def dispatcher_dispatch(event_name)
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?) Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?)
end end

View file

@ -166,6 +166,8 @@ class Message < ApplicationRecord
end end
def dispatch_create_events def dispatch_create_events
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self) Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self)
if outgoing? && conversation.messages.outgoing.count == 1 if outgoing? && conversation.messages.outgoing.count == 1
@ -174,6 +176,8 @@ class Message < ApplicationRecord
end end
def dispatch_update_event def dispatch_update_event
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self) Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self)
end end

View file

@ -1,40 +1,68 @@
class AutomationRules::ActionService class AutomationRules::ActionService
def initialize(rule, conversation) def initialize(rule, account, conversation)
@rule = rule @rule = rule
@account = account
@conversation = conversation @conversation = conversation
@account = @conversation.account Current.executed_by = rule
end end
def perform def perform
@rule.actions.each do |action, _current_index| @rule.actions.each do |action|
action = action.with_indifferent_access action = action.with_indifferent_access
begin
send(action[:action_name], action[:action_params]) send(action[:action_name], action[:action_params])
rescue StandardError => e
Sentry.capture_exception(e)
end end
end end
ensure
Current.reset
end
private private
def send_email_transcript(email)
ConversationReplyMailer.with(account: conversation.account).conversation_transcript(@conversation, email)&.deliver_later
end
def mute_conversation(_params)
@conversation.mute!
end
def change_status(status)
@conversation.update!(status: status[0])
end
def send_webhook_events(webhook_url)
payload = @conversation.webhook_data.merge(event: "automation_event: #{@rule.event_name}")
WebhookJob.perform_later(webhook_url, payload)
end
def send_message(message) def send_message(message)
# params = { content: message, private: false } return if @rule.event_name == 'message_created'
# mb = Messages::MessageBuilder.new(@administrator, @conversation, params)
# mb.perform params = { content: message[0], private: false }
mb = Messages::MessageBuilder.new(@administrator, @conversation, params)
mb.perform
end end
def assign_team(team_ids = []) def assign_team(team_ids = [])
return unless team_belongs_to_account?(team_ids) return unless team_belongs_to_account?(team_ids)
@account.teams.find_by(id: team_ids)
@conversation.update!(team_id: team_ids[0]) @conversation.update!(team_id: team_ids[0])
end end
def assign_best_agents(agent_ids = []) def assign_best_agent(agent_ids = [])
return unless agent_belongs_to_account?(agent_ids) return unless agent_belongs_to_account?(agent_ids)
@agent = @account.users.find_by(id: agent_ids) @agent = @account.users.find_by(id: agent_ids)
@conversation.update_assignee(@agent)
@conversation.update!(assignee_id: @agent.id) if @agent.present?
end end
def add_label(labels = []) def add_label(labels)
return if labels.empty?
@conversation.add_labels(labels) @conversation.add_labels(labels)
end end
@ -43,11 +71,11 @@ class AutomationRules::ActionService
case @rule.event_name case @rule.event_name
when 'conversation_created', 'conversation_status_changed' when 'conversation_created', 'conversation_status_changed'
TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[:message]) TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[:message])&.deliver_now
when 'conversation_updated' when 'conversation_updated'
TeamNotifications::AutomationNotificationMailer.conversation_updated(@conversation, team, params[:message]) TeamNotifications::AutomationNotificationMailer.conversation_updated(@conversation, team, params[:message])&.deliver_now
when 'message_created' when 'message_created'
TeamNotifications::AutomationNotificationMailer.message_created(@conversation, team, params[:message]) TeamNotifications::AutomationNotificationMailer.message_created(@conversation, team, params[:message])&.deliver_now
end end
end end

View file

@ -1,7 +1,7 @@
require 'json' require 'json'
class AutomationRules::ConditionsFilterService < FilterService class AutomationRules::ConditionsFilterService < FilterService
def initialize(rule, conversation) def initialize(rule, conversation = nil)
super([], nil) super([], nil)
@rule = rule @rule = rule
@conversation = conversation @conversation = conversation
@ -21,14 +21,14 @@ class AutomationRules::ConditionsFilterService < FilterService
records.any? records.any?
end end
def message_conditions(message) def message_conditions
message_filters = @filters['messages'] message_filters = @filters['messages']
@rule.conditions.each_with_index do |query_hash, current_index| @rule.conditions.each_with_index do |query_hash, current_index|
current_filter = message_filters[query_hash['attribute_key']] current_filter = message_filters[query_hash['attribute_key']]
@query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index) @query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index)
end end
records = Message.where(id: message.id).where(@query_string, @filter_values.with_indifferent_access) records = Message.where(conversation: @conversation).where(@query_string, @filter_values.with_indifferent_access)
records.any? records.any?
end end
@ -44,6 +44,19 @@ class AutomationRules::ConditionsFilterService < FilterService
end end
end end
# This will be used in future for contact automation rule
def contact_conditions(_contact)
conversation_filters = @filters['conversations']
@rule.conditions.each_with_index do |query_hash, current_index|
current_filter = conversation_filters[query_hash['attribute_key']]
@query_string += conversation_query_string(current_filter, query_hash.with_indifferent_access, current_index)
end
records = base_relation.where(@query_string, @filter_values.with_indifferent_access)
records.any?
end
def conversation_query_string(current_filter, query_hash, current_index) def conversation_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash['attribute_key'] attribute_key = query_hash['attribute_key']
query_operator = query_hash['query_operator'] query_operator = query_hash['query_operator']
@ -63,6 +76,6 @@ class AutomationRules::ConditionsFilterService < FilterService
end end
def base_relation def base_relation
Conversation.where(id: @conversation) Conversation.where(id: @conversation.id)
end end
end end

View file

@ -20,6 +20,8 @@ class Instagram::MessageText < Instagram::WebhooksBaseService
# person can connect the channel and then delete the inbox # person can connect the channel and then delete the inbox
return if @inbox.blank? return if @inbox.blank?
return unsend_message if message_is_deleted?
ensure_contact(contact_id) ensure_contact(contact_id)
create_message create_message
@ -46,6 +48,19 @@ class Instagram::MessageText < Instagram::WebhooksBaseService
@messaging[:message][:is_echo].present? @messaging[:message][:is_echo].present?
end end
def message_is_deleted?
@messaging[:message][:is_deleted].present?
end
def unsend_message
message_to_delete = @inbox.messages.find_by(
source_id: @messaging[:message][:mid]
)
return if message_to_delete.blank?
message_to_delete.update!(content: I18n.t('conversations.messages.deleted'), deleted: true)
end
def create_message def create_message
Messages::Instagram::MessageBuilder.new(@messaging, @inbox, outgoing_echo: agent_message_via_echo?).perform Messages::Instagram::MessageBuilder.new(@messaging, @inbox, outgoing_echo: agent_message_via_echo?).perform
end end

View file

@ -1,7 +1,7 @@
<p>Hi {{user.available_name}}</p> <p>Hi {{user.available_name}}</p>
<p>Time to save the world. A new conversation has been created in {{ inbox.name }}</p> <p>{{ custom_message }}</p>
<p> <p>
Click <a href="{{ action_url }}">here</a> to get cracking. Click <a href="{{ action_url }}">here</a> to get cracking.

View file

@ -0,0 +1,8 @@
<p>Hi {{user.available_name}}</p>
<p>{{ custom_message }}</p>
<p>
Click <a href="{{ action_url }}">here</a> to get cracking.
</p>

View file

@ -0,0 +1,8 @@
<p>Hi {{user.available_name}}</p>
<p>{{ custom_message }}</p>
<p>
Click <a href="{{ action_url }}">here</a> to get cracking.
</p>

View file

@ -56,7 +56,7 @@ ar:
activity: activity:
status: status:
resolved: "تم تحديث حالة المحادثة لـ\"مغلقة\" بواسطة %{user_name}" resolved: "تم تحديث حالة المحادثة لـ\"مغلقة\" بواسطة %{user_name}"
contact_resolved: "Conversation was resolved by %{contact_name}" contact_resolved: "تم حل المحادثة بواسطة %{contact_name}"
open: "تم إعادة فتح المحادثة بواسطة %{user_name}" open: "تم إعادة فتح المحادثة بواسطة %{user_name}"
pending: "تم تحديث حالة المحادثة لـ\"معلقة\" بواسطة %{user_name}" pending: "تم تحديث حالة المحادثة لـ\"معلقة\" بواسطة %{user_name}"
snoozed: "تم تأجيل المحادثة بواسطة %{user_name}" snoozed: "تم تأجيل المحادثة بواسطة %{user_name}"

View file

@ -56,7 +56,7 @@ pt:
activity: activity:
status: status:
resolved: "Conversa foi marcada como resolvida por %{user_name}" resolved: "Conversa foi marcada como resolvida por %{user_name}"
contact_resolved: "Conversation was resolved by %{contact_name}" contact_resolved: "Conversa foi resolvida por %{contact_name}"
open: "Conversa foi reaberta por %{user_name}" open: "Conversa foi reaberta por %{user_name}"
pending: "Conversa marcada como pendente por %{user_name}" pending: "Conversa marcada como pendente por %{user_name}"
snoozed: "Conversa adiada por %{user_name}" snoozed: "Conversa adiada por %{user_name}"

View file

@ -2,12 +2,14 @@ module Current
thread_mattr_accessor :user thread_mattr_accessor :user
thread_mattr_accessor :account thread_mattr_accessor :account
thread_mattr_accessor :account_user thread_mattr_accessor :account_user
thread_mattr_accessor :executed_by
thread_mattr_accessor :contact thread_mattr_accessor :contact
def self.reset def self.reset
Current.user = nil Current.user = nil
Current.account = nil Current.account = nil
Current.account_user = nil Current.account_user = nil
Current.executed_by = nil
Current.contact = nil Current.contact = nil
end end
end end

View file

@ -56,6 +56,33 @@ FactoryBot.define do
initialize_with { attributes } initialize_with { attributes }
end end
factory :instagram_message_unsend_event, class: Hash do
entry do
[
{
'id': 'instagram-message-id-123',
'time': '2021-09-08T06:34:04+0000',
'messaging': [
{
'sender': {
'id': 'Sender-id-1'
},
'recipient': {
'id': 'chatwoot-app-user-id-1'
},
'timestamp': '2021-09-08T06:34:04+0000',
'message': {
'mid': 'message-id-to-delete',
'is_deleted': true
}
}
]
}
]
end
initialize_with { attributes }
end
factory :instagram_message_attachment_event, class: Hash do factory :instagram_message_attachment_event, class: Hash do
entry do entry do
[ [

View file

@ -28,6 +28,7 @@ describe Webhooks::InstagramEventsJob do
let!(:instagram_inbox) { create(:inbox, channel: instagram_channel, account: account, greeting_enabled: false) } let!(:instagram_inbox) { create(:inbox, channel: instagram_channel, account: account, greeting_enabled: false) }
let!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access } let!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access }
let!(:test_params) { build(:instagram_test_text_event).with_indifferent_access } let!(:test_params) { build(:instagram_test_text_event).with_indifferent_access }
let!(:unsend_event) { build(:instagram_message_unsend_event).with_indifferent_access }
let!(:attachment_params) { build(:instagram_message_attachment_event).with_indifferent_access } let!(:attachment_params) { build(:instagram_message_attachment_event).with_indifferent_access }
let!(:story_mention_params) { build(:instagram_story_mention_event).with_indifferent_access } let!(:story_mention_params) { build(:instagram_story_mention_event).with_indifferent_access }
let(:fb_object) { double } let(:fb_object) { double }
@ -61,6 +62,26 @@ describe Webhooks::InstagramEventsJob do
expect(instagram_inbox.messages.last.content).to eq('This is a test message from facebook.') expect(instagram_inbox.messages.last.content).to eq('This is a test message from facebook.')
end end
it 'handle instagram unsend message event' do
create(:message,
source_id: 'message-id-to-delete',
inbox_id: instagram_inbox.id)
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return(
{
name: 'Jane',
id: 'Sender-id-1',
account_id: instagram_inbox.account_id,
profile_pic: 'https://chatwoot-assets.local/sample.png'
}.with_indifferent_access
)
expect(instagram_inbox.messages.count).to be 1
instagram_webhook.perform_now(unsend_event[:entry])
expect(instagram_inbox.messages.last.content).to eq 'This message was deleted'
expect(instagram_inbox.messages.last.reload.deleted).to eq true
end
it 'creates incoming message with attachments in the instagram inbox' do it 'creates incoming message with attachments in the instagram inbox' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object) allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return( allow(fb_object).to receive(:get_object).and_return(

View file

@ -31,16 +31,36 @@ describe AutomationRuleListener do
}, },
{ 'action_name' => 'assign_team', 'action_params' => [team.id] }, { 'action_name' => 'assign_team', 'action_params' => [team.id] },
{ 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] }, { 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] },
{ 'action_name' => 'assign_best_agents', 'action_params' => [user_1.id] } { 'action_name' => 'send_webhook_events', 'action_params' => 'https://www.example.com' },
{ 'action_name' => 'assign_best_agent', 'action_params' => [user_1.id] },
{ 'action_name' => 'send_email_transcript', 'action_params' => 'new_agent@example.com' },
{ 'action_name' => 'mute_conversation', 'action_params' => nil },
{ 'action_name' => 'change_status', 'action_params' => ['snoozed'] },
{ 'action_name' => 'send_message', 'action_params' => ['Send this message.'] }
]) ])
end end
describe '#conversation_status_changed' do describe '#conversation_status_changed' do
context 'when rule matches' do context 'when rule matches' do
it 'triggers automation rule send webhook events' do
payload = conversation.webhook_data.merge(event: "automation_event: #{automation_rule.event_name}")
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
expect(WebhookJob).to receive(:perform_later).with('https://www.example.com', payload).once
listener.conversation_status_changed(event)
end
it 'triggers automation rule to assign team' do it 'triggers automation rule to assign team' do
expect(conversation.team_id).not_to eq(team.id) expect(conversation.team_id).not_to eq(team.id)
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event) listener.conversation_status_changed(event)
conversation.reload conversation.reload
@ -51,6 +71,9 @@ describe AutomationRuleListener do
expect(conversation.labels).to eq([]) expect(conversation.labels).to eq([])
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event) listener.conversation_status_changed(event)
conversation.reload conversation.reload
@ -61,12 +84,65 @@ describe AutomationRuleListener do
expect(conversation.assignee).to be_nil expect(conversation.assignee).to be_nil
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event) listener.conversation_status_changed(event)
conversation.reload conversation.reload
expect(conversation.assignee).to eq(user_1) expect(conversation.assignee).to eq(user_1)
end end
it 'triggers automation rule send message to the contacts' do
expect(conversation.messages).to be_empty
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.messages.last.content).to eq('Send this message.')
end
it 'triggers automation rule changes status to snoozed' do
expect(conversation.status).to eq('resolved')
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.status).to eq('snoozed')
end
it 'triggers automation rule send email transcript to the mentioned email' do
mailer = double
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
allow(mailer).to receive(:conversation_transcript)
end
it 'triggers automation rule send email to the team' do
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
end
end end
end end
@ -114,6 +190,42 @@ describe AutomationRuleListener do
expect(conversation.assignee).to eq(user_1) expect(conversation.assignee).to eq(user_1)
end end
it 'triggers automation rule send email transcript to the mentioned email' do
mailer = double
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
listener.conversation_updated(event)
conversation.reload
allow(mailer).to receive(:conversation_transcript)
end
it 'triggers automation rule send email to the team' do
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
listener.conversation_updated(event)
end
it 'triggers automation rule send message to the contacts' do
expect(conversation.messages).to be_empty
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
listener.conversation_updated(event)
conversation.reload
expect(conversation.messages.last.content).to eq('Send this message.')
end
end end
end end
@ -137,6 +249,9 @@ describe AutomationRuleListener do
expect(conversation.team_id).not_to eq(team.id) expect(conversation.team_id).not_to eq(team.id)
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
listener.message_created(event) listener.message_created(event)
conversation.reload conversation.reload
@ -147,22 +262,41 @@ describe AutomationRuleListener do
expect(conversation.labels).to eq([]) expect(conversation.labels).to eq([])
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
listener.message_created(event) listener.message_created(event)
conversation.reload conversation.reload
expect(conversation.labels.pluck(:name)).to eq(%w[support priority_customer]) expect(conversation.labels.pluck(:name)).to eq(%w[support priority_customer])
end end
it 'triggers automation rule to assign best agents' do it 'triggers automation rule to assign best agent' do
expect(conversation.assignee).to be_nil expect(conversation.assignee).to be_nil
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
listener.message_created(event) listener.message_created(event)
conversation.reload conversation.reload
expect(conversation.assignee).to eq(user_1) expect(conversation.assignee).to eq(user_1)
end end
it 'triggers automation rule send email transcript to the mentioned email' do
mailer = double
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
listener.message_created(event)
conversation.reload
allow(mailer).to receive(:conversation_transcript)
end
end end
end end
end end

View file

@ -2,11 +2,13 @@ require 'rails_helper'
RSpec.describe AutomationRule, type: :model do RSpec.describe AutomationRule, type: :model do
describe 'associations' do describe 'associations' do
let(:account) { create(:account) }
let(:params) do let(:params) do
{ {
name: 'Notify Conversation Created and mark priority query', name: 'Notify Conversation Created and mark priority query',
description: 'Notify all administrator about conversation created and mark priority query', description: 'Notify all administrator about conversation created and mark priority query',
event_name: 'conversation_created', event_name: 'conversation_created',
account_id: account.id,
conditions: [ conditions: [
{ {
attribute_key: 'browser_language', attribute_key: 'browser_language',