Compare commits

..
Author SHA1 Message Date
Pranav 320e7ea246 Update paywall restrictions 2025-03-05 18:43:57 -08:00
111 changed files with 477 additions and 1107 deletions
+1 -1
View File
@@ -561,7 +561,7 @@ GEM
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.8.1) racc (1.8.1)
rack (2.2.12) rack (2.2.11)
rack-attack (6.7.0) rack-attack (6.7.0)
rack (>= 1.0, < 4) rack (>= 1.0, < 4)
rack-contrib (2.5.0) rack-contrib (2.5.0)
@@ -6,8 +6,6 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
before_action :conversation, except: [:index, :meta, :search, :create, :filter] before_action :conversation, except: [:index, :meta, :search, :create, :filter]
before_action :inbox, :contact, :contact_inbox, only: [:create] before_action :inbox, :contact, :contact_inbox, only: [:create]
ATTACHMENT_RESULTS_PER_PAGE = 100
def index def index
result = conversation_finder.perform result = conversation_finder.perform
@conversations = result[:conversations] @conversations = result[:conversations]
@@ -26,12 +24,7 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
end end
def attachments def attachments
@attachments_count = @conversation.attachments.count
@attachments = @conversation.attachments @attachments = @conversation.attachments
.includes(:message)
.order(created_at: :desc)
.page(attachment_params[:page])
.per(ATTACHMENT_RESULTS_PER_PAGE)
end end
def show; end def show; end
@@ -131,10 +124,6 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
params.permit(:priority) params.permit(:priority)
end end
def attachment_params
params.permit(:page)
end
def update_last_seen_on_conversation(last_seen_at, update_assignee) def update_last_seen_on_conversation(last_seen_at, update_assignee)
# rubocop:disable Rails/SkipsModelValidations # rubocop:disable Rails/SkipsModelValidations
@conversation.update_column(:agent_last_seen_at, last_seen_at) @conversation.update_column(:agent_last_seen_at, last_seen_at)
+14 -19
View File
@@ -5,11 +5,10 @@ module SwitchLocale
def switch_locale(&) def switch_locale(&)
# priority is for locale set in query string (mostly for widget/from js sdk) # priority is for locale set in query string (mostly for widget/from js sdk)
locale ||= params[:locale] locale ||= locale_from_params
locale ||= locale_from_custom_domain locale ||= locale_from_custom_domain
# if locale is not set in account, let's use DEFAULT_LOCALE env variable # if locale is not set in account, let's use DEFAULT_LOCALE env variable
locale ||= ENV.fetch('DEFAULT_LOCALE', nil) locale ||= locale_from_env_variable
set_locale(locale, &) set_locale(locale, &)
end end
@@ -33,30 +32,26 @@ module SwitchLocale
end end
def set_locale(locale, &) def set_locale(locale, &)
safe_locale = validate_and_get_locale(locale) # if locale is empty, use default_locale
locale ||= I18n.default_locale
# Ensure locale won't bleed into other requests # Ensure locale won't bleed into other requests
# https://guides.rubyonrails.org/i18n.html#managing-the-locale-across-requests # https://guides.rubyonrails.org/i18n.html#managing-the-locale-across-requests
I18n.with_locale(safe_locale, &) I18n.with_locale(locale, &)
end end
def validate_and_get_locale(locale) def locale_from_params
return I18n.default_locale.to_s if locale.blank? I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil
available_locales = I18n.available_locales.map(&:to_s)
locale_without_variant = locale.split('_')[0]
if available_locales.include?(locale)
locale
elsif available_locales.include?(locale_without_variant)
locale_without_variant
else
I18n.default_locale.to_s
end
end end
def locale_from_account(account) def locale_from_account(account)
return unless account return unless account
account.locale I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil
end
def locale_from_env_variable
return unless ENV.fetch('DEFAULT_LOCALE', nil)
I18n.available_locales.map(&:to_s).include?(ENV.fetch('DEFAULT_LOCALE')) ? ENV.fetch('DEFAULT_LOCALE') : nil
end end
end end
@@ -1,6 +1,4 @@
class Public::Api::V1::Portals::BaseController < PublicController class Public::Api::V1::Portals::BaseController < PublicController
include SwitchLocale
before_action :show_plain_layout before_action :show_plain_layout
before_action :set_color_scheme before_action :set_color_scheme
before_action :set_global_config before_action :set_global_config
@@ -29,7 +27,14 @@ class Public::Api::V1::Portals::BaseController < PublicController
end end
def switch_locale_with_portal(&) def switch_locale_with_portal(&)
@locale = validate_and_get_locale(params[:locale]) locale_without_variant = params[:locale].split('_')[0]
is_locale_available = I18n.available_locales.map(&:to_s).include?(params[:locale])
is_locale_variant_available = I18n.available_locales.map(&:to_s).include?(locale_without_variant)
if is_locale_available
@locale = params[:locale]
elsif is_locale_variant_available
@locale = locale_without_variant
end
I18n.with_locale(@locale, &) I18n.with_locale(@locale, &)
end end
@@ -39,12 +44,12 @@ class Public::Api::V1::Portals::BaseController < PublicController
Rails.logger.info "Article: not found for slug: #{params[:article_slug]}" Rails.logger.info "Article: not found for slug: #{params[:article_slug]}"
render_404 && return if article.blank? render_404 && return if article.blank?
article_locale = if article.category.present? @locale = if article.category.present?
article.category.locale article.category.locale
else else
article.portal.default_locale article.portal.default_locale
end end
@locale = validate_and_get_locale(article_locale)
I18n.with_locale(@locale, &) I18n.with_locale(@locale, &)
end end
-3
View File
@@ -4,7 +4,6 @@ import AddAccountModal from '../dashboard/components/layout/sidebarComponents/Ad
import LoadingState from './components/widgets/LoadingState.vue'; import LoadingState from './components/widgets/LoadingState.vue';
import NetworkNotification from './components/NetworkNotification.vue'; import NetworkNotification from './components/NetworkNotification.vue';
import UpdateBanner from './components/app/UpdateBanner.vue'; import UpdateBanner from './components/app/UpdateBanner.vue';
import UpgradeBanner from './components/app/UpgradeBanner.vue';
import PaymentPendingBanner from './components/app/PaymentPendingBanner.vue'; import PaymentPendingBanner from './components/app/PaymentPendingBanner.vue';
import PendingEmailVerificationBanner from './components/app/PendingEmailVerificationBanner.vue'; import PendingEmailVerificationBanner from './components/app/PendingEmailVerificationBanner.vue';
import vueActionCable from './helper/actionCable'; import vueActionCable from './helper/actionCable';
@@ -31,7 +30,6 @@ export default {
UpdateBanner, UpdateBanner,
PaymentPendingBanner, PaymentPendingBanner,
WootSnackbarBox, WootSnackbarBox,
UpgradeBanner,
PendingEmailVerificationBanner, PendingEmailVerificationBanner,
}, },
setup() { setup() {
@@ -146,7 +144,6 @@ export default {
<template v-if="currentAccountId"> <template v-if="currentAccountId">
<PendingEmailVerificationBanner v-if="hideOnOnboardingView" /> <PendingEmailVerificationBanner v-if="hideOnOnboardingView" />
<PaymentPendingBanner v-if="hideOnOnboardingView" /> <PaymentPendingBanner v-if="hideOnOnboardingView" />
<UpgradeBanner />
</template> </template>
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
@@ -26,7 +26,7 @@ const { t } = useI18n();
/> />
</div> </div>
<div <div
class="absolute bg-n-alpha-3 px-4 py-3 border rounded-xl border-n-strong text-n-slate-12 bottom-6 w-52 text-xs backdrop-blur-[100px] shadow-[0px_0px_24px_0px_rgba(0,0,0,0.12)] opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all break-all" class="absolute bg-n-alpha-3 px-4 py-3 border rounded-xl border-n-strong text-n-slate-12 bottom-6 w-52 text-xs backdrop-blur-[100px] shadow-[0px_0px_24px_0px_rgba(0,0,0,0.12)] opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all"
:class="{ :class="{
'ltr:left-0 rtl:right-0': orientation === ORIENTATION.LEFT, 'ltr:left-0 rtl:right-0': orientation === ORIENTATION.LEFT,
'ltr:right-0 rtl:left-0': orientation === ORIENTATION.RIGHT, 'ltr:right-0 rtl:left-0': orientation === ORIENTATION.RIGHT,
@@ -102,7 +102,6 @@ const statusToShow = computed(() => {
if (isRead.value) return MESSAGE_STATUS.READ; if (isRead.value) return MESSAGE_STATUS.READ;
if (isDelivered.value) return MESSAGE_STATUS.DELIVERED; if (isDelivered.value) return MESSAGE_STATUS.DELIVERED;
if (isSent.value) return MESSAGE_STATUS.SENT; if (isSent.value) return MESSAGE_STATUS.SENT;
if (status.value === MESSAGE_STATUS.FAILED) return MESSAGE_STATUS.FAILED;
return MESSAGE_STATUS.PROGRESS; return MESSAGE_STATUS.PROGRESS;
}); });
@@ -0,0 +1,79 @@
<script setup>
import { computed, onMounted } from 'vue';
import { useStore } from 'vuex';
import { useAccount } from 'dashboard/composables/useAccount';
import { differenceInDays } from 'date-fns';
import { useRoute } from 'vue-router';
const ALWAYS_ON_ROUTES = [
'agent_list',
'settings_inbox_list',
'billing_settings_index',
];
const { accountId } = useAccount();
const store = useStore();
const route = useRoute();
const routeName = computed(() => {
return route.name || '';
});
const isOnChatwootCloud = computed(
() => store.getters['globalConfig/isOnChatwootCloud']
);
const account = computed(() =>
store.getters['accounts/getAccount'](accountId.value)
);
const isTrialAccount = computed(() => {
if (!account.value) return false;
const createdAt = new Date(account.value.created_at);
const diffDays = differenceInDays(new Date(), createdAt);
return diffDays <= 15;
});
const testLimit = ({ allowed, consumed }) => {
return consumed > allowed;
};
const isLimitExceeded = computed(() => {
if (ALWAYS_ON_ROUTES.includes(routeName.value)) {
return false;
}
if (!account.value) return false;
const { limits } = account.value;
if (!limits) return false;
const { conversation, non_web_inboxes: nonWebInboxes } = limits;
return testLimit(conversation) || testLimit(nonWebInboxes);
});
const shouldShowBanner = computed(() => {
if (!isOnChatwootCloud.value) {
return false;
}
if (isTrialAccount.value) {
return false;
}
return isLimitExceeded.value;
});
const fetchLimits = () => store.dispatch('accounts/limits');
onMounted(() => {
if (isOnChatwootCloud.value) {
fetchLimits();
}
});
</script>
<template>
<div v-if="shouldShowBanner">Limits exceeded</div>
<slot v-else />
</template>
+4 -27
View File
@@ -9,7 +9,6 @@ class ActionCableConnector extends BaseActionCableConnector {
const { websocketURL = '' } = window.chatwootConfig || {}; const { websocketURL = '' } = window.chatwootConfig || {};
super(app, pubsubToken, websocketURL); super(app, pubsubToken, websocketURL);
this.CancelTyping = []; this.CancelTyping = [];
this.conversationEventTimestamps = new Map();
this.events = { this.events = {
'message.created': this.onMessageCreated, 'message.created': this.onMessageCreated,
'message.updated': this.onMessageUpdated, 'message.updated': this.onMessageUpdated,
@@ -34,23 +33,6 @@ class ActionCableConnector extends BaseActionCableConnector {
}; };
} }
/**
* Checks if a conversation event is out of sequence by comparing timestamps
* @param {number} conversationId - The ID of the conversation to check
* @param {number} eventTimestamp - The timestamp of the current event
* @returns {boolean} Returns true if event is out of sequence, false otherwise
*/
eventOutOfSequence(conversationId, eventTimestamp) {
if (!eventTimestamp) return false;
const lastTimestamp = this.conversationEventTimestamps.get(conversationId);
if (!lastTimestamp || eventTimestamp > lastTimestamp) {
this.conversationEventTimestamps.set(conversationId, eventTimestamp);
return false;
}
return true;
}
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
onReconnect = () => { onReconnect = () => {
emitter.emit(BUS_EVENTS.WEBSOCKET_RECONNECT); emitter.emit(BUS_EVENTS.WEBSOCKET_RECONNECT);
@@ -86,10 +68,8 @@ class ActionCableConnector extends BaseActionCableConnector {
} }
}; };
onAssigneeChanged = (payload, eventTimestamp) => { onAssigneeChanged = payload => {
const { id } = payload; const { id } = payload;
if (this.eventOutOfSequence(id, eventTimestamp)) return;
if (id) { if (id) {
this.app.$store.dispatch('updateConversation', payload); this.app.$store.dispatch('updateConversation', payload);
} }
@@ -101,8 +81,7 @@ class ActionCableConnector extends BaseActionCableConnector {
this.fetchConversationStats(); this.fetchConversationStats();
}; };
onConversationRead = (data, eventTimestamp) => { onConversationRead = data => {
if (this.eventOutOfSequence(data.id, eventTimestamp)) return;
this.app.$store.dispatch('updateConversation', data); this.app.$store.dispatch('updateConversation', data);
}; };
@@ -125,14 +104,12 @@ class ActionCableConnector extends BaseActionCableConnector {
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
onReload = () => window.location.reload(); onReload = () => window.location.reload();
onStatusChange = (data, eventTimestamp) => { onStatusChange = data => {
if (this.eventOutOfSequence(data.id, eventTimestamp)) return;
this.app.$store.dispatch('updateConversation', data); this.app.$store.dispatch('updateConversation', data);
this.fetchConversationStats(); this.fetchConversationStats();
}; };
onConversationUpdated = (data, eventTimestamp) => { onConversationUpdated = data => {
if (this.eventOutOfSequence(data.id, eventTimestamp)) return;
this.app.$store.dispatch('updateConversation', data); this.app.$store.dispatch('updateConversation', data);
this.fetchConversationStats(); this.fetchConversationStats();
}; };
@@ -560,7 +560,7 @@
"ERROR_MESSAGE": "Wir konnten die Suche nicht abschließen. Bitte versuch es erneut." "ERROR_MESSAGE": "Wir konnten die Suche nicht abschließen. Bitte versuch es erneut."
}, },
"FORM": { "FORM": {
"GO_TO_CONVERSATION": "Anzeigen", "GO_TO_CONVERSATION": "Aussicht",
"SUCCESS_MESSAGE": "Die Nachricht wurde erfolgreich versendet!", "SUCCESS_MESSAGE": "Die Nachricht wurde erfolgreich versendet!",
"ERROR_MESSAGE": "Beim Erstellen der Unterhaltung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.", "ERROR_MESSAGE": "Beim Erstellen der Unterhaltung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.",
"NO_INBOX_ALERT": "Es sind keine Posteingänge vorhanden, um eine Unterhaltung mit diesem Kontakt zu starten.", "NO_INBOX_ALERT": "Es sind keine Posteingänge vorhanden, um eine Unterhaltung mit diesem Kontakt zu starten.",
@@ -751,7 +751,7 @@
"WHATSAPP": "WhatsApp", "WHATSAPP": "WhatsApp",
"SMS": "SMS", "SMS": "SMS",
"EMAIL": "E-Mail", "EMAIL": "E-Mail",
"TELEGRAM": "Telegramm", "TELEGRAM": "Telegram",
"LINE": "Line", "LINE": "Line",
"API": "API-Kanal" "API": "API-Kanal"
} }
@@ -12,7 +12,7 @@
}, },
"WEBHOOK": { "WEBHOOK": {
"SUBSCRIBED_EVENTS": "Abonnierte Events", "SUBSCRIBED_EVENTS": "Abonnierte Events",
"LEARN_MORE": "Mehr über Webhooks erfahren", "LEARN_MORE": "Learn more about webhooks",
"FORM": { "FORM": {
"CANCEL": "Stornieren", "CANCEL": "Stornieren",
"DESC": "Webhook-Ereignisse bieten Ihnen Echtzeitinformationen darüber, was in Ihrem Chatwoot-Konto passiert. Bitte geben Sie eine gültige URL ein, um einen Rückruf zu konfigurieren.", "DESC": "Webhook-Ereignisse bieten Ihnen Echtzeitinformationen darüber, was in Ihrem Chatwoot-Konto passiert. Bitte geben Sie eine gültige URL ein, um einen Rückruf zu konfigurieren.",
@@ -31,7 +31,7 @@
}, },
"END_POINT": { "END_POINT": {
"LABEL": "Webhook-URL", "LABEL": "Webhook-URL",
"PLACEHOLDER": "Beispiel: {webhookExampleURL}", "PLACEHOLDER": "Example: {webhookExampleURL}",
"ERROR": "Bitte geben Sie eine gültige URL ein" "ERROR": "Bitte geben Sie eine gültige URL ein"
}, },
"EDIT_SUBMIT": "Webhook aktualisieren", "EDIT_SUBMIT": "Webhook aktualisieren",
@@ -114,7 +114,7 @@
}, },
"OPEN_AI": { "OPEN_AI": {
"AI_ASSIST": "AI-Assistent", "AI_ASSIST": "AI-Assistent",
"WITH_AI": " {option} mit KI ", "WITH_AI": " {option} with AI ",
"OPTIONS": { "OPTIONS": {
"REPLY_SUGGESTION": "Antwortvorschlag", "REPLY_SUGGESTION": "Antwortvorschlag",
"SUMMARIZE": "Zusammenfassen", "SUMMARIZE": "Zusammenfassen",
@@ -235,7 +235,7 @@
"ERROR": "Beim Abrufen der linearen Probleme ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut", "ERROR": "Beim Abrufen der linearen Probleme ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut",
"LINK_SUCCESS": "Problem erfolgreich verknüpft", "LINK_SUCCESS": "Problem erfolgreich verknüpft",
"LINK_ERROR": "Beim Verknüpfen des Problems ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut", "LINK_ERROR": "Beim Verknüpfen des Problems ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut",
"LINK_TITLE": "Unterhaltung (#{conversationId}) mit {name}" "LINK_TITLE": "Conversation (#{conversationId}) with {name}"
}, },
"ADD_OR_LINK": { "ADD_OR_LINK": {
"TITLE": "Lineares Problem erstellen/verknüpfen", "TITLE": "Lineares Problem erstellen/verknüpfen",
@@ -294,7 +294,7 @@
"PRIORITY": "Priorität", "PRIORITY": "Priorität",
"ASSIGNEE": "Zugewiesener", "ASSIGNEE": "Zugewiesener",
"LABELS": "Labels", "LABELS": "Labels",
"CREATED_AT": "Erstellt am {createdAt}" "CREATED_AT": "Created at {createdAt}"
}, },
"UNLINK": { "UNLINK": {
"TITLE": "Verknüpfung aufheben", "TITLE": "Verknüpfung aufheben",
@@ -302,8 +302,8 @@
"ERROR": "Beim Aufheben der Verknüpfung des Problems ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut" "ERROR": "Beim Aufheben der Verknüpfung des Problems ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut"
}, },
"DELETE": { "DELETE": {
"TITLE": "Sind Sie sicher, dass Sie die Integration löschen möchten?", "TITLE": "Are you sure you want to delete the integration?",
"MESSAGE": "Sind Sie sicher, dass Sie die Integration löschen möchten?", "MESSAGE": "Are you sure you want to delete the integration?",
"CONFIRM": "Ja, löschen", "CONFIRM": "Ja, löschen",
"CANCEL": "Stornieren" "CANCEL": "Stornieren"
} }
@@ -313,27 +313,27 @@
"NAME": "Kapitän", "NAME": "Kapitän",
"COPILOT": { "COPILOT": {
"SEND_MESSAGE": "Nachricht senden...", "SEND_MESSAGE": "Nachricht senden...",
"LOADER": "Captain denkt nach", "LOADER": "Captain is thinking",
"YOU": "Sie", "YOU": "Sie",
"USE": "Verwenden", "USE": "Use this",
"RESET": "Zurücksetzen", "RESET": "Reset",
"SELECT_ASSISTANT": "Assistent auswählen" "SELECT_ASSISTANT": "Select Assistant"
}, },
"PAYWALL": { "PAYWALL": {
"TITLE": "Upgrade auf Captain AI", "TITLE": "Upgrade to use Captain AI",
"AVAILABLE_ON": "Captain is not available on the free plan.", "AVAILABLE_ON": "Captain is not available on the free plan.",
"UPGRADE_PROMPT": "Tarif upgraden, um Zugang zu unseren Assistenten, Copilot und mehr zu erhalten.", "UPGRADE_PROMPT": "Upgrade your plan to get access to our assistants, copilot and more.",
"UPGRADE_NOW": "Jetzt upgraden", "UPGRADE_NOW": "Upgrade now",
"CANCEL_ANYTIME": "Sie können Ihr Paket jederzeit ändern oder kündigen" "CANCEL_ANYTIME": "You can change or cancel your plan anytime"
}, },
"ENTERPRISE_PAYWALL": { "ENTERPRISE_PAYWALL": {
"AVAILABLE_ON": "Captain AI Funktion ist nur mit einem kostenpflichtigen Tarif verfügbar.", "AVAILABLE_ON": "Captain AI feature is only available in a paid plan.",
"UPGRADE_PROMPT": "Tarif upgraden, um Zugang zu unseren Assistenten, Copilot und mehr zu erhalten.", "UPGRADE_PROMPT": "Upgrade your plan to get access to our assistants, copilot and more.",
"ASK_ADMIN": "Bitte kontaktieren Sie Ihren Administrator für das Upgrade." "ASK_ADMIN": "Please reach out to your administrator for the upgrade."
}, },
"BANNER": { "BANNER": {
"RESPONSES": "You've used over 80% of your response limit. To continue using Captain AI, please upgrade.", "RESPONSES": "You've used over 80% of your response limit. To continue using Captain AI, please upgrade.",
"DOCUMENTS": "Dokumentenlimit erreicht. Upgraden um Cpatain AI weiter zu verwenden." "DOCUMENTS": "Document limit reached. Upgrade to continue using Captain AI."
}, },
"FORM": { "FORM": {
"CANCEL": "Stornieren", "CANCEL": "Stornieren",
@@ -100,7 +100,7 @@
"NO_RESULTS": "Nenhum resultado encontrado." "NO_RESULTS": "Nenhum resultado encontrado."
}, },
"MULTI_SELECTOR": { "MULTI_SELECTOR": {
"PLACEHOLDER": "Nenhum", "PLACEHOLDER": "Nenhuma",
"TITLE": { "TITLE": {
"AGENT": "Selecionar agente", "AGENT": "Selecionar agente",
"TEAM": "Selecionar time" "TEAM": "Selecionar time"
@@ -1,16 +1,16 @@
{ {
"AUDIT_LOGS": { "AUDIT_LOGS": {
"HEADER": "Auditoria", "HEADER": "Registros de Auditoria",
"HEADER_BTN_TXT": "Adicionar Logs de Auditoria", "HEADER_BTN_TXT": "Adicionar Registros de Auditoria",
"LOADING": "Buscando Logs de Auditoria", "LOADING": "Buscando Logs de Auditoria",
"DESCRIPTION": "Logs de Auditoria mantêm um registro de atividades em sua conta, permitindo que você acompanhe e auditoria de sua conta, equipe ou serviços.", "DESCRIPTION": "Logs de Auditoria mantêm um registro de atividades em sua conta, permitindo que você acompanhe e auditoria de sua conta, equipe ou serviços.",
"LEARN_MORE": "Saiba mais sobre os logs de auditoria", "LEARN_MORE": "Saiba mais sobre os logs de auditoria",
"SEARCH_404": "Não existem itens correspondentes a esta consulta", "SEARCH_404": "Não existem itens correspondentes a esta consulta",
"SIDEBAR_TXT": "<p><b>Logs de Auditoria</b> </p><p> Os Logs de Auditoria são rastros para eventos e ações em um Sistema Chatwoot. </p>", "SIDEBAR_TXT": "<p><b>Registros de Auditoria</b> </p><p> Registros de Auditoria são trilhas para eventos e ações em um Sistema Chatwoot. </p>",
"LIST": { "LIST": {
"404": "Não há Logs de Auditoria disponíveis nesta conta.", "404": "Não há Registros de Auditoria disponíveis nesta conta.",
"TITLE": "Gerenciar Logs de Auditoria", "TITLE": "Gerenciar Registros de Auditoria",
"DESC": "Logs de auditoria são rastros para eventos e ações em um Sistema de Chatwoot.", "DESC": "Registros de Auditoria são trilhas para eventos e ações em um Sistema Chatwoot.",
"TABLE_HEADER": { "TABLE_HEADER": {
"ACTIVITY": "Usuário", "ACTIVITY": "Usuário",
"TIME": "Ação", "TIME": "Ação",
@@ -27,12 +27,12 @@
"ERROR": "Falha ao atualizar etiquetas" "ERROR": "Falha ao atualizar etiquetas"
}, },
"CONVERSATION": { "CONVERSATION": {
"TITLE": "Etiquetas da conversa", "TITLE": "Marcador da conversa",
"ADD_BUTTON": "Adicionar etiquetas" "ADD_BUTTON": "Adicionar marcador"
}, },
"LABEL_SELECT": { "LABEL_SELECT": {
"TITLE": "Adicionar etiquetas", "TITLE": "Adicionar marcador",
"PLACEHOLDER": "Pesquisar etiquetas", "PLACEHOLDER": "Pesquisar marcador ",
"NO_RESULT": "Nenhuma etiqueta encontrada", "NO_RESULT": "Nenhuma etiqueta encontrada",
"CREATE_LABEL": "Criar etiqueta" "CREATE_LABEL": "Criar etiqueta"
} }
@@ -65,7 +65,7 @@
"HEADER": { "HEADER": {
"RESOLVE_ACTION": "Resolver", "RESOLVE_ACTION": "Resolver",
"REOPEN_ACTION": "Reabrir", "REOPEN_ACTION": "Reabrir",
"OPEN_ACTION": "Abrir", "OPEN_ACTION": "Abertas",
"OPEN": "Mais", "OPEN": "Mais",
"CLOSE": "Fechar", "CLOSE": "Fechar",
"DETAILS": "detalhes", "DETAILS": "detalhes",
@@ -148,7 +148,7 @@
"MESSAGE_SIGN_TOOLTIP": "Assinatura de mensagem", "MESSAGE_SIGN_TOOLTIP": "Assinatura de mensagem",
"ENABLE_SIGN_TOOLTIP": "Ativar assinatura", "ENABLE_SIGN_TOOLTIP": "Ativar assinatura",
"DISABLE_SIGN_TOOLTIP": "Desativar assinatura", "DISABLE_SIGN_TOOLTIP": "Desativar assinatura",
"MSG_INPUT": "Shift + enter para nova linha. Digite '/' para selecionar uma Resposta Pronta.", "MSG_INPUT": "Shift + enter para nova linha. Digite '/' para atalhos.",
"PRIVATE_MSG_INPUT": "A mensagem será visível apenas para agentes", "PRIVATE_MSG_INPUT": "A mensagem será visível apenas para agentes",
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "A assinatura da mensagem não está configurada. Por favor, configure-a nas configurações do perfil.", "MESSAGE_SIGNATURE_NOT_CONFIGURED": "A assinatura da mensagem não está configurada. Por favor, configure-a nas configurações do perfil.",
"CLICK_HERE": "Clique aqui para atualizar", "CLICK_HERE": "Clique aqui para atualizar",
@@ -15,7 +15,7 @@
}, },
"ENTERPRISE_PAYWALL": { "ENTERPRISE_PAYWALL": {
"AVAILABLE_ON": "O recurso de função personalizada está disponível apenas nos planos pagos.", "AVAILABLE_ON": "O recurso de função personalizada está disponível apenas nos planos pagos.",
"UPGRADE_PROMPT": "Atualize para um plano pago para acessar recursos avançados como logs de auditoria, capacidade do agente e muito mais.", "UPGRADE_PROMPT": "Atualize para um plano pago para acessar recursos avançados como registros de auditoria, capacidade do agente e muito mais.",
"ASK_ADMIN": "Entre em contato com seu administrador para fazer a atualização." "ASK_ADMIN": "Entre em contato com seu administrador para fazer a atualização."
}, },
"LIST": { "LIST": {
@@ -1,6 +1,6 @@
{ {
"GENERAL_SETTINGS": { "GENERAL_SETTINGS": {
"TITLE": "Conta", "TITLE": "Configurações da conta",
"SUBMIT": "Atualizar configurações", "SUBMIT": "Atualizar configurações",
"BACK": "Anterior", "BACK": "Anterior",
"DISMISS": "Recusar", "DISMISS": "Recusar",
@@ -131,10 +131,10 @@
"GO_TO_INBOX_REPORTS": "Ir para Relatórios da Caixa de Entrada", "GO_TO_INBOX_REPORTS": "Ir para Relatórios da Caixa de Entrada",
"GO_TO_TEAM_REPORTS": "Ir para Relatórios da Equipe", "GO_TO_TEAM_REPORTS": "Ir para Relatórios da Equipe",
"GO_TO_SETTINGS_AGENTS": "Ir para Configurações de Agente", "GO_TO_SETTINGS_AGENTS": "Ir para Configurações de Agente",
"GO_TO_SETTINGS_TEAMS": "Ir para as Configurações de Equipe", "GO_TO_SETTINGS_TEAMS": "Ir para as configurações de equipe",
"GO_TO_SETTINGS_INBOXES": "Ir para as Configurações da Caixa de Entrada", "GO_TO_SETTINGS_INBOXES": "Ir para as configurações da Caixa de Entrada",
"GO_TO_SETTINGS_LABELS": "Ir para as Configurações de Etiqueta", "GO_TO_SETTINGS_LABELS": "Ir para as Configurações de Etiqueta",
"GO_TO_SETTINGS_CANNED_RESPONSES": "Ir para as Configurações de Respostas Prontas", "GO_TO_SETTINGS_CANNED_RESPONSES": "Ir para as configurações de respostas prontas",
"GO_TO_SETTINGS_APPLICATIONS": "Vá para Configurações do Aplicativo", "GO_TO_SETTINGS_APPLICATIONS": "Vá para Configurações do Aplicativo",
"GO_TO_SETTINGS_ACCOUNT": "Ir para as Configurações da Conta", "GO_TO_SETTINGS_ACCOUNT": "Ir para as Configurações da Conta",
"GO_TO_SETTINGS_PROFILE": "Ir para as Configurações do Perfil", "GO_TO_SETTINGS_PROFILE": "Ir para as Configurações do Perfil",
@@ -500,7 +500,7 @@
"ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "As conversas continuarão sobre o e-mail se o endereço de e-mail de contato estiver disponível.", "ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "As conversas continuarão sobre o e-mail se o endereço de e-mail de contato estiver disponível.",
"LOCK_TO_SINGLE_CONVERSATION": "Bloquear para conversa única", "LOCK_TO_SINGLE_CONVERSATION": "Bloquear para conversa única",
"LOCK_TO_SINGLE_CONVERSATION_SUB_TEXT": "Ativar ou desativar várias conversas para o mesmo contato nesta caixa de entrada", "LOCK_TO_SINGLE_CONVERSATION_SUB_TEXT": "Ativar ou desativar várias conversas para o mesmo contato nesta caixa de entrada",
"INBOX_UPDATE_TITLE": "Configurações da Caixa de Entrada", "INBOX_UPDATE_TITLE": "Configurações da Caixa de entrada",
"INBOX_UPDATE_SUB_TEXT": "Atualize suas configurações de caixa de entrada", "INBOX_UPDATE_SUB_TEXT": "Atualize suas configurações de caixa de entrada",
"AUTO_ASSIGNMENT_SUB_TEXT": "Ativar ou desativar a atribuição automática de novas conversas aos agentes adicionados a essa caixa de entrada.", "AUTO_ASSIGNMENT_SUB_TEXT": "Ativar ou desativar a atribuição automática de novas conversas aos agentes adicionados a essa caixa de entrada.",
"HMAC_VERIFICATION": "Validação de Identidade do Usuário", "HMAC_VERIFICATION": "Validação de Identidade do Usuário",
@@ -695,7 +695,7 @@
"PLACE_HOLDER": "Fale conosco no chat" "PLACE_HOLDER": "Fale conosco no chat"
}, },
"UPDATE": { "UPDATE": {
"BUTTON_TEXT": "Atualizar Configurações do Widget", "BUTTON_TEXT": "Atualizar configurações do widget",
"API": { "API": {
"SUCCESS_MESSAGE": "Configurações do widget atualizadas com sucesso", "SUCCESS_MESSAGE": "Configurações do widget atualizadas com sucesso",
"ERROR_MESSAGE": "Não é possível atualizar as configurações do widget" "ERROR_MESSAGE": "Não é possível atualizar as configurações do widget"
@@ -302,8 +302,8 @@
"ERROR": "Houve um erro ao desvincular o atributo, por favor, tente novamente" "ERROR": "Houve um erro ao desvincular o atributo, por favor, tente novamente"
}, },
"DELETE": { "DELETE": {
"TITLE": "Tem certeza que deseja excluir esta integração?", "TITLE": "Are you sure you want to delete the integration?",
"MESSAGE": "Tem certeza que deseja excluir esta integração?", "MESSAGE": "Are you sure you want to delete the integration?",
"CONFIRM": "Sim, excluir", "CONFIRM": "Sim, excluir",
"CANCEL": "Cancelar" "CANCEL": "Cancelar"
} }
@@ -317,7 +317,7 @@
"YOU": "Você", "YOU": "Você",
"USE": "Use isto", "USE": "Use isto",
"RESET": "Reiniciar", "RESET": "Reiniciar",
"SELECT_ASSISTANT": "Selecione o Assistente" "SELECT_ASSISTANT": "Select Assistant"
}, },
"PAYWALL": { "PAYWALL": {
"TITLE": "Atualize para usar o Capitão IA", "TITLE": "Atualize para usar o Capitão IA",
@@ -440,19 +440,19 @@
"DOCUMENTABLE": { "DOCUMENTABLE": {
"CONVERSATION": "Conversação #{id}" "CONVERSATION": "Conversação #{id}"
}, },
"SELECTED": "{count} selecionado", "SELECTED": "{count} selected",
"BULK_APPROVE_BUTTON": "Aprovar", "BULK_APPROVE_BUTTON": "Approve",
"BULK_DELETE_BUTTON": "Excluir", "BULK_DELETE_BUTTON": "Excluir",
"BULK_APPROVE": { "BULK_APPROVE": {
"SUCCESS_MESSAGE": "Perguntas Frequentes aprovadas com sucesso", "SUCCESS_MESSAGE": "FAQs approved successfully",
"ERROR_MESSAGE": "Ocorreu um erro ao aprovar as Perguntas Frequentes. Tente novamente." "ERROR_MESSAGE": "There was an error approving the FAQs, please try again."
}, },
"BULK_DELETE": { "BULK_DELETE": {
"TITLE": "Excluir as Perguntas Frequentes?", "TITLE": "Delete FAQs?",
"DESCRIPTION": "Tem certeza que deseja excluir as Perguntas Frequentes selecionadas? Esta ação não pode ser desfeita.", "DESCRIPTION": "Are you sure you want to delete the selected FAQs? This action cannot be undone.",
"CONFIRM": "Sim, excluir todas", "CONFIRM": "Yes, delete all",
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso/", "SUCCESS_MESSAGE": "FAQs deleted successfully",
"ERROR_MESSAGE": "Ocorreu um erro ao excluir as Perguntas Frequentes, por favor tente novamente." "ERROR_MESSAGE": "There was an error deleting the FAQs, please try again."
}, },
"DELETE": { "DELETE": {
"TITLE": "Tem certeza que deseja excluir o FAQ?", "TITLE": "Tem certeza que deseja excluir o FAQ?",
@@ -1,7 +1,7 @@
{ {
"LABEL_MGMT": { "LABEL_MGMT": {
"HEADER": "Etiquetas", "HEADER": "Etiquetas",
"HEADER_BTN_TXT": "Adicionar etiqueta", "HEADER_BTN_TXT": "Adicionar marcador",
"LOADING": "Buscando etiquetas", "LOADING": "Buscando etiquetas",
"DESCRIPTION": "As etiquetas ajudam você a categorizar e priorizar conversas e leads. Você pode atribuir uma etiqueta a uma conversa ou contato usando o painel lateral.", "DESCRIPTION": "As etiquetas ajudam você a categorizar e priorizar conversas e leads. Você pode atribuir uma etiqueta a uma conversa ou contato usando o painel lateral.",
"LEARN_MORE": "Aprenda mais sobre etiquetas", "LEARN_MORE": "Aprenda mais sobre etiquetas",
@@ -18,21 +18,21 @@
}, },
"FORM": { "FORM": {
"NAME": { "NAME": {
"LABEL": "Nome da Etiqueta", "LABEL": "Nome do marcador",
"PLACEHOLDER": "Nome da etiqueta", "PLACEHOLDER": "Nome do marcador",
"REQUIRED_ERROR": "O nome da etiqueta é obrigatório", "REQUIRED_ERROR": "O nome do marcador é obrigatório",
"MINIMUM_LENGTH_ERROR": "Tamanho mínimo 2 é necessário", "MINIMUM_LENGTH_ERROR": "Tamanho mínimo 2 é necessário",
"VALID_ERROR": "Somente Letras, Números, Hífen e Sublinhado são permitidos" "VALID_ERROR": "Somente Letras, Números, Hífen e Sublinhado são permitidos"
}, },
"DESCRIPTION": { "DESCRIPTION": {
"LABEL": "Descrição", "LABEL": "Descrição",
"PLACEHOLDER": "Descrição da etiqueta" "PLACEHOLDER": "Descrição do marcador"
}, },
"COLOR": { "COLOR": {
"LABEL": "Cor" "LABEL": "Cor"
}, },
"SHOW_ON_SIDEBAR": { "SHOW_ON_SIDEBAR": {
"LABEL": "Exibir etiqueta na barra lateral" "LABEL": "Exibir marcador na barra lateral"
}, },
"EDIT": "Alterar", "EDIT": "Alterar",
"CREATE": "Criar", "CREATE": "Criar",
@@ -54,10 +54,10 @@
"SUGGESTED_LABELS": "Etiquetas sugeridos" "SUGGESTED_LABELS": "Etiquetas sugeridos"
}, },
"ADD": { "ADD": {
"TITLE": "Adicionar etiqueta", "TITLE": "Adicionar marcador",
"DESC": "Etiquetas permitem agrupar as conversas.", "DESC": "Etiquetas permitem agrupar as conversas.",
"API": { "API": {
"SUCCESS_MESSAGE": "Etiqueta adicionada com sucesso", "SUCCESS_MESSAGE": "Marcador adicionado com sucesso",
"ERROR_MESSAGE": "Ocorreu um erro, por favor tente novamente" "ERROR_MESSAGE": "Ocorreu um erro, por favor tente novamente"
} }
}, },
@@ -71,7 +71,7 @@
"DELETE": { "DELETE": {
"BUTTON_TEXT": "Excluir", "BUTTON_TEXT": "Excluir",
"API": { "API": {
"SUCCESS_MESSAGE": "Etiqueta excluída com sucesso", "SUCCESS_MESSAGE": "Marcador excluído com sucesso",
"ERROR_MESSAGE": "Ocorreu um erro, por favor tente novamente" "ERROR_MESSAGE": "Ocorreu um erro, por favor tente novamente"
}, },
"CONFIRM": { "CONFIRM": {
@@ -471,7 +471,7 @@
"NO_AGENTS": "Não há conversas por agentes", "NO_AGENTS": "Não há conversas por agentes",
"TABLE_HEADER": { "TABLE_HEADER": {
"AGENT": "Agente", "AGENT": "Agente",
"OPEN": "Abrir", "OPEN": "Abertas",
"UNATTENDED": "Não atendidas", "UNATTENDED": "Não atendidas",
"STATUS": "Situação" "STATUS": "Situação"
} }
@@ -509,7 +509,7 @@
"SLA": "Nome do SLA", "SLA": "Nome do SLA",
"AGENTS": "Nome do Agente", "AGENTS": "Nome do Agente",
"INBOXES": "Nome da Caixa de Entrada", "INBOXES": "Nome da Caixa de Entrada",
"LABELS": "Nome da etiqueta", "LABELS": "Nome do marcador",
"TEAMS": "Nome da equipe" "TEAMS": "Nome da equipe"
}, },
"SLA": "Política SLA", "SLA": "Política SLA",
@@ -26,7 +26,7 @@
"UPDATE_SUCCESS": "Suas configurações foram atualizadas com sucesso", "UPDATE_SUCCESS": "Suas configurações foram atualizadas com sucesso",
"CARD": { "CARD": {
"ENTER_KEY": { "ENTER_KEY": {
"HEADING": "Enter (↵)", "HEADING": "Inserir (↵)",
"CONTENT": "Enviar mensagens pressionando a tecla Enter em vez de clicar no botão de enviar." "CONTENT": "Enviar mensagens pressionando a tecla Enter em vez de clicar no botão de enviar."
}, },
"CMD_ENTER_KEY": { "CMD_ENTER_KEY": {
@@ -37,19 +37,19 @@
}, },
"INTERFACE_SECTION": { "INTERFACE_SECTION": {
"TITLE": "Interface", "TITLE": "Interface",
"NOTE": "Personalize a aparência do seu painel do Chatwoot.", "NOTE": "Customize the look and feel of your Chatwoot dashboard.",
"FONT_SIZE": { "FONT_SIZE": {
"TITLE": "Tamanho da fonte", "TITLE": "Font size",
"NOTE": "Ajuste o tamanho do texto do painel com base na sua preferência.", "NOTE": "Adjust the text size across the dashboard based on your preference.",
"UPDATE_SUCCESS": "As configurações de sua fonte foram atualizadas com sucesso", "UPDATE_SUCCESS": "Your font settings have been updated successfully",
"UPDATE_ERROR": "Ocorreu um erro ao atualizar as configurações de fonte, por favor, tente novamente", "UPDATE_ERROR": "There is an error while updating the font settings, please try again",
"OPTIONS": { "OPTIONS": {
"SMALLER": "Menor", "SMALLER": "Smaller",
"SMALL": "Pequeno", "SMALL": "Small",
"DEFAULT": "Padrão", "DEFAULT": "Padrão",
"LARGE": "Grande", "LARGE": "Large",
"LARGER": "Maior", "LARGER": "Larger",
"EXTRA_LARGE": "Muito Grande" "EXTRA_LARGE": "Extra Large"
} }
} }
}, },
@@ -287,13 +287,13 @@
"HOME": "Principal", "HOME": "Principal",
"AGENTS": "Agentes", "AGENTS": "Agentes",
"AGENT_BOTS": "Robôs", "AGENT_BOTS": "Robôs",
"AUDIT_LOGS": "Auditoria", "AUDIT_LOGS": "Registros de Auditoria",
"INBOXES": "Caixas de Entrada", "INBOXES": "Caixas de Entrada",
"NOTIFICATIONS": "Notificações", "NOTIFICATIONS": "Notificações",
"CANNED_RESPONSES": "Respostas Prontas", "CANNED_RESPONSES": "Respostas Prontas",
"INTEGRATIONS": "Integrações", "INTEGRATIONS": "Integrações",
"PROFILE_SETTINGS": "Configurações do Perfil", "PROFILE_SETTINGS": "Configurações do Perfil",
"ACCOUNT_SETTINGS": "Conta", "ACCOUNT_SETTINGS": "Configurações da conta",
"APPLICATIONS": "Aplicações", "APPLICATIONS": "Aplicações",
"LABELS": "Etiquetas", "LABELS": "Etiquetas",
"CUSTOM_ATTRIBUTES": "Atributos Personalizados", "CUSTOM_ATTRIBUTES": "Atributos Personalizados",
@@ -322,7 +322,7 @@
"REPORTS_INBOX": "Caixa de Entrada", "REPORTS_INBOX": "Caixa de Entrada",
"REPORTS_TEAM": "Equipe", "REPORTS_TEAM": "Equipe",
"SET_AVAILABILITY_TITLE": "Defina como", "SET_AVAILABILITY_TITLE": "Defina como",
"SET_YOUR_AVAILABILITY": "Disponibilidade", "SET_YOUR_AVAILABILITY": "Definir a sua disponibilidade",
"SLA": "SLA", "SLA": "SLA",
"CUSTOM_ROLES": "Regras Personalizadas", "CUSTOM_ROLES": "Regras Personalizadas",
"BETA": "Beta", "BETA": "Beta",
@@ -1,9 +1,9 @@
{ {
"SLA": { "SLA": {
"HEADER": "Acordo de Nível de Serviço", "HEADER": "Termos do Serviço",
"ADD_ACTION": "Adicionar SLA", "ADD_ACTION": "Adicionar SLA",
"ADD_ACTION_LONG": "Criar uma nova Política de SLA", "ADD_ACTION_LONG": "Criar uma nova Política de SLA",
"DESCRIPTION": "Acordo de Nível de Serviço (SLAs em inglês) são acordos que definem expectativas claras entre sua equipe e os clientes. Estabelecem normas para tempos de resposta e de resolução, criando um quadro de responsabilização e garantindo uma experiência coerente e de qualidade.", "DESCRIPTION": "Contratos de Nível de Serviço (SLAs em inglês) são contratos que definem expectativas claras entre sua equipe e os clientes. Estabelecem normas para tempos de resposta e de resolução, criando um quadro de responsabilização e garantindo uma experiência coerente e de qualidade.",
"LEARN_MORE": "Saiba mais sobre SLA", "LEARN_MORE": "Saiba mais sobre SLA",
"LOADING": "Buscando SLAs", "LOADING": "Buscando SLAs",
"PAYWALL": { "PAYWALL": {
@@ -15,7 +15,7 @@
}, },
"ENTERPRISE_PAYWALL": { "ENTERPRISE_PAYWALL": {
"AVAILABLE_ON": "O recurso SLA está disponível apenas nos planos pagos.", "AVAILABLE_ON": "O recurso SLA está disponível apenas nos planos pagos.",
"UPGRADE_PROMPT": "Atualize para um plano pago para acessar recursos avançados como logs de auditoria, capacidade do agente e muito mais.", "UPGRADE_PROMPT": "Atualize para um plano pago para acessar recursos avançados como registros de auditoria, capacidade do agente e muito mais.",
"ASK_ADMIN": "Entre em contato com seu administrador para fazer a atualização." "ASK_ADMIN": "Entre em contato com seu administrador para fazer a atualização."
}, },
"LIST": { "LIST": {
@@ -266,7 +266,7 @@
"ATTRIBUTE_WARNING": "Контактная информация <strong>{primaryContactName}</strong> будет скопирована в <strong>{parentContactName}</strong>." "ATTRIBUTE_WARNING": "Контактная информация <strong>{primaryContactName}</strong> будет скопирована в <strong>{parentContactName}</strong>."
}, },
"SEARCH": { "SEARCH": {
"ERROR_MESSAGE": "Что-то пошло не так. Пожалуйста, попробуйте позже." "ERROR_MESSAGE": "Something went wrong. Please try again later."
}, },
"FORM": { "FORM": {
"SUBMIT": " Объединить контакты", "SUBMIT": " Объединить контакты",
@@ -563,7 +563,7 @@
"GO_TO_CONVERSATION": "Просмотр", "GO_TO_CONVERSATION": "Просмотр",
"SUCCESS_MESSAGE": "Сообщение успешно отправлено!", "SUCCESS_MESSAGE": "Сообщение успешно отправлено!",
"ERROR_MESSAGE": "Произошла ошибка при создании диалога. Пожалуйста, повторите попытку позже.", "ERROR_MESSAGE": "Произошла ошибка при создании диалога. Пожалуйста, повторите попытку позже.",
"NO_INBOX_ALERT": "Нет доступных входящих для начала разговора с этим контактом.", "NO_INBOX_ALERT": "Нет доступных \"входящих\" для начала разговора с этим контактом.",
"CONTACT_SELECTOR": { "CONTACT_SELECTOR": {
"LABEL": "Кому:", "LABEL": "Кому:",
"TAG_INPUT_PLACEHOLDER": "Поиск контакта с именем, email или номером телефона", "TAG_INPUT_PLACEHOLDER": "Поиск контакта с именем, email или номером телефона",
@@ -31,7 +31,7 @@
}, },
"PERMISSIONS": { "PERMISSIONS": {
"CONVERSATION_MANAGE": "Управление всеми диалогами", "CONVERSATION_MANAGE": "Управление всеми диалогами",
"CONVERSATION_UNASSIGNED_MANAGE": "Управление неназначенными беседами и теми, которые им назначены", "CONVERSATION_UNASSIGNED_MANAGE": "Управление неназначенными беседами и теми, которые назначены им",
"CONVERSATION_PARTICIPATING_MANAGE": "Управление текущими беседами и теми, которые им назначены", "CONVERSATION_PARTICIPATING_MANAGE": "Управление текущими беседами и теми, которые им назначены",
"CONTACT_MANAGE": "Управление контактами", "CONTACT_MANAGE": "Управление контактами",
"REPORT_MANAGE": "Управление отчетами", "REPORT_MANAGE": "Управление отчетами",
@@ -114,7 +114,7 @@
"CHANGE_PRIORITY": "Изменить приоритет", "CHANGE_PRIORITY": "Изменить приоритет",
"CHANGE_TEAM": "Изменить команду", "CHANGE_TEAM": "Изменить команду",
"SNOOZE_CONVERSATION": "Включить звук диалога", "SNOOZE_CONVERSATION": "Включить звук диалога",
"ADD_LABEL": "Добавить метку в диалог", "ADD_LABEL": "Добавить метку в разговор",
"REMOVE_LABEL": "Удалить метку из диалога", "REMOVE_LABEL": "Удалить метку из диалога",
"SETTINGS": "Настройки", "SETTINGS": "Настройки",
"AI_ASSIST": "Помощь ИИ", "AI_ASSIST": "Помощь ИИ",
@@ -128,11 +128,11 @@
"GO_TO_CONVERSATION_REPORTS": "Перейти к отчетам по диалогам", "GO_TO_CONVERSATION_REPORTS": "Перейти к отчетам по диалогам",
"GO_TO_AGENT_REPORTS": "Перейти к отчетам по сотрудникам", "GO_TO_AGENT_REPORTS": "Перейти к отчетам по сотрудникам",
"GO_TO_LABEL_REPORTS": "Перейти к отчетам по меткам", "GO_TO_LABEL_REPORTS": "Перейти к отчетам по меткам",
"GO_TO_INBOX_REPORTS": "Перейти к отчётам по «Входящим»", "GO_TO_INBOX_REPORTS": "Перейти к отчётам по \"Входящим\"",
"GO_TO_TEAM_REPORTS": "Перейти к отчетам по командам", "GO_TO_TEAM_REPORTS": "Перейти к отчетам по командам",
"GO_TO_SETTINGS_AGENTS": "Перейти к настройкам сотрудников", "GO_TO_SETTINGS_AGENTS": "Перейти к настройкам сотрудников",
"GO_TO_SETTINGS_TEAMS": "Перейти к настройкам команд", "GO_TO_SETTINGS_TEAMS": "Перейти к настройкам команд",
"GO_TO_SETTINGS_INBOXES": "Перейти к настройкам «Входящих»", "GO_TO_SETTINGS_INBOXES": "Перейти к настройкам \"Входящих\"",
"GO_TO_SETTINGS_LABELS": "Перейти к настройкам меток", "GO_TO_SETTINGS_LABELS": "Перейти к настройкам меток",
"GO_TO_SETTINGS_CANNED_RESPONSES": "Перейти к настройкам шаблонных ответов", "GO_TO_SETTINGS_CANNED_RESPONSES": "Перейти к настройкам шаблонных ответов",
"GO_TO_SETTINGS_APPLICATIONS": "Перейти в настройки приложения", "GO_TO_SETTINGS_APPLICATIONS": "Перейти в настройки приложения",
@@ -2,7 +2,7 @@
"INBOX_MGMT": { "INBOX_MGMT": {
"HEADER": "Источники", "HEADER": "Источники",
"DESCRIPTION": "Канал — это способ коммуникации, который ваш клиент выбирает для связи с вами. Входящие — это место, где вы управляете диалогами для определенного канала. Он может включать диалоги из различных источников, таких как электронная почта, онлайн чат или социальные сети.", "DESCRIPTION": "Канал — это способ коммуникации, который ваш клиент выбирает для связи с вами. Входящие — это место, где вы управляете диалогами для определенного канала. Он может включать диалоги из различных источников, таких как электронная почта, онлайн чат или социальные сети.",
"LEARN_MORE": "Узнать больше о «Входящих»", "LEARN_MORE": "Узнать больше о \"Входящих\"",
"RECONNECTION_REQUIRED": "Входящие сообщения отключены. Вы не будете получать новые сообщения пока не пройдете авторизацию повторно.", "RECONNECTION_REQUIRED": "Входящие сообщения отключены. Вы не будете получать новые сообщения пока не пройдете авторизацию повторно.",
"CLICK_TO_RECONNECT": "Нажмите здесь для повторного подключения.", "CLICK_TO_RECONNECT": "Нажмите здесь для повторного подключения.",
"LIST": { "LIST": {
@@ -208,8 +208,8 @@
} }
}, },
"WHATSAPP": { "WHATSAPP": {
"TITLE": "Канал WhatsApp", "TITLE": "WhatsApp канал",
"DESC": "Начните поддерживать своих клиентов через WhatsApp.", "DESC": "Начните поддерживать ваших клиентов через WhatsApp.",
"PROVIDERS": { "PROVIDERS": {
"LABEL": "Поставщик API", "LABEL": "Поставщик API",
"TWILIO": "Twilio", "TWILIO": "Twilio",
@@ -302,8 +302,8 @@
"ERROR": "Произошла ошибка при отвязке задачи, пожалуйста, попробуйте ещё раз" "ERROR": "Произошла ошибка при отвязке задачи, пожалуйста, попробуйте ещё раз"
}, },
"DELETE": { "DELETE": {
"TITLE": "Вы уверены, что хотите удалить интеграцию?", "TITLE": "Are you sure you want to delete the integration?",
"MESSAGE": "Вы уверены, что хотите удалить интеграцию?", "MESSAGE": "Are you sure you want to delete the integration?",
"CONFIRM": "Да, удалить", "CONFIRM": "Да, удалить",
"CANCEL": "Отменить" "CANCEL": "Отменить"
} }
@@ -317,18 +317,18 @@
"YOU": "Вы", "YOU": "Вы",
"USE": "Использовать это", "USE": "Использовать это",
"RESET": "Сброс", "RESET": "Сброс",
"SELECT_ASSISTANT": "Выбрать ассистента" "SELECT_ASSISTANT": "Select Assistant"
}, },
"PAYWALL": { "PAYWALL": {
"TITLE": "Обновите тарифный план, чтобы использовать Captain AI", "TITLE": "Обновите тарифный план, чтобы использовать Captain AI",
"AVAILABLE_ON": "Капитан недоступен на бесплатном тарифном плане.", "AVAILABLE_ON": "Капитан недоступен на бесплатном тарифном плане.",
"UPGRADE_PROMPT": "Обновите тарифный план, чтобы получить доступ к нашим ассистентам, copilot и другим функциям.", "UPGRADE_PROMPT": "Обновите тарифный план, чтобы получить доступ к помощникам, Captain AI и другому.",
"UPGRADE_NOW": "Обновить сейчас", "UPGRADE_NOW": "Обновить сейчас",
"CANCEL_ANYTIME": "Вы можете изменить или отменить ваш тарифный план в любое время" "CANCEL_ANYTIME": "Вы можете изменить или отменить ваш тарифный план в любое время"
}, },
"ENTERPRISE_PAYWALL": { "ENTERPRISE_PAYWALL": {
"AVAILABLE_ON": "Функция Captain AI доступна только в платном плане.", "AVAILABLE_ON": "Функция Captain AI доступна только в платном плане.",
"UPGRADE_PROMPT": "Обновите тарифный план, чтобы получить доступ к нашим ассистентам, copilot и другим функциям.", "UPGRADE_PROMPT": "Обновите тарифный план, чтобы получить доступ к помощникам, Captain AI и другому.",
"ASK_ADMIN": "Пожалуйста, обратитесь к вашему администратору для обновления." "ASK_ADMIN": "Пожалуйста, обратитесь к вашему администратору для обновления."
}, },
"BANNER": { "BANNER": {
@@ -341,35 +341,35 @@
"EDIT": "Обновить" "EDIT": "Обновить"
}, },
"ASSISTANTS": { "ASSISTANTS": {
"HEADER": "Ассистенты", "HEADER": "Помощники",
"ADD_NEW": "Создать нового ассистента", "ADD_NEW": "Создать нового помощника",
"DELETE": { "DELETE": {
"TITLE": "Вы уверены, что хотите удалить ассистента?", "TITLE": "Вы уверены, что хотите удалить помощника?",
"DESCRIPTION": "Это действие необратимо. Удаление этого ассистента удалит его из всех подключенных источников и навсегда удалит все сгенерированные знания.", "DESCRIPTION": "Это действие необратимо. Удаление этого помощника удалит его из всех подключенных источников и навсегда удалит все сгенерированные знания.",
"CONFIRM": "Да, удалить", "CONFIRM": "Да, удалить",
"SUCCESS_MESSAGE": "Ассистент успешно удален", "SUCCESS_MESSAGE": "Помощник успешно удален",
"ERROR_MESSAGE": "При удалении ассистента произошла ошибка. Пожалуйста, попробуйте еще раз." "ERROR_MESSAGE": "При удалении помощника произошла ошибка. Пожалуйста, попробуйте еще раз."
}, },
"FORM_DESCRIPTION": "Заполните приведенные ниже сведения, чтобы назвать своего ассистента, описать его цель и указать поддерживаемый продукт.", "FORM_DESCRIPTION": "Заполните приведенные ниже сведения, чтобы назвать своего помощника, описать его цель и указать поддерживаемый продукт.",
"CREATE": { "CREATE": {
"TITLE": "Создать ассистента", "TITLE": "Создать помощника",
"SUCCESS_MESSAGE": "Ассистент успешно создан", "SUCCESS_MESSAGE": "Помощник успешно создан",
"ERROR_MESSAGE": "При создании ассистента произошла ошибка, пожалуйста, попробуйте еще раз." "ERROR_MESSAGE": "При создании помощника произошла ошибка, пожалуйста, попробуйте еще раз."
}, },
"FORM": { "FORM": {
"NAME": { "NAME": {
"LABEL": "Имя ассистента", "LABEL": "Имя помощника",
"PLACEHOLDER": "Введите имя ассистента", "PLACEHOLDER": "Введите имя помощника",
"ERROR": "Пожалуйста, укажите имя ассистента" "ERROR": "Пожалуйста, укажите имя помощника"
}, },
"DESCRIPTION": { "DESCRIPTION": {
"LABEL": "Описание ассистента", "LABEL": "Описание помощника",
"PLACEHOLDER": "Опишите, как и где будет использоваться этот ассистент", "PLACEHOLDER": "Опишите, как и где будет использоваться этот помощник",
"ERROR": "Необходимо описание" "ERROR": "Необходимо описание"
}, },
"PRODUCT_NAME": { "PRODUCT_NAME": {
"LABEL": "Название продукта", "LABEL": "Название продукта",
"PLACEHOLDER": "Введите название продукта, для которого предназначен этот ассистент", "PLACEHOLDER": "Введите название продукта, для которого предназначен этот помощник",
"ERROR": "Требуется название продукта" "ERROR": "Требуется название продукта"
}, },
"FEATURES": { "FEATURES": {
@@ -379,18 +379,18 @@
} }
}, },
"EDIT": { "EDIT": {
"TITLE": "Обновить ассистента", "TITLE": "Обновить помощника",
"SUCCESS_MESSAGE": "Ассистент успешно обновлен", "SUCCESS_MESSAGE": "Помощник успешно обновлен",
"ERROR_MESSAGE": "При обновлении ассистента произошла ошибка, пожалуйста, попробуйте еще раз." "ERROR_MESSAGE": "При обновлении помощника произошла ошибка, пожалуйста, попробуйте еще раз."
}, },
"OPTIONS": { "OPTIONS": {
"EDIT_ASSISTANT": "Редактировать ассистента", "EDIT_ASSISTANT": "Редактировать помощника",
"DELETE_ASSISTANT": "Удалить ассистента", "DELETE_ASSISTANT": "Удалить помощника",
"VIEW_CONNECTED_INBOXES": "Просмотр подключенных источников" "VIEW_CONNECTED_INBOXES": "Просмотр подключенных источников"
}, },
"EMPTY_STATE": { "EMPTY_STATE": {
"TITLE": "Нет доступных ассистентов", "TITLE": "Нет доступных помощников",
"SUBTITLE": "Создайте ассистента, чтобы дать быстрые и точные ответы пользователям. Он может учиться на ваших статьях из центра поддержки и прошлых диалогах." "SUBTITLE": "Создайте помощника, чтобы дать быстрые и точные ответы пользователям. Он может учиться на ваших статьях из центра поддержки и прошлых диалогах."
} }
}, },
"DOCUMENTS": { "DOCUMENTS": {
@@ -413,9 +413,9 @@
"ERROR": "Пожалуйста, укажите корректный URL для документа" "ERROR": "Пожалуйста, укажите корректный URL для документа"
}, },
"ASSISTANT": { "ASSISTANT": {
"LABEL": "Ассистент", "LABEL": "Помощник",
"PLACEHOLDER": "Выберите ассистента", "PLACEHOLDER": "Выберите помощника",
"ERROR": "Необходимо заполнить поле ассистента" "ERROR": "Необходимо заполнить поле помощника"
} }
}, },
"DELETE": { "DELETE": {
@@ -440,19 +440,19 @@
"DOCUMENTABLE": { "DOCUMENTABLE": {
"CONVERSATION": "Диалог #{id}" "CONVERSATION": "Диалог #{id}"
}, },
"SELECTED": "Выбрано {count}", "SELECTED": "{count} selected",
"BULK_APPROVE_BUTTON": "Одобрить", "BULK_APPROVE_BUTTON": "Approve",
"BULK_DELETE_BUTTON": "Удалить", "BULK_DELETE_BUTTON": "Удалить",
"BULK_APPROVE": { "BULK_APPROVE": {
"SUCCESS_MESSAGE": "FAQ успешно одобрены", "SUCCESS_MESSAGE": "FAQs approved successfully",
"ERROR_MESSAGE": "Произошла ошибка при одобрении FAQ, пожалуйста, попробуйте ещё раз." "ERROR_MESSAGE": "There was an error approving the FAQs, please try again."
}, },
"BULK_DELETE": { "BULK_DELETE": {
"TITLE": "Удалить FAQ?", "TITLE": "Delete FAQs?",
"DESCRIPTION": "Вы уверены, что хотите удалить выбранные FAQ? Это действие невозможно отменить.", "DESCRIPTION": "Are you sure you want to delete the selected FAQs? This action cannot be undone.",
"CONFIRM": "Да, удалить всё", "CONFIRM": "Yes, delete all",
"SUCCESS_MESSAGE": "FAQ успешно удалены", "SUCCESS_MESSAGE": "FAQs deleted successfully",
"ERROR_MESSAGE": "Произошла ошибка при удалении FAQ, пожалуйста, попробуйте ещё раз." "ERROR_MESSAGE": "There was an error deleting the FAQs, please try again."
}, },
"DELETE": { "DELETE": {
"TITLE": "Вы действительно хотите удалить FAQ?", "TITLE": "Вы действительно хотите удалить FAQ?",
@@ -462,7 +462,7 @@
"ERROR_MESSAGE": "Произошла ошибка при удалении FAQ, попробуйте еще раз." "ERROR_MESSAGE": "Произошла ошибка при удалении FAQ, попробуйте еще раз."
}, },
"FILTER": { "FILTER": {
"ASSISTANT": "Ассистент: {selected}", "ASSISTANT": "Помощник: {selected}",
"STATUS": "Статус: {selected}", "STATUS": "Статус: {selected}",
"ALL_ASSISTANTS": "Все" "ALL_ASSISTANTS": "Все"
}, },
@@ -472,7 +472,7 @@
"APPROVED": "Одобрено", "APPROVED": "Одобрено",
"ALL": "Все" "ALL": "Все"
}, },
"FORM_DESCRIPTION": "Добавьте вопрос и соответствующий ему ответ в базу знаний и выберите ассистента, с которым он должен связаться.", "FORM_DESCRIPTION": "Добавьте вопрос и соответствующий ему ответ в базу знаний и выберите помощника, с которым он должен связаться.",
"CREATE": { "CREATE": {
"TITLE": "Добавить FAQ", "TITLE": "Добавить FAQ",
"SUCCESS_MESSAGE": "Ответ успешно добавлен.", "SUCCESS_MESSAGE": "Ответ успешно добавлен.",
@@ -487,59 +487,59 @@
"ANSWER": { "ANSWER": {
"LABEL": "Ответ", "LABEL": "Ответ",
"PLACEHOLDER": "Введите ответ", "PLACEHOLDER": "Введите ответ",
"ERROR": "Пожалуйста, введите корректный ответ." "ERROR": "Please provide a valid answer."
}, },
"ASSISTANT": { "ASSISTANT": {
"LABEL": "Ассистент", "LABEL": "Помощник",
"PLACEHOLDER": "Выбрать ассистента", "PLACEHOLDER": "Select an assistant",
"ERROR": "Выбрать ассистента" "ERROR": "Please select an assistant."
} }
}, },
"EDIT": { "EDIT": {
"TITLE": "Обновить FAQ", "TITLE": "Update the FAQ",
"SUCCESS_MESSAGE": "FAQ успешно обновлён", "SUCCESS_MESSAGE": "The FAQ has been successfully updated",
"ERROR_MESSAGE": "Произошла ошибка при обновлении FAQ, пожалуйста, попробуйте ещё раз", "ERROR_MESSAGE": "There was an error updating the FAQ, please try again",
"APPROVE_SUCCESS_MESSAGE": "FAQ был отмечен как одобренный" "APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
}, },
"OPTIONS": { "OPTIONS": {
"APPROVE": "Отметить как одобренный", "APPROVE": "Mark as approved",
"EDIT_RESPONSE": "FAQ отмечен как одобренный", "EDIT_RESPONSE": "Edit FAQ",
"DELETE_RESPONSE": "Удалить FAQ" "DELETE_RESPONSE": "Delete FAQ"
}, },
"EMPTY_STATE": { "EMPTY_STATE": {
"TITLE": "FAQ не найдены", "TITLE": "No FAQs Found",
"SUBTITLE": "FAQ помогают вашему ассистенту быстро и точно отвечать на вопросы клиентов. Их можно генерировать автоматически из вашего контента или добавлять вручную." "SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually."
} }
}, },
"INBOXES": { "INBOXES": {
"HEADER": "Подключённые источники входящих", "HEADER": "Connected Inboxes",
"ADD_NEW": "Подключить новый источник входящих", "ADD_NEW": "Connect a new inbox",
"OPTIONS": { "OPTIONS": {
"DISCONNECT": "Отключиться" "DISCONNECT": "Отключиться"
}, },
"DELETE": { "DELETE": {
"TITLE": "Вы уверены, что хотите отключить этот источник входящих?", "TITLE": "Are you sure to disconnect the inbox?",
"DESCRIPTION": "", "DESCRIPTION": "",
"CONFIRM": "Да, удалить", "CONFIRM": "Да, удалить",
"SUCCESS_MESSAGE": "Источник входящих успешно отключён.", "SUCCESS_MESSAGE": "The inbox was successfully disconnected.",
"ERROR_MESSAGE": "Произошла ошибка при отключении источника входящих, пожалуйста, попробуйте ещё раз." "ERROR_MESSAGE": "There was an error disconnecting the inbox, please try again."
}, },
"FORM_DESCRIPTION": "Выберите источник входящих для подключения к ассистенту.", "FORM_DESCRIPTION": "Choose an inbox to connect with the assistant.",
"CREATE": { "CREATE": {
"TITLE": "Подключить источник входящих", "TITLE": "Connect an Inbox",
"SUCCESS_MESSAGE": "Источник входящих успешно подключён.", "SUCCESS_MESSAGE": "The inbox was successfully connected.",
"ERROR_MESSAGE": "Произошла ошибка при подключении источника входящих. Пожалуйста, попробуйте ещё раз." "ERROR_MESSAGE": "An error occurred while connecting the inbox. Please try again."
}, },
"FORM": { "FORM": {
"INBOX": { "INBOX": {
"LABEL": "Электронная почта", "LABEL": "Электронная почта",
"PLACEHOLDER": "Выберите источник входящих для развертывания ассистента.", "PLACEHOLDER": "Choose the inbox to deploy the assistant.",
"ERROR": "Необходимо выбрать источник входящих." "ERROR": "An inbox selection is required."
} }
}, },
"EMPTY_STATE": { "EMPTY_STATE": {
"TITLE": "Нет подключённых источников входящих", "TITLE": "No Connected Inboxes",
"SUBTITLE": "Подключение источника входящих позволяет ассистенту обрабатывать первые вопросы ваших клиентов до их передачи вам." "SUBTITLE": "Connecting an inbox allows the assistant to handle initial questions from your customers before transferring them to you."
} }
} }
} }
@@ -124,7 +124,7 @@
}, },
"AGENT_REPORTS": { "AGENT_REPORTS": {
"HEADER": "Обзор агентов", "HEADER": "Обзор агентов",
"DESCRIPTION": "Легко отслеживайте эффективность работы агентов с помощью ключевых метрик, таких как количество бесед, время ответа, время решения проблем и количество решённых случаев. Нажмите на имя агента, чтобы узнать подробности.", "DESCRIPTION": "Easily track agent performance with key metrics such as conversations, response times, resolution times, and resolved cases. Click an agent’s name to learn more.",
"LOADING_CHART": "Загрузка данных графика...", "LOADING_CHART": "Загрузка данных графика...",
"NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.", "NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.",
"DOWNLOAD_AGENT_REPORTS": "Сказать отчёт по агентам", "DOWNLOAD_AGENT_REPORTS": "Сказать отчёт по агентам",
@@ -259,7 +259,7 @@
}, },
"INBOX_REPORTS": { "INBOX_REPORTS": {
"HEADER": "Обзор входящих", "HEADER": "Обзор входящих",
"DESCRIPTION": "Быстро просматривайте эффективность источника входящих с основными метриками — количеством бесед, временем ответа, временем решения проблем и количеством решённых случаев — всё в одном месте. Нажмите на имя источника для получения подробной информации.", "DESCRIPTION": "Quickly view your inbox performance with key metrics like conversations, response times, resolution times, and resolved cases—all in one place. Click an inbox name for more details.",
"LOADING_CHART": "Загрузка данных графика...", "LOADING_CHART": "Загрузка данных графика...",
"NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.", "NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.",
"DOWNLOAD_INBOX_REPORTS": "Скачать отчет по входящим", "DOWNLOAD_INBOX_REPORTS": "Скачать отчет по входящим",
@@ -327,7 +327,7 @@
}, },
"TEAM_REPORTS": { "TEAM_REPORTS": {
"HEADER": "Обзор команды", "HEADER": "Обзор команды",
"DESCRIPTION": "Получите обзор работы вашей команды с основными метриками, такими как количество бесед, время ответа, время решения проблем и количество решённых случаев. Нажмите на имя команды для подробностей.", "DESCRIPTION": "Get a snapshot of your team’s performance with essential metrics, including conversations, response times, resolution times, and resolved cases. Click a team name for more details.",
"LOADING_CHART": "Загрузка данных графика...", "LOADING_CHART": "Загрузка данных графика...",
"NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.", "NO_ENOUGH_DATA": "Недостаточно данных для создания отчета, пожалуйста, повторите попытку позже.",
"DOWNLOAD_TEAM_REPORTS": "Скачать отчет по команде", "DOWNLOAD_TEAM_REPORTS": "Скачать отчет по команде",
@@ -546,9 +546,9 @@
"INBOX": "Электронная почта", "INBOX": "Электронная почта",
"AGENT": "Оператор", "AGENT": "Оператор",
"TEAM": "Команда", "TEAM": "Команда",
"AVG_RESOLUTION_TIME": "Среднее время решения", "AVG_RESOLUTION_TIME": "Avg. Resolution Time",
"AVG_FIRST_RESPONSE_TIME": "Среднее время первого ответа", "AVG_FIRST_RESPONSE_TIME": "Avg. First Response Time",
"AVG_REPLY_TIME": "Среднее время ожидания клиента", "AVG_REPLY_TIME": "Avg. Customer Waiting Time",
"RESOLUTION_COUNT": "Количество завершенных", "RESOLUTION_COUNT": "Количество завершенных",
"CONVERSATIONS": "Количество диалогов" "CONVERSATIONS": "Количество диалогов"
} }
@@ -11,8 +11,8 @@
"CONVERSATIONS": "Диалоги", "CONVERSATIONS": "Диалоги",
"MESSAGES": "Сообщения" "MESSAGES": "Сообщения"
}, },
"VIEW_MORE": "Посмотреть больше", "VIEW_MORE": "View more",
"LOAD_MORE": "Загрузить ещё", "LOAD_MORE": "Load more",
"SEARCHING_DATA": "Идёт поиск", "SEARCHING_DATA": "Идёт поиск",
"LOADING_DATA": "Загрузка", "LOADING_DATA": "Загрузка",
"EMPTY_STATE": "Не найдено {item} для запроса '{query}'", "EMPTY_STATE": "Не найдено {item} для запроса '{query}'",
@@ -36,20 +36,20 @@
} }
}, },
"INTERFACE_SECTION": { "INTERFACE_SECTION": {
"TITLE": "Интерфейс", "TITLE": "Interface",
"NOTE": "Настройте внешний вид и оформление вашей панели Chatwoot.", "NOTE": "Customize the look and feel of your Chatwoot dashboard.",
"FONT_SIZE": { "FONT_SIZE": {
"TITLE": "Размер шрифта", "TITLE": "Font size",
"NOTE": "Измените размер текста на всей панели в соответствии с вашими предпочтениями.", "NOTE": "Adjust the text size across the dashboard based on your preference.",
"UPDATE_SUCCESS": "Настройки шрифта успешно обновлены", "UPDATE_SUCCESS": "Your font settings have been updated successfully",
"UPDATE_ERROR": "Произошла ошибка при обновлении настроек шрифта, пожалуйста, попробуйте ещё раз", "UPDATE_ERROR": "There is an error while updating the font settings, please try again",
"OPTIONS": { "OPTIONS": {
"SMALLER": "Меньше", "SMALLER": "Smaller",
"SMALL": "Маленький", "SMALL": "Small",
"DEFAULT": "По умолчанию", "DEFAULT": "По умолчанию",
"LARGE": "Большой", "LARGE": "Large",
"LARGER": "Крупнее", "LARGER": "Larger",
"EXTRA_LARGE": "Очень большой" "EXTRA_LARGE": "Extra Large"
} }
} }
}, },
@@ -162,7 +162,7 @@
"REQUEST_PUSH": "Включить push-уведомления", "REQUEST_PUSH": "Включить push-уведомления",
"SLA_MISSED_FIRST_RESPONSE": "Отправить push-уведомление, если диалог не соответствует SLA первого ответа", "SLA_MISSED_FIRST_RESPONSE": "Отправить push-уведомление, если диалог не соответствует SLA первого ответа",
"SLA_MISSED_NEXT_RESPONSE": "Отправить push-уведомление, если диалог не успел получить следующий ответ SLA", "SLA_MISSED_NEXT_RESPONSE": "Отправить push-уведомление, если диалог не успел получить следующий ответ SLA",
"SLA_MISSED_RESOLUTION": "Отправить push-уведомление, если диалог не соответствует SLA" "SLA_MISSED_RESOLUTION": "Отправить push-уведомление, если диалог не соответствует уровню разрешения SLA"
}, },
"PROFILE_IMAGE": { "PROFILE_IMAGE": {
"LABEL": "Изображение профиля" "LABEL": "Изображение профиля"
@@ -281,9 +281,9 @@
"SETTINGS": "Настройки", "SETTINGS": "Настройки",
"CONTACTS": "Контакты", "CONTACTS": "Контакты",
"CAPTAIN": "Капитан", "CAPTAIN": "Капитан",
"CAPTAIN_ASSISTANTS": "Ассистенты", "CAPTAIN_ASSISTANTS": "Помощники",
"CAPTAIN_DOCUMENTS": "Документы", "CAPTAIN_DOCUMENTS": "Документы",
"CAPTAIN_RESPONSES": "FAQ", "CAPTAIN_RESPONSES": "FAQs",
"HOME": "Главная", "HOME": "Главная",
"AGENTS": "Операторы", "AGENTS": "Операторы",
"AGENT_BOTS": "Боты", "AGENT_BOTS": "Боты",
@@ -345,14 +345,14 @@
}, },
"BILLING_SETTINGS": { "BILLING_SETTINGS": {
"TITLE": "Платёж", "TITLE": "Платёж",
"DESCRIPTION": "Управляйте подпиской здесь, обновите тарифный план и получите больше возможностей для вашей команды.", "DESCRIPTION": "Manage your subscription here, upgrade your plan and get more for your team.",
"CURRENT_PLAN": { "CURRENT_PLAN": {
"TITLE": "Текущий план", "TITLE": "Текущий план",
"PLAN_NOTE": "На данный момент вы подписаны на ** план{plan}** с **{quantity}** лицензиями", "PLAN_NOTE": "На данный момент вы подписаны на ** план{plan}** с **{quantity}** лицензиями",
"SEAT_COUNT": "Количество мест", "SEAT_COUNT": "Number of seats",
"RENEWS_ON": "Продление" "RENEWS_ON": "Renews on"
}, },
"VIEW_PRICING": "Посмотреть цены", "VIEW_PRICING": "View Pricing",
"MANAGE_SUBSCRIPTION": { "MANAGE_SUBSCRIPTION": {
"TITLE": "Управление подпиской", "TITLE": "Управление подпиской",
"DESCRIPTION": "Просматривайте ваши предыдущие счета, редактируйте платежные реквизиты или отмените подписку.", "DESCRIPTION": "Просматривайте ваши предыдущие счета, редактируйте платежные реквизиты или отмените подписку.",
@@ -360,11 +360,11 @@
}, },
"CAPTAIN": { "CAPTAIN": {
"TITLE": "Капитан", "TITLE": "Капитан",
"DESCRIPTION": "Управляйте использованием и кредитами для Captain AI.", "DESCRIPTION": "Manage usage and credits for Captain AI.",
"BUTTON_TXT": "Купить дополнительные кредиты", "BUTTON_TXT": "Buy more credits",
"DOCUMENTS": "Документы", "DOCUMENTS": "Документы",
"RESPONSES": "Ответы", "RESPONSES": "Responses",
"UPGRADE": "Captain недоступен в бесплатном тарифном плане, обновите его, чтобы получить доступ к ассистентам, copilot и другим функциям." "UPGRADE": "Captain is not available on the free plan, upgrade now to get access to assistants, copilot and more."
}, },
"CHAT_WITH_US": { "CHAT_WITH_US": {
"TITLE": "Нужна помощь?", "TITLE": "Нужна помощь?",
@@ -3,12 +3,13 @@ import { mapGetters } from 'vuex';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import NextSidebar from 'next/sidebar/Sidebar.vue'; import NextSidebar from 'next/sidebar/Sidebar.vue';
import Sidebar from '../../components/layout/Sidebar.vue';
import WootKeyShortcutModal from 'dashboard/components/widgets/modal/WootKeyShortcutModal.vue'; import WootKeyShortcutModal from 'dashboard/components/widgets/modal/WootKeyShortcutModal.vue';
import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAccountModal.vue'; import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAccountModal.vue';
import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector.vue'; import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector.vue';
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue'; import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue';
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue'; import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue';
import PaymentPaywall from 'dashboard/components/app/PaymentPaywall.vue';
import { useUISettings } from 'dashboard/composables/useUISettings'; import { useUISettings } from 'dashboard/composables/useUISettings';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
@@ -19,10 +20,6 @@ import { FEATURE_FLAGS } from 'dashboard/featureFlags';
const CommandBar = defineAsyncComponent( const CommandBar = defineAsyncComponent(
() => import('./commands/commandbar.vue') () => import('./commands/commandbar.vue')
); );
const Sidebar = defineAsyncComponent(
() => import('../../components/layout/Sidebar.vue')
);
import { emitter } from 'shared/helpers/mitt'; import { emitter } from 'shared/helpers/mitt';
export default { export default {
@@ -32,6 +29,7 @@ export default {
CommandBar, CommandBar,
WootKeyShortcutModal, WootKeyShortcutModal,
AddAccountModal, AddAccountModal,
PaymentPaywall,
AccountSelector, AccountSelector,
AddLabelModal, AddLabelModal,
NotificationPanel, NotificationPanel,
@@ -197,7 +195,9 @@ export default {
@show-add-label-popup="showAddLabelPopup" @show-add-label-popup="showAddLabelPopup"
/> />
<main class="flex flex-1 h-full min-h-0 px-0 overflow-hidden"> <main class="flex flex-1 h-full min-h-0 px-0 overflow-hidden">
<router-view /> <PaymentPaywall>
<router-view />
</PaymentPaywall>
<CommandBar /> <CommandBar />
<AccountSelector <AccountSelector
:show-account-modal="showAccountModal" :show-account-modal="showAccountModal"
@@ -121,6 +121,8 @@ export default {
this.isALineChannel || this.isALineChannel ||
this.isAPIInbox || this.isAPIInbox ||
(this.isAnEmailChannel && !this.inbox.provider) || (this.isAnEmailChannel && !this.inbox.provider) ||
this.isAMicrosoftInbox ||
this.isAGoogleInbox ||
this.isAWhatsAppChannel || this.isAWhatsAppChannel ||
this.isAWebWidgetInbox this.isAWebWidgetInbox
) { ) {
@@ -39,14 +39,13 @@ export default {
}, },
mixins: [globalConfigMixin], mixins: [globalConfigMixin],
setup() { setup() {
const { isEditorHotKeyEnabled, updateUISettings } = useUISettings(); const { isEditorHotKeyEnabled } = useUISettings();
const { currentFontSize, updateFontSize } = useFontSize(); const { currentFontSize, updateFontSize } = useFontSize();
return { return {
currentFontSize, currentFontSize,
updateFontSize, updateFontSize,
isEditorHotKeyEnabled, isEditorHotKeyEnabled,
updateUISettings,
}; };
}, },
data() { data() {
@@ -23,6 +23,7 @@ const state = {
export const getters = { export const getters = {
getAccount: $state => id => { getAccount: $state => id => {
console.log('account', id);
return findRecordById($state, id); return findRecordById($state, id);
}, },
getUIFlags($state) { getUIFlags($state) {
@@ -79,10 +79,10 @@ class BaseActionCableConnector {
this.consumer.disconnect(); this.consumer.disconnect();
} }
onReceived = ({ event, data, event_timestamp } = {}) => { onReceived = ({ event, data } = {}) => {
if (this.isAValidEvent(data)) { if (this.isAValidEvent(data)) {
if (this.events[event] && typeof this.events[event] === 'function') { if (this.events[event] && typeof this.events[event] === 'function') {
this.events[event](data, event_timestamp); this.events[event](data);
} }
} }
}; };
+4 -8
View File
@@ -10,11 +10,11 @@ class ActionCableBroadcastJob < ApplicationJob
CONVERSATION_STATUS_CHANGED CONVERSATION_STATUS_CHANGED
].freeze ].freeze
def perform(members, event_name, data, event_timestamp) def perform(members, event_name, data)
return if members.blank? return if members.blank?
broadcast_data = prepare_broadcast_data(event_name, data) broadcast_data = prepare_broadcast_data(event_name, data)
broadcast_to_members(members, event_name, broadcast_data, event_timestamp) broadcast_to_members(members, event_name, broadcast_data)
end end
private private
@@ -30,17 +30,13 @@ class ActionCableBroadcastJob < ApplicationJob
conversation.push_event_data.merge(account_id: data[:account_id]) conversation.push_event_data.merge(account_id: data[:account_id])
end end
# A timestamp is added to the broadcast data, this timestamp is def broadcast_to_members(members, event_name, broadcast_data)
# generated in the main app thread when the job is enqueued.
# This is used as a "sequence number" to ensure we ignore out of order events
def broadcast_to_members(members, event_name, broadcast_data, event_timestamp)
members.each do |member| members.each do |member|
ActionCable.server.broadcast( ActionCable.server.broadcast(
member, member,
{ {
event: event_name, event: event_name,
data: broadcast_data, data: broadcast_data
event_timestamp: event_timestamp
} }
) )
end end
@@ -2,15 +2,8 @@ class Inboxes::FetchImapEmailInboxesJob < ApplicationJob
queue_as :scheduled_jobs queue_as :scheduled_jobs
def perform def perform
email_inboxes = Inbox.where(channel_type: 'Channel::Email') Inbox.where(channel_type: 'Channel::Email').all.find_each(batch_size: 100) do |inbox|
email_inboxes.find_each(batch_size: 100) do |inbox| ::Inboxes::FetchImapEmailsJob.perform_later(inbox.channel) if inbox.channel.imap_enabled
::Inboxes::FetchImapEmailsJob.perform_later(inbox.channel) if should_fetch_emails?(inbox)
end end
end end
private
def should_fetch_emails?(inbox)
inbox.channel.imap_enabled && !inbox.account.suspended?
end
end end
+7 -12
View File
@@ -58,8 +58,7 @@ class ActionCableListener < BaseListener
conversation, account = extract_conversation_and_account(event) conversation, account = extract_conversation_and_account(event)
tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox) tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox)
# Include the original event timestamp to ensure correct ordering on frontend broadcast(account, tokens, CONVERSATION_CREATED, conversation.push_event_data)
broadcast(account, tokens, CONVERSATION_CREATED, conversation.push_event_data, event.timestamp.to_f)
end end
def conversation_read(event) def conversation_read(event)
@@ -73,16 +72,14 @@ class ActionCableListener < BaseListener
conversation, account = extract_conversation_and_account(event) conversation, account = extract_conversation_and_account(event)
tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox) tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox)
# Include the original event timestamp to ensure correct ordering on frontend broadcast(account, tokens, CONVERSATION_STATUS_CHANGED, conversation.push_event_data)
broadcast(account, tokens, CONVERSATION_STATUS_CHANGED, conversation.push_event_data, event.timestamp.to_f)
end end
def conversation_updated(event) def conversation_updated(event)
conversation, account = extract_conversation_and_account(event) conversation, account = extract_conversation_and_account(event)
tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox) tokens = user_tokens(account, conversation.inbox.members) + contact_inbox_tokens(conversation.contact_inbox)
# Include the original event timestamp to ensure correct ordering on frontend broadcast(account, tokens, CONVERSATION_UPDATED, conversation.push_event_data)
broadcast(account, tokens, CONVERSATION_UPDATED, conversation.push_event_data, event.timestamp.to_f)
end end
def conversation_typing_on(event) def conversation_typing_on(event)
@@ -121,16 +118,14 @@ class ActionCableListener < BaseListener
conversation, account = extract_conversation_and_account(event) conversation, account = extract_conversation_and_account(event)
tokens = user_tokens(account, conversation.inbox.members) tokens = user_tokens(account, conversation.inbox.members)
# Include the original event timestamp to ensure correct ordering on frontend broadcast(account, tokens, ASSIGNEE_CHANGED, conversation.push_event_data)
broadcast(account, tokens, ASSIGNEE_CHANGED, conversation.push_event_data, event.timestamp.to_f)
end end
def team_changed(event) def team_changed(event)
conversation, account = extract_conversation_and_account(event) conversation, account = extract_conversation_and_account(event)
tokens = user_tokens(account, conversation.inbox.members) tokens = user_tokens(account, conversation.inbox.members)
# Include the original event timestamp to ensure correct ordering on frontend broadcast(account, tokens, TEAM_CHANGED, conversation.push_event_data)
broadcast(account, tokens, TEAM_CHANGED, conversation.push_event_data, event.timestamp.to_f)
end end
def conversation_contact_changed(event) def conversation_contact_changed(event)
@@ -202,7 +197,7 @@ class ActionCableListener < BaseListener
contact_inbox.hmac_verified? ? contact.contact_inboxes.where(hmac_verified: true).filter_map(&:pubsub_token) : [contact_inbox.pubsub_token] contact_inbox.hmac_verified? ? contact.contact_inboxes.where(hmac_verified: true).filter_map(&:pubsub_token) : [contact_inbox.pubsub_token]
end end
def broadcast(account, tokens, event_name, data, event_timestamp = nil) def broadcast(account, tokens, event_name, data)
return if tokens.blank? return if tokens.blank?
payload = data.merge(account_id: account.id) payload = data.merge(account_id: account.id)
@@ -210,6 +205,6 @@ class ActionCableListener < BaseListener
# Useful in cases like conversation assignment for generating a notification with assigner name. # Useful in cases like conversation assignment for generating a notification with assigner name.
payload[:performer] = Current.user&.push_event_data if Current.user.present? payload[:performer] = Current.user&.push_event_data if Current.user.present?
::ActionCableBroadcastJob.perform_later(tokens.uniq, event_name, payload, event_timestamp) ::ActionCableBroadcastJob.perform_later(tokens.uniq, event_name, payload)
end end
end end
+3 -18
View File
@@ -37,7 +37,7 @@ class Channel::Sms < ApplicationRecord
body = message_body(contact_number, message.content) body = message_body(contact_number, message.content)
body['media'] = message.attachments.map(&:download_url) if message.attachments.present? body['media'] = message.attachments.map(&:download_url) if message.attachments.present?
send_to_bandwidth(body, message) send_to_bandwidth(body)
end end
def send_text_message(contact_number, message_content) def send_text_message(contact_number, message_content)
@@ -56,7 +56,7 @@ class Channel::Sms < ApplicationRecord
} }
end end
def send_to_bandwidth(body, message = nil) def send_to_bandwidth(body)
response = HTTParty.post( response = HTTParty.post(
"#{api_base_path}/users/#{provider_config['account_id']}/messages", "#{api_base_path}/users/#{provider_config['account_id']}/messages",
basic_auth: bandwidth_auth, basic_auth: bandwidth_auth,
@@ -64,22 +64,7 @@ class Channel::Sms < ApplicationRecord
body: body.to_json body: body.to_json
) )
if response.success? response.success? ? response.parsed_response['id'] : nil
response.parsed_response['id']
else
handle_error(response, message)
nil
end
end
def handle_error(response, message)
Rails.logger.error("[#{account_id}] Error sending SMS: #{response.parsed_response['description']}")
return if message.blank?
# https://dev.bandwidth.com/apis/messaging-apis/messaging/#tag/Messages/operation/createMessage
message.external_error = response.parsed_response['description']
message.status = :failed
message.save!
end end
def bandwidth_auth def bandwidth_auth
@@ -20,30 +20,15 @@ class Facebook::SendOnFacebookService < Base::SendOnChannelService
end end
def send_message_to_facebook(delivery_params) def send_message_to_facebook(delivery_params)
parsed_result = deliver_message(delivery_params) result = Facebook::Messenger::Bot.deliver(delivery_params, page_id: channel.page_id)
return if parsed_result.nil? parsed_result = JSON.parse(result)
if parsed_result['error'].present? if parsed_result['error'].present?
message.update!(status: :failed, external_error: external_error(parsed_result)) message.update!(status: :failed, external_error: external_error(parsed_result))
Rails.logger.info "Facebook::SendOnFacebookService: Error sending message to Facebook : Page - #{channel.page_id} : #{parsed_result}" Rails.logger.info "Facebook::SendOnFacebookService: Error sending message to Facebook : Page - #{channel.page_id} : #{result}"
end end
message.update!(source_id: parsed_result['message_id']) if parsed_result['message_id'].present? message.update!(source_id: parsed_result['message_id']) if parsed_result['message_id'].present?
end end
def deliver_message(delivery_params)
result = Facebook::Messenger::Bot.deliver(delivery_params, page_id: channel.page_id)
JSON.parse(result)
rescue JSON::ParserError
message.update!(status: :failed, external_error: 'Facebook was unable to process this request')
Rails.logger.error "Facebook::SendOnFacebookService: Error parsing JSON response from Facebook : Page - #{channel.page_id} : #{result}"
nil
rescue Net::OpenTimeout
message.update!(status: :failed, external_error: 'Request timed out, please try again later')
Rails.logger.error "Facebook::SendOnFacebookService: Timeout error sending message to Facebook : Page - #{channel.page_id}"
nil
end
def fb_text_message_params def fb_text_message_params
{ {
recipient: { id: contact.get_source_id(inbox.id) }, recipient: { id: contact.get_source_id(inbox.id) },
@@ -70,28 +70,22 @@ class Instagram::SendOnInstagramService < Base::SendOnChannelService
query: query query: query
) )
handle_response(response, message_content) if response[:error].present?
end Rails.logger.error("Instagram response: #{response['error']} : #{message_content}")
message.status = :failed
def handle_response(response, message_content) message.external_error = external_error(response)
parsed_response = response.parsed_response
if response.success? && parsed_response['error'].blank?
message.update!(source_id: parsed_response['message_id'])
parsed_response
else
external_error = external_error(parsed_response)
Rails.logger.error("Instagram response: #{external_error} : #{message_content}")
message.update!(status: :failed, external_error: external_error)
nil
end end
message.source_id = response['message_id'] if response['message_id'].present?
message.save!
response
end end
def external_error(response) def external_error(response)
# https://developers.facebook.com/docs/instagram-api/reference/error-codes/ # https://developers.facebook.com/docs/instagram-api/reference/error-codes/
error_message = response.dig('error', 'message') error_message = response[:error][:message]
error_code = response.dig('error', 'code') error_code = response[:error][:code]
"#{error_code} - #{error_message}" "#{error_code} - #{error_message}"
end end
@@ -27,33 +27,6 @@ class Whatsapp::Providers::BaseService
raise 'Overwrite this method in child class' raise 'Overwrite this method in child class'
end end
def error_message
raise 'Overwrite this method in child class'
end
def process_response(response)
parsed_response = response.parsed_response
if response.success? && parsed_response['error'].blank?
parsed_response['messages'].first['id']
else
handle_error(response)
nil
end
end
def handle_error(response)
Rails.logger.error response.body
return if @message.blank?
# https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/#sample-response
error_message = error_message(response)
return if error_message.blank?
@message.external_error = error_message
@message.status = :failed
@message.save!
end
def create_buttons(items) def create_buttons(items)
buttons = [] buttons = []
items.each do |item| items.each do |item|
@@ -1,6 +1,5 @@
class Whatsapp::Providers::Whatsapp360DialogService < Whatsapp::Providers::BaseService class Whatsapp::Providers::Whatsapp360DialogService < Whatsapp::Providers::BaseService
def send_message(phone_number, message) def send_message(phone_number, message)
@message = message
if message.attachments.present? if message.attachments.present?
send_attachment_message(phone_number, message) send_attachment_message(phone_number, message)
elsif message.content_type == 'input_select' elsif message.content_type == 'input_select'
@@ -79,7 +78,6 @@ class Whatsapp::Providers::Whatsapp360DialogService < Whatsapp::Providers::BaseS
} }
type_content['caption'] = message.content unless %w[audio sticker].include?(type) type_content['caption'] = message.content unless %w[audio sticker].include?(type)
type_content['filename'] = attachment.file.filename if type == 'document' type_content['filename'] = attachment.file.filename if type == 'document'
response = HTTParty.post( response = HTTParty.post(
"#{api_base_path}/messages", "#{api_base_path}/messages",
headers: api_headers, headers: api_headers,
@@ -93,9 +91,13 @@ class Whatsapp::Providers::Whatsapp360DialogService < Whatsapp::Providers::BaseS
process_response(response) process_response(response)
end end
def error_message(response) def process_response(response)
# {"meta": {"success": false, "http_code": 400, "developer_message": "errro-message", "360dialog_trace_id": "someid"}} if response.success?
response.parsed_response.dig('meta', 'developer_message') response['messages'].first['id']
else
Rails.logger.error response.body
nil
end
end end
def template_body_parameters(template_info) def template_body_parameters(template_info)
@@ -1,7 +1,5 @@
class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseService class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseService
def send_message(phone_number, message) def send_message(phone_number, message)
@message = message
if message.attachments.present? if message.attachments.present?
send_attachment_message(phone_number, message) send_attachment_message(phone_number, message)
elsif message.content_type == 'input_select' elsif message.content_type == 'input_select'
@@ -113,9 +111,13 @@ class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseServi
process_response(response) process_response(response)
end end
def error_message(response) def process_response(response)
# https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/#sample-response if response.success?
response.parsed_response&.dig('error', 'message') response['messages'].first['id']
else
Rails.logger.error response.body
nil
end
end end
def template_body_parameters(template_info) def template_body_parameters(template_info)
@@ -1,7 +1,3 @@
json.meta do
json.total_count @attachments_count
end
json.payload @attachments do |attachment| json.payload @attachments do |attachment|
json.message_id attachment.push_event_data[:message_id] json.message_id attachment.push_event_data[:message_id]
json.thumb_url attachment.push_event_data[:thumb_url] json.thumb_url attachment.push_event_data[:thumb_url]
-2
View File
@@ -68,8 +68,6 @@ am:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ar:
invalid_operator: مشغل غير صالح. المشغل المسموح به لـ %{attribute_name} هو [%{allowed_keys}]. invalid_operator: مشغل غير صالح. المشغل المسموح به لـ %{attribute_name} هو [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: قيمة غير صالحة. القيم المقدمة ل %{attribute_name} غير صالحة invalid_value: قيمة غير صالحة. القيم المقدمة ل %{attribute_name} غير صالحة
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: فترة التبليغ %{since} إلى %{until} period: فترة التبليغ %{since} إلى %{until}
utc_warning: التقرير الذي تم إنشاؤه في التوقيت العالمي الموحّد utc_warning: التقرير الذي تم إنشاؤه في التوقيت العالمي الموحّد
-2
View File
@@ -68,8 +68,6 @@ az:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ bg:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ca:
invalid_operator: Operador no vàlid. Els operadors permesos per a %{attribute_name} son [%{allowed_keys}]. invalid_operator: Operador no vàlid. Els operadors permesos per a %{attribute_name} son [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Valor no vàlid. Els valors proporcionats per a %{attribute_name} no són vàlids invalid_value: Valor no vàlid. Els valors proporcionats per a %{attribute_name} no són vàlids
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Període d'informes %{since} a %{until} period: Període d'informes %{since} a %{until}
utc_warning: L'informe generat es troba a la zona horària UTC utc_warning: L'informe generat es troba a la zona horària UTC
-2
View File
@@ -68,8 +68,6 @@ cs:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ da:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Rapporteringsperiode %{since} til %{until} period: Rapporteringsperiode %{since} til %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ de:
invalid_operator: Ungültiger Operator. Die erlaubten Operatoren für %{attribute_name} sind [%{allowed_keys}]. invalid_operator: Ungültiger Operator. Die erlaubten Operatoren für %{attribute_name} sind [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Ungültiger Wert. Die Werte für %{attribute_name} sind ungültig invalid_value: Ungültiger Wert. Die Werte für %{attribute_name} sind ungültig
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Berichtszeitraum von %{since} bis %{until} period: Berichtszeitraum von %{since} bis %{until}
utc_warning: Der generierte Bericht ist in UTC-Zeitzone utc_warning: Der generierte Bericht ist in UTC-Zeitzone
-2
View File
@@ -68,8 +68,6 @@ el:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Περίοδος αναφοράς %{since} έως %{until} period: Περίοδος αναφοράς %{since} έως %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ es:
invalid_operator: Operador no válido. Los operadores permitidos para %{attribute_name} son [%{allowed_keys}]. invalid_operator: Operador no válido. Los operadores permitidos para %{attribute_name} son [%{allowed_keys}].
invalid_query_operator: El operador de consulta debe ser "Y" o "O". invalid_query_operator: El operador de consulta debe ser "Y" o "O".
invalid_value: Valor no válido. Los valores proporcionados para %{attribute_name} no son válidos invalid_value: Valor no válido. Los valores proporcionados para %{attribute_name} no son válidos
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reportando el periodo desde %{since} hasta %{until} period: Reportando el periodo desde %{since} hasta %{until}
utc_warning: El informe generado está en zona horaria UTC utc_warning: El informe generado está en zona horaria UTC
-2
View File
@@ -68,8 +68,6 @@ fa:
invalid_operator: این عملیات مجاز نیست. عملیات های مجاز برای %{attribute_name} شامل %{allowed_keys} می باشد. invalid_operator: این عملیات مجاز نیست. عملیات های مجاز برای %{attribute_name} شامل %{allowed_keys} می باشد.
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: مقدار معتبر نیست. مقادیر ارائه شده برای %{attribute_name} معتبر نیست invalid_value: مقدار معتبر نیست. مقادیر ارائه شده برای %{attribute_name} معتبر نیست
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: زمان گزارش از %{since} تا %{until} period: زمان گزارش از %{since} تا %{until}
utc_warning: گزارش تولید شده در منطقه زمانی UTC است utc_warning: گزارش تولید شده در منطقه زمانی UTC است
-2
View File
@@ -68,8 +68,6 @@ fi:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Raportointijakso %{since} – %{until} period: Raportointijakso %{since} – %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ fr:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Période de rapport %{since} à %{until} period: Période de rapport %{since} à %{until}
utc_warning: Le rapport généré est dans le fuseau horaire UTC utc_warning: Le rapport généré est dans le fuseau horaire UTC
-2
View File
@@ -68,8 +68,6 @@ he:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ hi:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ hr:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ hu:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Jelentési időszak %{since}-tól %{until}-ig period: Jelentési időszak %{since}-tól %{until}-ig
utc_warning: A generált riport UTC időzónát használ utc_warning: A generált riport UTC időzónát használ
-2
View File
@@ -68,8 +68,6 @@ hy:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ id:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Periode pelaporan %{since} hingga %{until} period: Periode pelaporan %{since} hingga %{until}
utc_warning: Laporan yang dihasilkan berada dalam zona waktu UTC utc_warning: Laporan yang dihasilkan berada dalam zona waktu UTC
-2
View File
@@ -68,8 +68,6 @@ is:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ it:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Periodo di segnalazione da %{since} a %{until} period: Periodo di segnalazione da %{since} a %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ja:
invalid_operator: 無効な演算子です。%{attribute_name} に許可されている演算子は [%{allowed_keys}] です。 invalid_operator: 無効な演算子です。%{attribute_name} に許可されている演算子は [%{allowed_keys}] です。
invalid_query_operator: クエリ演算子は "AND" または "OR" でなければなりません。 invalid_query_operator: クエリ演算子は "AND" または "OR" でなければなりません。
invalid_value: 無効な値です。%{attribute_name} に提供された値は無効です。 invalid_value: 無効な値です。%{attribute_name} に提供された値は無効です。
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: レポート期間 %{since} から %{until} まで period: レポート期間 %{since} から %{until} まで
utc_warning: 生成されたレポートはUTCタイムゾーンです utc_warning: 生成されたレポートはUTCタイムゾーンです
-2
View File
@@ -68,8 +68,6 @@ ka:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ko:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: 보고 기간 %{since} - %{until} period: 보고 기간 %{since} - %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ lt:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Ataskaitinis laikotarpis nuo %{since} iki %{until} period: Ataskaitinis laikotarpis nuo %{since} iki %{until}
utc_warning: Sugeneruota ataskaita yra UTC laiko juostoje utc_warning: Sugeneruota ataskaita yra UTC laiko juostoje
-2
View File
@@ -68,8 +68,6 @@ lv:
invalid_operator: Nederīgs operators. Atļautie operatori priekš %{attribute_name} ir [%{allowed_keys}]. invalid_operator: Nederīgs operators. Atļautie operatori priekš %{attribute_name} ir [%{allowed_keys}].
invalid_query_operator: Vaicājuma operatoram ir jābūt "UN" vai "VAI". invalid_query_operator: Vaicājuma operatoram ir jābūt "UN" vai "VAI".
invalid_value: Nederīga vērtība. Norādītās vērtības priekš %{attribute_name} nav derīgas invalid_value: Nederīga vērtība. Norādītās vērtības priekš %{attribute_name} nav derīgas
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Ziņošanas periods %{since} līdz %{until} period: Ziņošanas periods %{since} līdz %{until}
utc_warning: Izveidotais pārskats atbilst UTC laika joslai utc_warning: Izveidotais pārskats atbilst UTC laika joslai
-2
View File
@@ -68,8 +68,6 @@ ml:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ms:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ne:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ nl:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Rapportering van %{since} tot %{until} period: Rapportering van %{since} tot %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@
invalid_operator: Ugyldig operatør. De tillatte operatørene for %{attribute_name} er [%{allowed_keys}]. invalid_operator: Ugyldig operatør. De tillatte operatørene for %{attribute_name} er [%{allowed_keys}].
invalid_query_operator: Spørrings-operatør må være enten "AND" eller "OR". invalid_query_operator: Spørrings-operatør må være enten "AND" eller "OR".
invalid_value: Ugyldig verdi. Verdiene angitt for %{attribute_name} er ugyldige invalid_value: Ugyldig verdi. Verdiene angitt for %{attribute_name} er ugyldige
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Rapporteringsperiode %{since} til %{until} period: Rapporteringsperiode %{since} til %{until}
utc_warning: Rapporten generert er i UTC tidssone utc_warning: Rapporten generert er i UTC tidssone
-2
View File
@@ -68,8 +68,6 @@ pl:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Okres raportowania od %{since} do %{until} period: Okres raportowania od %{since} do %{until}
utc_warning: Generowany raport jest w strefie czasowej UTC utc_warning: Generowany raport jest w strefie czasowej UTC
-2
View File
@@ -68,8 +68,6 @@ pt:
invalid_operator: Operador inválido. Os operadores permitidos para %{attribute_name} são [%{allowed_keys}]. invalid_operator: Operador inválido. Os operadores permitidos para %{attribute_name} são [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Valor inválido. Os valores fornecidos para %{attribute_name} são inválidos invalid_value: Valor inválido. Os valores fornecidos para %{attribute_name} são inválidos
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Período do relatório de %{since} a %{until} period: Período do relatório de %{since} a %{until}
utc_warning: O relatório gerado está no fuso horário UTC utc_warning: O relatório gerado está no fuso horário UTC
+1 -3
View File
@@ -68,8 +68,6 @@ pt_BR:
invalid_operator: Operador inválido. Os operadores permitidos para %{attribute_name} são [%{allowed_keys}]. invalid_operator: Operador inválido. Os operadores permitidos para %{attribute_name} são [%{allowed_keys}].
invalid_query_operator: Operador de consulta deve ser "E" ou "OU". invalid_query_operator: Operador de consulta deve ser "E" ou "OU".
invalid_value: Valor inválido. Os valores fornecidos para %{attribute_name} são inválidos invalid_value: Valor inválido. Os valores fornecidos para %{attribute_name} são inválidos
custom_attribute_definition:
key_conflict: A chave fornecida não é permitida pois pode entrar em conflito com os atributos padrão.
reports: reports:
period: Reportando o período %{since} a %{until} period: Reportando o período %{since} a %{until}
utc_warning: O relatório gerado está em fuso horário UTC utc_warning: O relatório gerado está em fuso horário UTC
@@ -135,7 +133,7 @@ pt_BR:
messages: messages:
instagram_story_content: '%{story_sender} mencionou você na conversa: ' instagram_story_content: '%{story_sender} mencionou você na conversa: '
instagram_deleted_story_content: Este Story não está mais disponível. instagram_deleted_story_content: Este Story não está mais disponível.
deleted: Esta mensagem foi excluída deleted: Esta mensagem foi apagada
delivery_status: delivery_status:
error_code: 'Código de erro: %{error_code}' error_code: 'Código de erro: %{error_code}'
activity: activity:
-2
View File
@@ -68,8 +68,6 @@ ro:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Perioada de raportare %{since}-%{until} period: Perioada de raportare %{since}-%{until}
utc_warning: Raportul generat este în fusul orar UTC utc_warning: Raportul generat este în fusul orar UTC
+3 -5
View File
@@ -68,8 +68,6 @@ ru:
invalid_operator: Неверный оператор. Допустимыми операторами для %{attribute_name} являются [%{allowed_keys}]. invalid_operator: Неверный оператор. Допустимыми операторами для %{attribute_name} являются [%{allowed_keys}].
invalid_query_operator: Оператор запроса должен быть "AND" или "OR". invalid_query_operator: Оператор запроса должен быть "AND" или "OR".
invalid_value: Недопустимое значение. Значения, предоставленные для %{attribute_name} являются недопустимыми invalid_value: Недопустимое значение. Значения, предоставленные для %{attribute_name} являются недопустимыми
custom_attribute_definition:
key_conflict: Предоставленный ключ не разрешён, так как он может конфликтовать со стандартными атрибутами.
reports: reports:
period: Отчётный период с %{since} по %{until} period: Отчётный период с %{since} по %{until}
utc_warning: Отчёт создан в часовом поясе UTC utc_warning: Отчёт создан в часовом поясе UTC
@@ -167,7 +165,7 @@ ru:
removed: '%{user_name} удалил политику SLA %{sla_name}' removed: '%{user_name} удалил политику SLA %{sla_name}'
muted: '%{user_name} заглушил(а) этот разговор' muted: '%{user_name} заглушил(а) этот разговор'
unmuted: '%{user_name} включил(а) уведомления для разговора' unmuted: '%{user_name} включил(а) уведомления для разговора'
auto_resolution_message: 'Разговор закрывается, поскольку он был неактивен в течение длительного времени. Пожалуйста, начните новый разговор, если потребуется дополнительная помощь.' auto_resolution_message: 'Resolving the conversation as it has been inactive for a while. Please start a new conversation if you need further assistance.'
templates: templates:
greeting_message_body: '%{account_name} как правило отвечает в течении несколько часов.' greeting_message_body: '%{account_name} как правило отвечает в течении несколько часов.'
ways_to_reach_you_message_body: 'Оставьте ваш email для связи' ways_to_reach_you_message_body: 'Оставьте ваш email для связи'
@@ -218,8 +216,8 @@ ru:
name: 'Linear' name: 'Linear'
description: 'Создавайте или прикрепляйте уже существующие задачи в Linear непосредственно из окна диалога для более упорядоченного и эффективного процесса отслеживания проблем.' description: 'Создавайте или прикрепляйте уже существующие задачи в Linear непосредственно из окна диалога для более упорядоченного и эффективного процесса отслеживания проблем.'
captain: captain:
copilot_error: 'Пожалуйста, подключите ассистента к этому источнику входящих для использования Copilot' copilot_error: 'Please connect an assistant to this inbox to use Copilot'
copilot_limit: 'У вас закончились кредиты для Copilot. Вы можете купить дополнительные кредиты в разделе биллинга.' copilot_limit: 'You are out of Copilot credits. You can buy more credits from the billing section.'
public_portal: public_portal:
search: search:
search_placeholder: Поиск статьи по названию или содержанию... search_placeholder: Поиск статьи по названию или содержанию...
-2
View File
@@ -68,8 +68,6 @@ sh:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ sk:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ sl:
invalid_operator: Neveljaven operater. Dovoljeni operaterji za %{attribute_name} so [%{allowed_keys}]. invalid_operator: Neveljaven operater. Dovoljeni operaterji za %{attribute_name} so [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Neveljavna vrednost. Podane vrednosti za %{attribute_name} so neveljavne invalid_value: Neveljavna vrednost. Podane vrednosti za %{attribute_name} so neveljavne
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Obdobje poročanja %{since} do %{until} period: Obdobje poročanja %{since} do %{until}
utc_warning: Ustvarjeno poročilo je v časovnem pasu UTC utc_warning: Ustvarjeno poročilo je v časovnem pasu UTC
-2
View File
@@ -68,8 +68,6 @@ sq:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ sr-Latn:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Period izveštaja %{since} do %{until} period: Period izveštaja %{since} do %{until}
utc_warning: Generisani izveštaj je u UTC vremenskoj zoni utc_warning: Generisani izveštaj je u UTC vremenskoj zoni
-2
View File
@@ -68,8 +68,6 @@ sv:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Rapporteringsperiod %{since} till %{until} period: Rapporteringsperiod %{since} till %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ta:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ th:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ tl:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ tr:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Raporlama aralığı %{since}'dan %{until}'a period: Raporlama aralığı %{since}'dan %{until}'a
utc_warning: Oluşturulan rapor UTC zaman dilimindedir. utc_warning: Oluşturulan rapor UTC zaman dilimindedir.
-2
View File
@@ -68,8 +68,6 @@ uk:
invalid_operator: Некоректний оператор. Дозволені оператори для %{attribute_name} є [%{allowed_keys}]. invalid_operator: Некоректний оператор. Дозволені оператори для %{attribute_name} є [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Невірне значення. Надані значення для %{attribute_name} є неприпустимі invalid_value: Невірне значення. Надані значення для %{attribute_name} є неприпустимі
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Період звіту %{since} до %{until} period: Період звіту %{since} до %{until}
utc_warning: Звіт створено в часовій зоні UTC utc_warning: Звіт створено в часовій зоні UTC
-2
View File
@@ -68,8 +68,6 @@ ur:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ ur:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
-2
View File
@@ -68,8 +68,6 @@ vi:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Thời gian báo cáo từ %{since} đến %{until} period: Thời gian báo cáo từ %{since} đến %{until}
utc_warning: Báo cáo đã được tạo với múi giờ UTC utc_warning: Báo cáo đã được tạo với múi giờ UTC
-2
View File
@@ -68,8 +68,6 @@ zh_CN:
invalid_operator: 无效的操作符。%{attribute_name} 允许的操作符为 [%{allowed_keys}]。 invalid_operator: 无效的操作符。%{attribute_name} 允许的操作符为 [%{allowed_keys}]。
invalid_query_operator: 查询操作符必须为 "AND" 或 "OR"。 invalid_query_operator: 查询操作符必须为 "AND" 或 "OR"。
invalid_value: 无效的值。为 %{attribute_name} 提供的值无效 invalid_value: 无效的值。为 %{attribute_name} 提供的值无效
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: 报告周期 %{since} 至 %{until} period: 报告周期 %{since} 至 %{until}
utc_warning: 生成的报表在 UTC 时区 utc_warning: 生成的报表在 UTC 时区
-2
View File
@@ -68,8 +68,6 @@ zh_TW:
invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}]. invalid_operator: Invalid operator. The allowed operators for %{attribute_name} are [%{allowed_keys}].
invalid_query_operator: Query operator must be either "AND" or "OR". invalid_query_operator: Query operator must be either "AND" or "OR".
invalid_value: Invalid value. The values provided for %{attribute_name} are invalid invalid_value: Invalid value. The values provided for %{attribute_name} are invalid
custom_attribute_definition:
key_conflict: The provided key is not allowed as it might conflict with default attributes.
reports: reports:
period: Reporting period %{since} to %{until} period: Reporting period %{since} to %{until}
utc_warning: The report generated is in UTC timezone utc_warning: The report generated is in UTC timezone
@@ -18,10 +18,6 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService
slack_client.chat_unfurl( slack_client.chat_unfurl(
event event
) )
# You may wonder why we're not requesting reauthorization and disabling hooks when scope errors occur.
# Since link unfurling is just a nice-to-have feature that doesn't affect core functionality, we will silently ignore these errors.
rescue Slack::Web::Api::Errors::MissingScope => e
Rails.logger.warn "Slack: Missing scope error: #{e.message}"
end end
private private

Some files were not shown because too many files have changed in this diff Show More