Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5688cc8f5 | ||
|
|
d028cc1984 | ||
|
|
0d59fb4459 | ||
|
|
7acbe8b3ff | ||
|
|
b791d75b30 | ||
|
|
36a05097fa | ||
|
|
0a181b0cea | ||
|
|
87df43bdd0 | ||
|
|
28f87d2fca | ||
|
|
37eed5de1e | ||
|
|
170b64d1f1 | ||
|
|
95cb3a7ad8 | ||
|
|
ecd9c26c8c | ||
|
|
88e2661ca6 | ||
|
|
33dea83716 | ||
|
|
4c6a345d60 | ||
|
|
04ac9d3780 | ||
|
|
1f6203d558 | ||
|
|
3eed8905cc | ||
|
|
f27bbef73b | ||
|
|
ed3059c1aa | ||
|
|
9d591b8f46 | ||
|
|
1afcd36dee | ||
|
|
a3ffb48a47 |
+5
-3
@@ -996,11 +996,13 @@ GEM
|
|||||||
activemodel (>= 3.2)
|
activemodel (>= 3.2)
|
||||||
mail (~> 2.5)
|
mail (~> 2.5)
|
||||||
version_gem (1.1.4)
|
version_gem (1.1.4)
|
||||||
vite_rails (3.0.17)
|
vite_rails (3.10.0)
|
||||||
railties (>= 5.1, < 8)
|
railties (>= 5.1, < 9)
|
||||||
vite_ruby (~> 3.0, >= 3.2.2)
|
vite_ruby (~> 3.0, >= 3.2.2)
|
||||||
vite_ruby (3.8.0)
|
vite_ruby (3.10.2)
|
||||||
dry-cli (>= 0.7, < 2)
|
dry-cli (>= 0.7, < 2)
|
||||||
|
logger (~> 1.6)
|
||||||
|
mutex_m
|
||||||
rack-proxy (~> 0.6, >= 0.6.1)
|
rack-proxy (~> 0.6, >= 0.6.1)
|
||||||
zeitwerk (~> 2.2)
|
zeitwerk (~> 2.2)
|
||||||
warden (1.2.9)
|
warden (1.2.9)
|
||||||
|
|||||||
@@ -92,10 +92,18 @@ class Messages::Facebook::MessageBuilder < Messages::Messenger::MessageBuilder
|
|||||||
def fallback_params(attachment)
|
def fallback_params(attachment)
|
||||||
{
|
{
|
||||||
fallback_title: attachment['title'],
|
fallback_title: attachment['title'],
|
||||||
external_url: attachment['url']
|
external_url: attachment['url'] || attachment.dig('payload', 'url')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Facebook shared posts point to page URLs, not downloadable media URLs.
|
||||||
|
# Keep this Facebook-only so Messenger/Instagram share attachments still use the parent media handling.
|
||||||
|
def normalize_file_type(type)
|
||||||
|
return :fallback if type.to_sym == :share
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
def conversation_params
|
def conversation_params
|
||||||
{
|
{
|
||||||
account_id: @inbox.account_id,
|
account_id: @inbox.account_id,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Messages::MessageBuilder
|
|||||||
@account = conversation.account
|
@account = conversation.account
|
||||||
@message_type = params[:message_type] || 'outgoing'
|
@message_type = params[:message_type] || 'outgoing'
|
||||||
@attachments = params[:attachments]
|
@attachments = params[:attachments]
|
||||||
|
@is_voice_message = ActiveModel::Type::Boolean.new.cast(params[:is_voice_message])
|
||||||
@automation_rule = content_attributes&.dig(:automation_rule_id)
|
@automation_rule = content_attributes&.dig(:automation_rule_id)
|
||||||
return unless params.instance_of?(ActionController::Parameters)
|
return unless params.instance_of?(ActionController::Parameters)
|
||||||
|
|
||||||
@@ -56,16 +57,25 @@ class Messages::MessageBuilder
|
|||||||
file: uploaded_attachment
|
file: uploaded_attachment
|
||||||
)
|
)
|
||||||
|
|
||||||
attachment.file_type = if uploaded_attachment.is_a?(String)
|
attachment.file_type = attachment_file_type(uploaded_attachment)
|
||||||
file_type_by_signed_id(
|
tag_voice_message(attachment)
|
||||||
uploaded_attachment
|
|
||||||
)
|
|
||||||
else
|
|
||||||
file_type(uploaded_attachment&.content_type)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attachment_file_type(uploaded_attachment)
|
||||||
|
if uploaded_attachment.is_a?(String)
|
||||||
|
file_type_by_signed_id(uploaded_attachment)
|
||||||
|
else
|
||||||
|
file_type(uploaded_attachment&.content_type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_voice_message(attachment)
|
||||||
|
return unless @is_voice_message && attachment.file_type == 'audio'
|
||||||
|
|
||||||
|
attachment.meta = (attachment.meta || {}).merge('is_voice_message' => true)
|
||||||
|
end
|
||||||
|
|
||||||
def process_emails
|
def process_emails
|
||||||
return unless @conversation.inbox&.inbox_type == 'Email'
|
return unless @conversation.inbox&.inbox_type == 'Email'
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Api::V1::Accounts::Instagram::AuthorizationsController < Api::V1::Accounts
|
|||||||
enable_fb_login: '0',
|
enable_fb_login: '0',
|
||||||
force_authentication: '1',
|
force_authentication: '1',
|
||||||
response_type: 'code',
|
response_type: 'code',
|
||||||
state: generate_instagram_token(Current.account.id)
|
state: generate_instagram_token(Current.account.id, params[:return_to])
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if redirect_url
|
if redirect_url
|
||||||
|
|||||||
@@ -8,7 +8,15 @@ class Api::V1::Accounts::OauthAuthorizationController < Api::V1::Accounts::BaseC
|
|||||||
end
|
end
|
||||||
|
|
||||||
def state
|
def state
|
||||||
Current.account.to_sgid(expires_in: 15.minutes).to_s
|
# The sgid purpose doubles as a return hint: onboarding tags it so the callback
|
||||||
|
# can route the user back to inbox setup. The purpose is part of the signed
|
||||||
|
# payload (tamper-proof), and a non-onboarding request keeps the default
|
||||||
|
# purpose, leaving callers like Notion byte-identical.
|
||||||
|
Current.account.to_sgid(expires_in: 15.minutes, for: state_purpose).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def state_purpose
|
||||||
|
params[:return_to] == 'onboarding' ? 'onboarding' : 'default'
|
||||||
end
|
end
|
||||||
|
|
||||||
def base_url
|
def base_url
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
class Api::V1::Accounts::OnboardingsController < Api::V1::Accounts::BaseController
|
||||||
|
before_action :check_admin_authorization?
|
||||||
|
|
||||||
|
def update
|
||||||
|
@account = Current.account
|
||||||
|
finalize = finalizing_account_details?
|
||||||
|
|
||||||
|
@account.assign_attributes(account_params)
|
||||||
|
@account.custom_attributes.merge!(custom_attributes_params)
|
||||||
|
@account.custom_attributes.delete('onboarding_step') if finalize
|
||||||
|
@account.save!
|
||||||
|
|
||||||
|
# TODO: re-enable when the help center generation UI is ready to surface progress
|
||||||
|
# Onboarding::HelpCenterCreationService.new(@account, Current.user).perform if finalize && website.present?
|
||||||
|
|
||||||
|
render 'api/v1/accounts/update', format: :json
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def finalizing_account_details?
|
||||||
|
@account.custom_attributes['onboarding_step'] == 'account_details'
|
||||||
|
end
|
||||||
|
|
||||||
|
def website
|
||||||
|
custom_attributes_params[:website]
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_params
|
||||||
|
params.permit(:name, :locale)
|
||||||
|
end
|
||||||
|
|
||||||
|
def custom_attributes_params
|
||||||
|
params.permit(:industry, :company_size, :timezone, :referral_source, :user_role, :website)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,7 +3,7 @@ class Api::V1::Accounts::Tiktok::AuthorizationsController < Api::V1::Accounts::O
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
redirect_url = Tiktok::AuthClient.authorize_url(
|
redirect_url = Tiktok::AuthClient.authorize_url(
|
||||||
state: generate_tiktok_token(Current.account.id)
|
state: generate_tiktok_token(Current.account.id, params[:return_to])
|
||||||
)
|
)
|
||||||
|
|
||||||
if redirect_url
|
if redirect_url
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ class Api::V1::AccountsController < Api::BaseController
|
|||||||
@account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email))
|
@account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email))
|
||||||
@account.custom_attributes.merge!(custom_attributes_params)
|
@account.custom_attributes.merge!(custom_attributes_params)
|
||||||
@account.settings.merge!(settings_params)
|
@account.settings.merge!(settings_params)
|
||||||
@account.custom_attributes.delete('onboarding_step') if @account.custom_attributes['onboarding_step'] == 'account_details'
|
|
||||||
@account.custom_attributes['onboarding_step'] = 'invite_team' if @account.custom_attributes['onboarding_step'] == 'account_update'
|
@account.custom_attributes['onboarding_step'] = 'invite_team' if @account.custom_attributes['onboarding_step'] == 'account_update'
|
||||||
@account.save!
|
@account.save!
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class Instagram::CallbacksController < ApplicationController
|
|||||||
@long_lived_token_response = exchange_for_long_lived_token(@response.token)
|
@long_lived_token_response = exchange_for_long_lived_token(@response.token)
|
||||||
inbox, already_exists = find_or_create_inbox
|
inbox, already_exists = find_or_create_inbox
|
||||||
|
|
||||||
|
return redirect_to app_onboarding_inbox_setup_url(account_id: account_id) if return_to == 'onboarding'
|
||||||
|
|
||||||
if already_exists
|
if already_exists
|
||||||
redirect_to app_instagram_inbox_settings_url(account_id: account_id, inbox_id: inbox.id)
|
redirect_to app_instagram_inbox_settings_url(account_id: account_id, inbox_id: inbox.id)
|
||||||
else
|
else
|
||||||
@@ -149,6 +151,10 @@ class Instagram::CallbacksController < ApplicationController
|
|||||||
verify_instagram_token(params[:state])
|
verify_instagram_token(params[:state])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def return_to
|
||||||
|
instagram_token_return_to(params[:state])
|
||||||
|
end
|
||||||
|
|
||||||
def oauth_code
|
def oauth_code
|
||||||
params[:code]
|
params[:code]
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,4 +14,11 @@ class Microsoft::CallbacksController < OauthCallbackController
|
|||||||
def imap_address
|
def imap_address
|
||||||
'outlook.office365.com'
|
'outlook.office365.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Exchange Online's SMTP AUTH (XOAUTH2) rejects proxy addresses in the SASL `user=` field;
|
||||||
|
# it must match the token's UPN. `preferred_username` is the documented v2.0 claim;
|
||||||
|
# `upn` is the v1.0 fallback.
|
||||||
|
def imap_login_identity
|
||||||
|
users_data['preferred_username'] || users_data['upn'] || super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ class OauthCallbackController < ApplicationController
|
|||||||
def handle_response
|
def handle_response
|
||||||
inbox, already_exists = find_or_create_inbox
|
inbox, already_exists = find_or_create_inbox
|
||||||
|
|
||||||
|
return redirect_to app_onboarding_inbox_setup_url(account_id: account.id) if return_to == 'onboarding'
|
||||||
|
|
||||||
if already_exists
|
if already_exists
|
||||||
redirect_to app_email_inbox_settings_url(account_id: account.id, inbox_id: inbox.id)
|
redirect_to app_email_inbox_settings_url(account_id: account.id, inbox_id: inbox.id)
|
||||||
else
|
else
|
||||||
@@ -44,7 +46,7 @@ class OauthCallbackController < ApplicationController
|
|||||||
|
|
||||||
def update_channel(channel_email)
|
def update_channel(channel_email)
|
||||||
channel_email.update!({
|
channel_email.update!({
|
||||||
imap_login: users_data['email'], imap_address: imap_address,
|
imap_login: imap_login_identity, imap_address: imap_address,
|
||||||
imap_port: '993', imap_enabled: true,
|
imap_port: '993', imap_enabled: true,
|
||||||
provider: provider_name,
|
provider: provider_name,
|
||||||
provider_config: {
|
provider_config: {
|
||||||
@@ -55,6 +57,13 @@ class OauthCallbackController < ApplicationController
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Identity used as the IMAP/SMTP login (SASL XOAUTH2 `user=` field). Defaults to the
|
||||||
|
# id_token's email claim; providers override when their server requires a different
|
||||||
|
# claim (e.g. Microsoft SMTP requires UPN).
|
||||||
|
def imap_login_identity
|
||||||
|
users_data['email']
|
||||||
|
end
|
||||||
|
|
||||||
def provider_name
|
def provider_name
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
@@ -81,10 +90,19 @@ class OauthCallbackController < ApplicationController
|
|||||||
decoded_token[0]
|
decoded_token[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The sgid purpose carries the onboarding return hint (see
|
||||||
|
# OauthAuthorizationController#state). Try the onboarding purpose first — a match
|
||||||
|
# both resolves the account and records the return target — then fall back to the
|
||||||
|
# default purpose used by every other caller.
|
||||||
def account_from_signed_id
|
def account_from_signed_id
|
||||||
raise ActionController::BadRequest, 'Missing state variable' if params[:state].blank?
|
raise ActionController::BadRequest, 'Missing state variable' if params[:state].blank?
|
||||||
|
|
||||||
account = GlobalID::Locator.locate_signed(params[:state])
|
if (account = GlobalID::Locator.locate_signed(params[:state], for: 'onboarding'))
|
||||||
|
@return_to = 'onboarding'
|
||||||
|
else
|
||||||
|
account = GlobalID::Locator.locate_signed(params[:state])
|
||||||
|
end
|
||||||
|
|
||||||
raise 'Invalid or expired state' if account.nil?
|
raise 'Invalid or expired state' if account.nil?
|
||||||
|
|
||||||
account
|
account
|
||||||
@@ -94,6 +112,11 @@ class OauthCallbackController < ApplicationController
|
|||||||
@account ||= account_from_signed_id
|
@account ||= account_from_signed_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def return_to
|
||||||
|
account # resolving the sgid records which purpose matched
|
||||||
|
@return_to
|
||||||
|
end
|
||||||
|
|
||||||
# Fallback name, for when name field is missing from users_data
|
# Fallback name, for when name field is missing from users_data
|
||||||
def fallback_name
|
def fallback_name
|
||||||
users_data['email'].split('@').first.parameterize.titleize
|
users_data['email'].split('@').first.parameterize.titleize
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
class Public::Api::V1::Portals::SearchController < Public::Api::V1::Portals::BaseController
|
||||||
|
before_action :ensure_custom_domain_request, only: [:index]
|
||||||
|
before_action :portal
|
||||||
|
before_action :set_portal_layout
|
||||||
|
before_action :set_view_variant
|
||||||
|
before_action :ensure_portal_feature_enabled
|
||||||
|
layout 'portal'
|
||||||
|
|
||||||
|
def index
|
||||||
|
@query = params[:query].to_s.strip
|
||||||
|
@articles = @portal.articles.published.includes(:category).where(locale: params[:locale])
|
||||||
|
|
||||||
|
search_articles
|
||||||
|
|
||||||
|
@articles = @articles.page(params[:page]).per(10)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def search_articles
|
||||||
|
@articles = @query.present? ? @articles.search(search_params) : @articles.none
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_params
|
||||||
|
params.permit(:query, :locale, :sort, :status, :page).tap do |permitted|
|
||||||
|
permitted[:query] = @query
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Public::Api::V1::Portals::SearchController.prepend_mod_with('Public::Api::V1::Portals::SearchController')
|
||||||
@@ -20,6 +20,8 @@ class Tiktok::CallbacksController < ApplicationController
|
|||||||
def process_successful_authorization
|
def process_successful_authorization
|
||||||
inbox, already_exists = find_or_create_inbox
|
inbox, already_exists = find_or_create_inbox
|
||||||
|
|
||||||
|
return redirect_to app_onboarding_inbox_setup_url(account_id: account_id) if return_to == 'onboarding'
|
||||||
|
|
||||||
if already_exists
|
if already_exists
|
||||||
redirect_to app_tiktok_inbox_settings_url(account_id: account_id, inbox_id: inbox.id)
|
redirect_to app_tiktok_inbox_settings_url(account_id: account_id, inbox_id: inbox.id)
|
||||||
else
|
else
|
||||||
@@ -127,6 +129,10 @@ class Tiktok::CallbacksController < ApplicationController
|
|||||||
@account_id ||= verify_tiktok_token(params[:state])
|
@account_id ||= verify_tiktok_token(params[:state])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def return_to
|
||||||
|
tiktok_token_return_to(params[:state])
|
||||||
|
end
|
||||||
|
|
||||||
def account
|
def account
|
||||||
@account ||= Account.find(account_id)
|
@account ||= Account.find(account_id)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ module Instagram::IntegrationHelper
|
|||||||
# Generates a signed JWT token for Instagram integration
|
# Generates a signed JWT token for Instagram integration
|
||||||
#
|
#
|
||||||
# @param account_id [Integer] The account ID to encode in the token
|
# @param account_id [Integer] The account ID to encode in the token
|
||||||
|
# @param return_to [String, nil] Optional onboarding return hint
|
||||||
# @return [String, nil] The encoded JWT token or nil if client secret is missing
|
# @return [String, nil] The encoded JWT token or nil if client secret is missing
|
||||||
def generate_instagram_token(account_id)
|
def generate_instagram_token(account_id, return_to = nil)
|
||||||
return if client_secret.blank?
|
return if client_secret.blank?
|
||||||
|
|
||||||
JWT.encode(token_payload(account_id), client_secret, 'HS256')
|
JWT.encode(token_payload(account_id, return_to), client_secret, 'HS256')
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("Failed to generate Instagram token: #{e.message}")
|
Rails.logger.error("Failed to generate Instagram token: #{e.message}")
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def token_payload(account_id)
|
def token_payload(account_id, return_to = nil)
|
||||||
{
|
payload = { sub: account_id, iat: Time.current.to_i }
|
||||||
sub: account_id,
|
payload[:return_to] = return_to if return_to.present?
|
||||||
iat: Time.current.to_i
|
payload
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Verifies and decodes a Instagram JWT token
|
# Verifies and decodes a Instagram JWT token
|
||||||
@@ -28,7 +28,14 @@ module Instagram::IntegrationHelper
|
|||||||
def verify_instagram_token(token)
|
def verify_instagram_token(token)
|
||||||
return if token.blank? || client_secret.blank?
|
return if token.blank? || client_secret.blank?
|
||||||
|
|
||||||
decode_token(token, client_secret)
|
decode_token(token, client_secret)&.dig('sub')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Reads the onboarding return hint from a Instagram JWT token, if present.
|
||||||
|
def instagram_token_return_to(token)
|
||||||
|
return if token.blank? || client_secret.blank?
|
||||||
|
|
||||||
|
decode_token(token, client_secret)&.dig('return_to')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -41,7 +48,7 @@ module Instagram::IntegrationHelper
|
|||||||
JWT.decode(token, secret, true, {
|
JWT.decode(token, secret, true, {
|
||||||
algorithm: 'HS256',
|
algorithm: 'HS256',
|
||||||
verify_expiration: true
|
verify_expiration: true
|
||||||
}).first['sub']
|
}).first
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("Unexpected error verifying Instagram token: #{e.message}")
|
Rails.logger.error("Unexpected error verifying Instagram token: #{e.message}")
|
||||||
nil
|
nil
|
||||||
|
|||||||
@@ -45,9 +45,16 @@ module PortalHelper
|
|||||||
theme.present? && theme != 'system' ? "?theme=#{theme}" : ''
|
theme.present? && theme != 'system' ? "?theme=#{theme}" : ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def portal_query_string(theme, is_plain_layout_enabled)
|
||||||
|
query_params = {}
|
||||||
|
query_params[:theme] = theme if theme.present? && theme != 'system'
|
||||||
|
query_params[:show_plain_layout] = true if is_plain_layout_enabled
|
||||||
|
query_params.present? ? "?#{query_params.to_query}" : ''
|
||||||
|
end
|
||||||
|
|
||||||
def generate_home_link(portal_slug, portal_locale, theme, is_plain_layout_enabled)
|
def generate_home_link(portal_slug, portal_locale, theme, is_plain_layout_enabled)
|
||||||
if is_plain_layout_enabled
|
if is_plain_layout_enabled
|
||||||
"/hc/#{portal_slug}/#{portal_locale}#{theme_query_string(theme)}"
|
"/hc/#{portal_slug}/#{portal_locale}#{portal_query_string(theme, is_plain_layout_enabled)}"
|
||||||
else
|
else
|
||||||
"/hc/#{portal_slug}/#{portal_locale}"
|
"/hc/#{portal_slug}/#{portal_locale}"
|
||||||
end
|
end
|
||||||
@@ -61,7 +68,7 @@ module PortalHelper
|
|||||||
is_plain_layout_enabled = params[:is_plain_layout_enabled]
|
is_plain_layout_enabled = params[:is_plain_layout_enabled]
|
||||||
|
|
||||||
if is_plain_layout_enabled
|
if is_plain_layout_enabled
|
||||||
"/hc/#{portal_slug}/#{category_locale}/categories/#{category_slug}#{theme_query_string(theme)}"
|
"/hc/#{portal_slug}/#{category_locale}/categories/#{category_slug}#{portal_query_string(theme, is_plain_layout_enabled)}"
|
||||||
else
|
else
|
||||||
"/hc/#{portal_slug}/#{category_locale}/categories/#{category_slug}"
|
"/hc/#{portal_slug}/#{category_locale}/categories/#{category_slug}"
|
||||||
end
|
end
|
||||||
@@ -69,7 +76,7 @@ module PortalHelper
|
|||||||
|
|
||||||
def generate_article_link(portal_slug, article_slug, theme, is_plain_layout_enabled)
|
def generate_article_link(portal_slug, article_slug, theme, is_plain_layout_enabled)
|
||||||
if is_plain_layout_enabled
|
if is_plain_layout_enabled
|
||||||
"/hc/#{portal_slug}/articles/#{article_slug}#{theme_query_string(theme)}"
|
"/hc/#{portal_slug}/articles/#{article_slug}#{portal_query_string(theme, is_plain_layout_enabled)}"
|
||||||
else
|
else
|
||||||
"/hc/#{portal_slug}/articles/#{article_slug}"
|
"/hc/#{portal_slug}/articles/#{article_slug}"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ module Tiktok::IntegrationHelper
|
|||||||
# Generates a signed JWT token for Tiktok integration
|
# Generates a signed JWT token for Tiktok integration
|
||||||
#
|
#
|
||||||
# @param account_id [Integer] The account ID to encode in the token
|
# @param account_id [Integer] The account ID to encode in the token
|
||||||
|
# @param return_to [String, nil] Optional onboarding return hint
|
||||||
# @return [String, nil] The encoded JWT token or nil if client secret is missing
|
# @return [String, nil] The encoded JWT token or nil if client secret is missing
|
||||||
def generate_tiktok_token(account_id)
|
def generate_tiktok_token(account_id, return_to = nil)
|
||||||
return if client_secret.blank?
|
return if client_secret.blank?
|
||||||
|
|
||||||
JWT.encode(token_payload(account_id), client_secret, 'HS256')
|
JWT.encode(token_payload(account_id, return_to), client_secret, 'HS256')
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("Failed to generate TikTok token: #{e.message}")
|
Rails.logger.error("Failed to generate TikTok token: #{e.message}")
|
||||||
nil
|
nil
|
||||||
@@ -19,7 +20,14 @@ module Tiktok::IntegrationHelper
|
|||||||
def verify_tiktok_token(token)
|
def verify_tiktok_token(token)
|
||||||
return if token.blank? || client_secret.blank?
|
return if token.blank? || client_secret.blank?
|
||||||
|
|
||||||
decode_token(token, client_secret)
|
decode_token(token, client_secret)&.dig('sub')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Reads the onboarding return hint from a Tiktok JWT token, if present.
|
||||||
|
def tiktok_token_return_to(token)
|
||||||
|
return if token.blank? || client_secret.blank?
|
||||||
|
|
||||||
|
decode_token(token, client_secret)&.dig('return_to')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -28,18 +36,17 @@ module Tiktok::IntegrationHelper
|
|||||||
@client_secret ||= GlobalConfigService.load('TIKTOK_APP_SECRET', nil)
|
@client_secret ||= GlobalConfigService.load('TIKTOK_APP_SECRET', nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def token_payload(account_id)
|
def token_payload(account_id, return_to = nil)
|
||||||
{
|
payload = { sub: account_id, iat: Time.current.to_i }
|
||||||
sub: account_id,
|
payload[:return_to] = return_to if return_to.present?
|
||||||
iat: Time.current.to_i
|
payload
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode_token(token, secret)
|
def decode_token(token, secret)
|
||||||
JWT.decode(token, secret, true, {
|
JWT.decode(token, secret, true, {
|
||||||
algorithm: 'HS256',
|
algorithm: 'HS256',
|
||||||
verify_expiration: true
|
verify_expiration: true
|
||||||
}).first['sub']
|
}).first
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("Unexpected error verifying Tiktok token: #{e.message}")
|
Rails.logger.error("Unexpected error verifying Tiktok token: #{e.message}")
|
||||||
nil
|
nil
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export const buildCreatePayload = ({
|
|||||||
bccEmails = '',
|
bccEmails = '',
|
||||||
toEmails = '',
|
toEmails = '',
|
||||||
templateParams,
|
templateParams,
|
||||||
|
isVoiceMessage = false,
|
||||||
}) => {
|
}) => {
|
||||||
let payload;
|
let payload;
|
||||||
if (files && files.length !== 0) {
|
if (files && files.length !== 0) {
|
||||||
@@ -33,6 +34,9 @@ export const buildCreatePayload = ({
|
|||||||
if (contentAttributes) {
|
if (contentAttributes) {
|
||||||
payload.append('content_attributes', JSON.stringify(contentAttributes));
|
payload.append('content_attributes', JSON.stringify(contentAttributes));
|
||||||
}
|
}
|
||||||
|
if (isVoiceMessage) {
|
||||||
|
payload.append('is_voice_message', true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
payload = {
|
payload = {
|
||||||
content: message,
|
content: message,
|
||||||
@@ -64,6 +68,7 @@ class MessageApi extends ApiClient {
|
|||||||
bccEmails = '',
|
bccEmails = '',
|
||||||
toEmails = '',
|
toEmails = '',
|
||||||
templateParams,
|
templateParams,
|
||||||
|
isVoiceMessage = false,
|
||||||
}) {
|
}) {
|
||||||
return axios({
|
return axios({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -78,6 +83,7 @@ class MessageApi extends ApiClient {
|
|||||||
bccEmails,
|
bccEmails,
|
||||||
toEmails,
|
toEmails,
|
||||||
templateParams,
|
templateParams,
|
||||||
|
isVoiceMessage,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/* global axios */
|
||||||
|
import ApiClient from './ApiClient';
|
||||||
|
|
||||||
|
class OnboardingAPI extends ApiClient {
|
||||||
|
constructor() {
|
||||||
|
super('onboarding', { accountScoped: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
update(data) {
|
||||||
|
return axios.patch(this.url, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new OnboardingAPI();
|
||||||
@@ -83,5 +83,29 @@ describe('#ConversationAPI', () => {
|
|||||||
template_params: undefined,
|
template_params: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('appends is_voice_message when isVoiceMessage is true', () => {
|
||||||
|
const formPayload = buildCreatePayload({
|
||||||
|
message: 'voice message',
|
||||||
|
echoId: 42,
|
||||||
|
isPrivate: false,
|
||||||
|
files: [new Blob(['audio-data'], { type: 'audio/ogg' })],
|
||||||
|
isVoiceMessage: true,
|
||||||
|
});
|
||||||
|
expect(formPayload).toBeInstanceOf(FormData);
|
||||||
|
expect(formPayload.get('is_voice_message')).toEqual('true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not append is_voice_message when isVoiceMessage is false', () => {
|
||||||
|
const formPayload = buildCreatePayload({
|
||||||
|
message: 'regular audio',
|
||||||
|
echoId: 43,
|
||||||
|
isPrivate: false,
|
||||||
|
files: [new Blob(['audio-data'], { type: 'audio/ogg' })],
|
||||||
|
isVoiceMessage: false,
|
||||||
|
});
|
||||||
|
expect(formPayload).toBeInstanceOf(FormData);
|
||||||
|
expect(formPayload.get('is_voice_message')).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ const emit = defineEmits(['edit', 'delete']);
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const STATUS_COMPLETED = 'completed';
|
const STATUS_COMPLETED = 'completed';
|
||||||
|
const STATUS_PROCESSING = 'processing';
|
||||||
|
|
||||||
const { formatMessage } = useMessageFormatter();
|
const { formatMessage } = useMessageFormatter();
|
||||||
|
|
||||||
@@ -68,9 +69,15 @@ const campaignStatus = computed(() => {
|
|||||||
: t('CAMPAIGN.LIVE_CHAT.CARD.STATUS.DISABLED');
|
: t('CAMPAIGN.LIVE_CHAT.CARD.STATUS.DISABLED');
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.status === STATUS_COMPLETED
|
if (props.status === STATUS_COMPLETED) {
|
||||||
? t('CAMPAIGN.SMS.CARD.STATUS.COMPLETED')
|
return t('CAMPAIGN.SMS.CARD.STATUS.COMPLETED');
|
||||||
: t('CAMPAIGN.SMS.CARD.STATUS.SCHEDULED');
|
}
|
||||||
|
|
||||||
|
if (props.status === STATUS_PROCESSING) {
|
||||||
|
return t('CAMPAIGN.SMS.CARD.STATUS.PROCESSING');
|
||||||
|
}
|
||||||
|
|
||||||
|
return t('CAMPAIGN.SMS.CARD.STATUS.SCHEDULED');
|
||||||
});
|
});
|
||||||
|
|
||||||
const inboxName = computed(() => props.inbox?.name || '');
|
const inboxName = computed(() => props.inbox?.name || '');
|
||||||
|
|||||||
+29
-15
@@ -1,34 +1,48 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import Button from 'dashboard/components-next/button/Button.vue';
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
|
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
|
||||||
|
import { usePolicy } from 'dashboard/composables/usePolicy';
|
||||||
|
|
||||||
const emit = defineEmits(['add', 'import', 'export']);
|
const emit = defineEmits(['add', 'import', 'export']);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { checkPermissions } = usePolicy();
|
||||||
|
|
||||||
const contactMenuItems = [
|
const contactMenuItems = computed(() => [
|
||||||
{
|
{
|
||||||
label: t('CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.ADD_CONTACT'),
|
label: t('CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.ADD_CONTACT'),
|
||||||
action: 'add',
|
action: 'add',
|
||||||
value: 'add',
|
value: 'add',
|
||||||
icon: 'i-lucide-plus',
|
icon: 'i-lucide-plus',
|
||||||
},
|
},
|
||||||
{
|
...(checkPermissions(['administrator', 'contact_manage'])
|
||||||
label: t('CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.EXPORT_CONTACT'),
|
? [
|
||||||
action: 'export',
|
{
|
||||||
value: 'export',
|
label: t(
|
||||||
icon: 'i-lucide-upload',
|
'CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.EXPORT_CONTACT'
|
||||||
},
|
),
|
||||||
{
|
action: 'export',
|
||||||
label: t('CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.IMPORT_CONTACT'),
|
value: 'export',
|
||||||
action: 'import',
|
icon: 'i-lucide-upload',
|
||||||
value: 'import',
|
},
|
||||||
icon: 'i-lucide-download',
|
]
|
||||||
},
|
: []),
|
||||||
];
|
...(checkPermissions(['administrator', 'contact_manage'])
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: t(
|
||||||
|
'CONTACTS_LAYOUT.HEADER.ACTIONS.CONTACT_CREATION.IMPORT_CONTACT'
|
||||||
|
),
|
||||||
|
action: 'import',
|
||||||
|
value: 'import',
|
||||||
|
icon: 'i-lucide-download',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
]);
|
||||||
const showActionsDropdown = ref(false);
|
const showActionsDropdown = ref(false);
|
||||||
|
|
||||||
const handleContactAction = ({ action }) => {
|
const handleContactAction = ({ action }) => {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import FileBubble from './bubbles/File.vue';
|
|||||||
import AudioBubble from './bubbles/Audio.vue';
|
import AudioBubble from './bubbles/Audio.vue';
|
||||||
import VideoBubble from './bubbles/Video.vue';
|
import VideoBubble from './bubbles/Video.vue';
|
||||||
import EmbedBubble from './bubbles/Embed.vue';
|
import EmbedBubble from './bubbles/Embed.vue';
|
||||||
|
import FallbackBubble from './bubbles/Fallback.vue';
|
||||||
import InstagramStoryBubble from './bubbles/InstagramStory.vue';
|
import InstagramStoryBubble from './bubbles/InstagramStory.vue';
|
||||||
import EmailBubble from './bubbles/Email/Index.vue';
|
import EmailBubble from './bubbles/Email/Index.vue';
|
||||||
import UnsupportedBubble from './bubbles/Unsupported.vue';
|
import UnsupportedBubble from './bubbles/Unsupported.vue';
|
||||||
@@ -328,6 +329,8 @@ const componentToRender = computed(() => {
|
|||||||
if (Array.isArray(props.attachments) && props.attachments.length === 1) {
|
if (Array.isArray(props.attachments) && props.attachments.length === 1) {
|
||||||
const fileType = props.attachments[0].fileType;
|
const fileType = props.attachments[0].fileType;
|
||||||
|
|
||||||
|
if (fileType === ATTACHMENT_TYPES.FALLBACK) return FallbackBubble;
|
||||||
|
|
||||||
if (!props.content) {
|
if (!props.content) {
|
||||||
if (fileType === ATTACHMENT_TYPES.IMAGE) return ImageBubble;
|
if (fileType === ATTACHMENT_TYPES.IMAGE) return ImageBubble;
|
||||||
if (fileType === ATTACHMENT_TYPES.FILE) return FileBubble;
|
if (fileType === ATTACHMENT_TYPES.FILE) return FileBubble;
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import BaseBubble from './Base.vue';
|
||||||
|
import FormattedContent from './Text/FormattedContent.vue';
|
||||||
|
import { useMessageContext } from '../provider.js';
|
||||||
|
|
||||||
|
const { attachments, content } = useMessageContext();
|
||||||
|
|
||||||
|
const attachment = computed(() => attachments.value?.[0] || {});
|
||||||
|
const url = computed(
|
||||||
|
() => attachment.value.dataUrl || attachment.value.data_url
|
||||||
|
);
|
||||||
|
const title = computed(
|
||||||
|
() =>
|
||||||
|
attachment.value.fallbackTitle ||
|
||||||
|
attachment.value.fallback_title ||
|
||||||
|
url.value
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BaseBubble class="p-3" data-bubble-name="fallback">
|
||||||
|
<FormattedContent v-if="content" :content="content" class="mb-2" />
|
||||||
|
<a
|
||||||
|
v-if="url"
|
||||||
|
:href="url"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="block max-w-[320px] truncate text-sm text-n-brand underline"
|
||||||
|
>
|
||||||
|
{{ title }}
|
||||||
|
</a>
|
||||||
|
<span v-else class="text-sm text-n-slate-11">
|
||||||
|
{{ title }}
|
||||||
|
</span>
|
||||||
|
</BaseBubble>
|
||||||
|
</template>
|
||||||
@@ -14,11 +14,11 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['removeAttachment']);
|
const emit = defineEmits(['removeAttachment']);
|
||||||
|
|
||||||
const nonRecordedAudioAttachments = computed(() => {
|
const nonRecordedAudioAttachments = computed(() => {
|
||||||
return props.attachments.filter(attachment => !attachment?.isRecordedAudio);
|
return props.attachments.filter(attachment => !attachment?.isVoiceMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
const recordedAudioAttachments = computed(() =>
|
const recordedAudioAttachments = computed(() =>
|
||||||
props.attachments.filter(attachment => attachment.isRecordedAudio)
|
props.attachments.filter(attachment => attachment.isVoiceMessage)
|
||||||
);
|
);
|
||||||
|
|
||||||
const onRemoveAttachment = itemIndex => {
|
const onRemoveAttachment = itemIndex => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { ref, onMounted, onUnmounted } from 'vue';
|
|||||||
import WaveSurfer from 'wavesurfer.js';
|
import WaveSurfer from 'wavesurfer.js';
|
||||||
import RecordPlugin from 'wavesurfer.js/dist/plugins/record.js';
|
import RecordPlugin from 'wavesurfer.js/dist/plugins/record.js';
|
||||||
import { format, intervalToDuration } from 'date-fns';
|
import { format, intervalToDuration } from 'date-fns';
|
||||||
import { convertAudio } from './utils/mp3ConversionUtils';
|
import { convertAudio } from './utils/audioConversionUtils';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
audioRecordFormat: {
|
audioRecordFormat: {
|
||||||
@@ -18,6 +18,7 @@ const emit = defineEmits([
|
|||||||
'finishRecord',
|
'finishRecord',
|
||||||
'pause',
|
'pause',
|
||||||
'play',
|
'play',
|
||||||
|
'recordError',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const waveformContainer = ref(null);
|
const waveformContainer = ref(null);
|
||||||
@@ -26,6 +27,7 @@ const record = ref(null);
|
|||||||
const isRecording = ref(false);
|
const isRecording = ref(false);
|
||||||
const isPlaying = ref(false);
|
const isPlaying = ref(false);
|
||||||
const hasRecording = ref(false);
|
const hasRecording = ref(false);
|
||||||
|
const recordedAudioUrl = ref(null);
|
||||||
|
|
||||||
const formatTimeProgress = time => {
|
const formatTimeProgress = time => {
|
||||||
const duration = intervalToDuration({ start: 0, end: time });
|
const duration = intervalToDuration({ start: 0, end: time });
|
||||||
@@ -35,6 +37,28 @@ const formatTimeProgress = time => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AUDIO_EXTENSION_MAP = {
|
||||||
|
'audio/ogg': 'ogg',
|
||||||
|
'audio/mp3': 'mp3',
|
||||||
|
'audio/mpeg': 'mp3',
|
||||||
|
'audio/wav': 'wav',
|
||||||
|
'audio/webm': 'webm',
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRecordPluginOptions = audioFormat => {
|
||||||
|
const options = {
|
||||||
|
scrollingWaveform: true,
|
||||||
|
renderRecordedAudio: false,
|
||||||
|
};
|
||||||
|
if (
|
||||||
|
audioFormat === 'audio/ogg' &&
|
||||||
|
MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')
|
||||||
|
) {
|
||||||
|
options.mimeType = 'audio/ogg;codecs=opus';
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
const initWaveSurfer = () => {
|
const initWaveSurfer = () => {
|
||||||
wavesurfer.value = WaveSurfer.create({
|
wavesurfer.value = WaveSurfer.create({
|
||||||
container: waveformContainer.value,
|
container: waveformContainer.value,
|
||||||
@@ -45,10 +69,7 @@ const initWaveSurfer = () => {
|
|||||||
barGap: 1,
|
barGap: 1,
|
||||||
barRadius: 2,
|
barRadius: 2,
|
||||||
plugins: [
|
plugins: [
|
||||||
RecordPlugin.create({
|
RecordPlugin.create(getRecordPluginOptions(props.audioRecordFormat)),
|
||||||
scrollingWaveform: true,
|
|
||||||
renderRecordedAudio: false,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -62,21 +83,34 @@ const initWaveSurfer = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
record.value.on('record-end', async blob => {
|
record.value.on('record-end', async blob => {
|
||||||
const audioUrl = URL.createObjectURL(blob);
|
try {
|
||||||
const audioBlob = await convertAudio(blob, props.audioRecordFormat);
|
const audioBlob = await convertAudio(blob, props.audioRecordFormat);
|
||||||
const fileName = `${getUuid()}.mp3`;
|
// Use the converted blob's actual type, which may differ from the
|
||||||
const file = new File([audioBlob], fileName, {
|
// requested format when the browser can't produce it (e.g. Safari falls
|
||||||
type: props.audioRecordFormat,
|
// back to MP3 instead of OGG). This keeps the filename, content type, and
|
||||||
});
|
// voice-note flag consistent with the real bytes.
|
||||||
wavesurfer.value.load(audioUrl);
|
const audioType = audioBlob.type || props.audioRecordFormat;
|
||||||
emit('finishRecord', {
|
const ext = AUDIO_EXTENSION_MAP[audioType] || 'mp3';
|
||||||
name: file.name,
|
const fileName = `${getUuid()}.${ext}`;
|
||||||
type: file.type,
|
const file = new File([audioBlob], fileName, {
|
||||||
size: file.size,
|
type: audioType,
|
||||||
file,
|
});
|
||||||
});
|
if (recordedAudioUrl.value) URL.revokeObjectURL(recordedAudioUrl.value);
|
||||||
hasRecording.value = true;
|
recordedAudioUrl.value = URL.createObjectURL(audioBlob);
|
||||||
isRecording.value = false;
|
wavesurfer.value.load(recordedAudioUrl.value);
|
||||||
|
emit('finishRecord', {
|
||||||
|
name: file.name,
|
||||||
|
type: file.type,
|
||||||
|
size: file.size,
|
||||||
|
file,
|
||||||
|
});
|
||||||
|
hasRecording.value = true;
|
||||||
|
isRecording.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
isRecording.value = false;
|
||||||
|
hasRecording.value = false;
|
||||||
|
emit('recordError', { error });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
record.value.on('record-progress', time => {
|
record.value.on('record-progress', time => {
|
||||||
@@ -109,6 +143,10 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
if (recordedAudioUrl.value) {
|
||||||
|
URL.revokeObjectURL(recordedAudioUrl.value);
|
||||||
|
recordedAudioUrl.value = null;
|
||||||
|
}
|
||||||
if (wavesurfer.value) {
|
if (wavesurfer.value) {
|
||||||
wavesurfer.value.destroy();
|
wavesurfer.value.destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -1,5 +1,7 @@
|
|||||||
import lamejs from '@breezystack/lamejs';
|
import lamejs from '@breezystack/lamejs';
|
||||||
|
|
||||||
|
import { remuxWebmToOgg } from './webmOpusToOgg';
|
||||||
|
|
||||||
const writeString = (view, offset, string) => {
|
const writeString = (view, offset, string) => {
|
||||||
// eslint-disable-next-line no-plusplus
|
// eslint-disable-next-line no-plusplus
|
||||||
for (let i = 0; i < string.length; i++) {
|
for (let i = 0; i < string.length; i++) {
|
||||||
@@ -139,6 +141,20 @@ export const convertAudio = async (inputBlob, outputFormat, bitrate = 128) => {
|
|||||||
audio = await convertToWav(inputBlob);
|
audio = await convertToWav(inputBlob);
|
||||||
} else if (outputFormat === 'audio/mp3') {
|
} else if (outputFormat === 'audio/mp3') {
|
||||||
audio = await convertToMp3(inputBlob, bitrate);
|
audio = await convertToMp3(inputBlob, bitrate);
|
||||||
|
} else if (outputFormat === 'audio/ogg') {
|
||||||
|
const inputType = inputBlob.type.split(';')[0].trim();
|
||||||
|
if (inputType === 'audio/webm' || inputType === 'video/webm') {
|
||||||
|
audio = await remuxWebmToOgg(inputBlob);
|
||||||
|
} else if (inputType === 'audio/ogg') {
|
||||||
|
audio = inputBlob;
|
||||||
|
} else {
|
||||||
|
// Browsers that record neither WebM nor OGG (e.g. Safari records
|
||||||
|
// audio/mp4) cannot produce OGG/Opus. Fall back to MP3 so the recording
|
||||||
|
// still sends as a regular audio message instead of failing. The caller
|
||||||
|
// keys the voice-note flag off the returned blob type, so an MP3 result
|
||||||
|
// is never mislabeled as an OGG/Opus voice note.
|
||||||
|
audio = await convertToMp3(inputBlob, bitrate);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unsupported output format');
|
throw new Error('Unsupported output format');
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
/* eslint-disable no-bitwise */
|
||||||
|
/**
|
||||||
|
* WebM/Opus → OGG/Opus remuxer
|
||||||
|
*
|
||||||
|
* Chrome's MediaRecorder produces WebM containers even when
|
||||||
|
* `audio/ogg;codecs=opus` is requested. WhatsApp Cloud API requires
|
||||||
|
* proper OGG/Opus files for voice messages.
|
||||||
|
*
|
||||||
|
* This module extracts raw Opus packets from the WebM (EBML) container
|
||||||
|
* and repackages them into a valid OGG bitstream. The audio data itself
|
||||||
|
* is never re-encoded — only the container format changes.
|
||||||
|
*
|
||||||
|
* References:
|
||||||
|
* EBML (container for WebM): RFC 8794 — https://www.rfc-editor.org/rfc/rfc8794
|
||||||
|
* Matroska/WebM elements: https://www.matroska.org/technical/elements.html
|
||||||
|
* OGG bitstream framing: RFC 3533 — https://www.rfc-editor.org/rfc/rfc3533
|
||||||
|
* Opus codec: RFC 6716 — https://www.rfc-editor.org/rfc/rfc6716
|
||||||
|
* Opus in OGG (OpusHead/Tags): RFC 7845 — https://www.rfc-editor.org/rfc/rfc7845
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ======================== EBML / WebM parser ========================
|
||||||
|
|
||||||
|
const EBML_IDS = {
|
||||||
|
Segment: 0x18538067,
|
||||||
|
SegmentInfo: 0x1549a966,
|
||||||
|
Tracks: 0x1654ae6b,
|
||||||
|
TrackEntry: 0xae,
|
||||||
|
CodecPrivate: 0x63a2,
|
||||||
|
Audio: 0xe1,
|
||||||
|
SamplingFrequency: 0xb5,
|
||||||
|
Channels: 0x9f,
|
||||||
|
Cluster: 0x1f43b675,
|
||||||
|
Timecode: 0xe7,
|
||||||
|
SimpleBlock: 0xa3,
|
||||||
|
BlockGroup: 0xa0,
|
||||||
|
Block: 0xa1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MASTER_ELEMENTS = new Set([
|
||||||
|
0x1a45dfa3, // EBML header
|
||||||
|
EBML_IDS.Segment,
|
||||||
|
EBML_IDS.SegmentInfo,
|
||||||
|
EBML_IDS.Tracks,
|
||||||
|
EBML_IDS.TrackEntry,
|
||||||
|
EBML_IDS.Audio,
|
||||||
|
EBML_IDS.Cluster,
|
||||||
|
EBML_IDS.BlockGroup,
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** Read an EBML variable-length integer (data size). */
|
||||||
|
function readVint(data, pos) {
|
||||||
|
if (pos >= data.length) return null;
|
||||||
|
const first = data[pos];
|
||||||
|
if (first === 0) return null;
|
||||||
|
|
||||||
|
let len = 1;
|
||||||
|
let mask = 0x80;
|
||||||
|
while (len <= 8 && !(first & mask)) {
|
||||||
|
len += 1;
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
if (len > 8 || pos + len > data.length) return null;
|
||||||
|
|
||||||
|
let value = first & (mask - 1);
|
||||||
|
for (let i = 1; i < len; i += 1) {
|
||||||
|
value = value * 256 + data[pos + i];
|
||||||
|
}
|
||||||
|
return { value, length: len };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an EBML element ID (leading marker bits are kept). */
|
||||||
|
function readElementId(data, pos) {
|
||||||
|
if (pos >= data.length) return null;
|
||||||
|
const first = data[pos];
|
||||||
|
if (first === 0) return null;
|
||||||
|
|
||||||
|
let len = 1;
|
||||||
|
let mask = 0x80;
|
||||||
|
while (len <= 4 && !(first & mask)) {
|
||||||
|
len += 1;
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
if (len > 4 || pos + len > data.length) return null;
|
||||||
|
|
||||||
|
let id = first;
|
||||||
|
for (let i = 1; i < len; i += 1) {
|
||||||
|
id = id * 256 + data[pos + i];
|
||||||
|
}
|
||||||
|
return { id, length: len };
|
||||||
|
}
|
||||||
|
|
||||||
|
function readUintBE(data, offset, length) {
|
||||||
|
let v = 0;
|
||||||
|
for (let i = 0; i < length; i += 1) v = v * 256 + data[offset + i];
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readFloatBE(data, offset, length) {
|
||||||
|
if (length !== 4 && length !== 8) return NaN;
|
||||||
|
const buf = new ArrayBuffer(length);
|
||||||
|
const u8 = new Uint8Array(buf);
|
||||||
|
for (let i = 0; i < length; i += 1) u8[i] = data[offset + i];
|
||||||
|
const view = new DataView(buf);
|
||||||
|
return length === 4 ? view.getFloat32(0) : view.getFloat64(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extract the raw Opus frame from a SimpleBlock / Block element. */
|
||||||
|
function extractFrameFromBlock(data, offset, end) {
|
||||||
|
const trackVint = readVint(data, offset);
|
||||||
|
if (!trackVint) return null;
|
||||||
|
let pos = offset + trackVint.length;
|
||||||
|
|
||||||
|
// int16 relative timecode (big-endian, signed) – skip
|
||||||
|
pos += 2;
|
||||||
|
// Flags byte – skip. Lacing (Xiph/EBML/fixed-size) is NOT supported;
|
||||||
|
// this assumes single-frame blocks as produced by MediaRecorder.
|
||||||
|
const flags = data[pos];
|
||||||
|
const lacingBits = (flags >> 1) & 0x03;
|
||||||
|
if (lacingBits !== 0) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(
|
||||||
|
'webmOpusToOgg: laced SimpleBlock detected (unsupported), frame may be invalid'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
if (pos >= end) return null;
|
||||||
|
return data.slice(pos, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walk the EBML tree and collect metadata + Opus frames.
|
||||||
|
* We only descend into master elements and only extract the fields we need.
|
||||||
|
*/
|
||||||
|
function parseWebM(buffer) {
|
||||||
|
const data = new Uint8Array(buffer);
|
||||||
|
const result = {
|
||||||
|
channels: 1,
|
||||||
|
sampleRate: 48000,
|
||||||
|
codecPrivate: null,
|
||||||
|
frames: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
function walk(start, end) {
|
||||||
|
let pos = start;
|
||||||
|
while (pos < end) {
|
||||||
|
const idRes = readElementId(data, pos);
|
||||||
|
if (!idRes) break;
|
||||||
|
pos += idRes.length;
|
||||||
|
|
||||||
|
const sizeRes = readVint(data, pos);
|
||||||
|
if (!sizeRes) break;
|
||||||
|
pos += sizeRes.length;
|
||||||
|
|
||||||
|
// Handle "unknown size" (all-ones VINT) by treating it as the rest of the parent
|
||||||
|
// Use Math.pow instead of bit-shift to avoid 32-bit overflow for 5+ byte VINTs
|
||||||
|
const maxVint = 2 ** (7 * sizeRes.length) - 1;
|
||||||
|
const elEnd =
|
||||||
|
sizeRes.value === maxVint ? end : Math.min(pos + sizeRes.value, end);
|
||||||
|
|
||||||
|
if (MASTER_ELEMENTS.has(idRes.id)) {
|
||||||
|
walk(pos, elEnd);
|
||||||
|
} else {
|
||||||
|
switch (idRes.id) {
|
||||||
|
case EBML_IDS.Channels:
|
||||||
|
result.channels = readUintBE(data, pos, sizeRes.value);
|
||||||
|
break;
|
||||||
|
case EBML_IDS.SamplingFrequency:
|
||||||
|
result.sampleRate = readFloatBE(data, pos, sizeRes.value);
|
||||||
|
break;
|
||||||
|
case EBML_IDS.CodecPrivate:
|
||||||
|
result.codecPrivate = data.slice(pos, elEnd);
|
||||||
|
break;
|
||||||
|
case EBML_IDS.SimpleBlock:
|
||||||
|
case EBML_IDS.Block: {
|
||||||
|
const frame = extractFrameFromBlock(data, pos, elEnd);
|
||||||
|
if (frame && frame.length > 0) result.frames.push(frame);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = elEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk(0, data.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== OGG writer ========================
|
||||||
|
|
||||||
|
/** OGG CRC-32 table (polynomial 0x04C11DB7). */
|
||||||
|
const CRC_TABLE = (() => {
|
||||||
|
const t = new Uint32Array(256);
|
||||||
|
for (let i = 0; i < 256; i += 1) {
|
||||||
|
let c = i << 24;
|
||||||
|
for (let j = 0; j < 8; j += 1) {
|
||||||
|
c = ((c << 1) ^ (c & 0x80000000 ? 0x04c11db7 : 0)) >>> 0;
|
||||||
|
}
|
||||||
|
t[i] = c;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
})();
|
||||||
|
|
||||||
|
function oggCrc32(bytes) {
|
||||||
|
let crc = 0;
|
||||||
|
for (let i = 0; i < bytes.length; i += 1) {
|
||||||
|
crc = (CRC_TABLE[((crc >>> 24) ^ bytes[i]) & 0xff] ^ (crc << 8)) >>> 0;
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build one OGG page.
|
||||||
|
*
|
||||||
|
* @param {number} headerType 0x02 = BOS, 0x04 = EOS, 0x00 = normal
|
||||||
|
* @param {number} granulePosition 48 kHz sample count
|
||||||
|
* @param {number} serialNumber logical stream id
|
||||||
|
* @param {number} pageSeq page sequence counter
|
||||||
|
* @param {Uint8Array[]} packets one or more complete Opus packets
|
||||||
|
*/
|
||||||
|
function createOggPage(
|
||||||
|
headerType,
|
||||||
|
granulePosition,
|
||||||
|
serialNumber,
|
||||||
|
pageSeq,
|
||||||
|
packets
|
||||||
|
) {
|
||||||
|
// Build the lacing / segment table
|
||||||
|
const segTable = [];
|
||||||
|
let dataLen = 0;
|
||||||
|
packets.forEach(pkt => {
|
||||||
|
let rem = pkt.length;
|
||||||
|
while (rem >= 255) {
|
||||||
|
segTable.push(255);
|
||||||
|
rem -= 255;
|
||||||
|
}
|
||||||
|
segTable.push(rem); // final segment (0 when pkt.length is a multiple of 255)
|
||||||
|
dataLen += pkt.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
const hdrLen = 27 + segTable.length;
|
||||||
|
const page = new Uint8Array(hdrLen + dataLen);
|
||||||
|
const dv = new DataView(page.buffer);
|
||||||
|
|
||||||
|
// Capture pattern
|
||||||
|
page.set([0x4f, 0x67, 0x67, 0x53]); // "OggS"
|
||||||
|
page[4] = 0; // version
|
||||||
|
page[5] = headerType;
|
||||||
|
|
||||||
|
// Granule position (int64 LE)
|
||||||
|
dv.setUint32(6, granulePosition & 0xffffffff, true);
|
||||||
|
dv.setUint32(
|
||||||
|
10,
|
||||||
|
Math.floor(granulePosition / 0x100000000) & 0xffffffff,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
dv.setUint32(14, serialNumber, true); // serial
|
||||||
|
dv.setUint32(18, pageSeq, true); // page sequence
|
||||||
|
dv.setUint32(22, 0, true); // CRC placeholder
|
||||||
|
|
||||||
|
page[26] = segTable.length;
|
||||||
|
for (let i = 0; i < segTable.length; i += 1) page[27 + i] = segTable[i];
|
||||||
|
|
||||||
|
let off = hdrLen;
|
||||||
|
packets.forEach(pkt => {
|
||||||
|
page.set(pkt, off);
|
||||||
|
off += pkt.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fill in the CRC
|
||||||
|
dv.setUint32(22, oggCrc32(page), true);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== Opus helpers ========================
|
||||||
|
|
||||||
|
/** Lookup table: frame duration in ms for each Opus TOC config index (0-31). */
|
||||||
|
const OPUS_FRAME_MS = [
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
60, // 0-3 SILK NB
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
60, // 4-7 SILK MB
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
40,
|
||||||
|
60, // 8-11 SILK WB
|
||||||
|
10,
|
||||||
|
20, // 12-13 Hybrid SWB
|
||||||
|
10,
|
||||||
|
20, // 14-15 Hybrid FB
|
||||||
|
2.5,
|
||||||
|
5,
|
||||||
|
10,
|
||||||
|
20, // 16-19 CELT NB
|
||||||
|
2.5,
|
||||||
|
5,
|
||||||
|
10,
|
||||||
|
20, // 20-23 CELT WB
|
||||||
|
2.5,
|
||||||
|
5,
|
||||||
|
10,
|
||||||
|
20, // 24-27 CELT SWB
|
||||||
|
2.5,
|
||||||
|
5,
|
||||||
|
10,
|
||||||
|
20, // 28-31 CELT FB
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Return the total number of 48 kHz PCM samples represented by an Opus packet. */
|
||||||
|
function opusPacketSamples(pkt) {
|
||||||
|
if (!pkt || pkt.length === 0) return 960; // default 20 ms
|
||||||
|
const toc = pkt[0];
|
||||||
|
const config = (toc >> 3) & 0x1f;
|
||||||
|
const code = toc & 0x03;
|
||||||
|
|
||||||
|
const samplesPerFrame = ((OPUS_FRAME_MS[config] || 20) * 48000) / 1000;
|
||||||
|
let frameCount;
|
||||||
|
if (code <= 1) frameCount = code + 1;
|
||||||
|
else if (code === 2) frameCount = 2;
|
||||||
|
else frameCount = pkt.length >= 2 ? pkt[1] & 0x3f : 1;
|
||||||
|
|
||||||
|
return samplesPerFrame * frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildOpusHead(channels, sampleRate, preSkip) {
|
||||||
|
const buf = new Uint8Array(19);
|
||||||
|
const dv = new DataView(buf.buffer);
|
||||||
|
buf.set(new TextEncoder().encode('OpusHead'));
|
||||||
|
buf[8] = 1; // version
|
||||||
|
buf[9] = channels;
|
||||||
|
dv.setUint16(10, preSkip, true);
|
||||||
|
dv.setUint32(12, sampleRate, true);
|
||||||
|
dv.setInt16(16, 0, true); // output gain
|
||||||
|
buf[18] = 0; // channel mapping family
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildOpusTags() {
|
||||||
|
const vendor = new TextEncoder().encode('chatwoot');
|
||||||
|
const buf = new Uint8Array(8 + 4 + vendor.length + 4);
|
||||||
|
const dv = new DataView(buf.buffer);
|
||||||
|
buf.set(new TextEncoder().encode('OpusTags'));
|
||||||
|
dv.setUint32(8, vendor.length, true);
|
||||||
|
buf.set(vendor, 12);
|
||||||
|
dv.setUint32(12 + vendor.length, 0, true); // 0 user comments
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================== Public API ========================
|
||||||
|
|
||||||
|
const MAX_FRAMES_PER_PAGE = 50; // ~1 s at 20 ms/frame
|
||||||
|
const MAX_SEGMENTS_PER_PAGE = 255;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remux a WebM/Opus blob into an OGG/Opus blob.
|
||||||
|
* If the input is already OGG (starts with "OggS"), it is returned as-is.
|
||||||
|
*
|
||||||
|
* @param {Blob} webmBlob
|
||||||
|
* @returns {Promise<Blob>} OGG/Opus blob
|
||||||
|
*/
|
||||||
|
export async function remuxWebmToOgg(webmBlob) {
|
||||||
|
const buffer = await webmBlob.arrayBuffer();
|
||||||
|
const bytes = new Uint8Array(buffer);
|
||||||
|
|
||||||
|
// Already OGG? Return unchanged.
|
||||||
|
if (
|
||||||
|
bytes.length >= 4 &&
|
||||||
|
bytes[0] === 0x4f &&
|
||||||
|
bytes[1] === 0x67 &&
|
||||||
|
bytes[2] === 0x67 &&
|
||||||
|
bytes[3] === 0x53
|
||||||
|
) {
|
||||||
|
return webmBlob;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { channels, sampleRate, codecPrivate, frames } = parseWebM(buffer);
|
||||||
|
if (frames.length === 0) {
|
||||||
|
throw new Error('No Opus frames found in WebM input');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract pre-skip from the WebM CodecPrivate (which IS the OpusHead)
|
||||||
|
let preSkip = 312;
|
||||||
|
if (codecPrivate && codecPrivate.length >= 12) {
|
||||||
|
const magic = new TextDecoder().decode(codecPrivate.slice(0, 8));
|
||||||
|
if (magic === 'OpusHead') {
|
||||||
|
preSkip = new DataView(
|
||||||
|
codecPrivate.buffer,
|
||||||
|
codecPrivate.byteOffset,
|
||||||
|
codecPrivate.length
|
||||||
|
).getUint16(10, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const serial = (Math.random() * 0x100000000) >>> 0;
|
||||||
|
let pageSeq = 0;
|
||||||
|
const pages = [];
|
||||||
|
|
||||||
|
// Page 0 – OpusHead (BOS)
|
||||||
|
pages.push(
|
||||||
|
createOggPage(0x02, 0, serial, pageSeq, [
|
||||||
|
buildOpusHead(channels, sampleRate, preSkip),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
pageSeq += 1;
|
||||||
|
|
||||||
|
// Page 1 – OpusTags
|
||||||
|
pages.push(createOggPage(0x00, 0, serial, pageSeq, [buildOpusTags()]));
|
||||||
|
pageSeq += 1;
|
||||||
|
|
||||||
|
// Audio pages
|
||||||
|
let granule = 0;
|
||||||
|
let idx = 0;
|
||||||
|
|
||||||
|
while (idx < frames.length) {
|
||||||
|
const packets = [];
|
||||||
|
let segs = 0;
|
||||||
|
|
||||||
|
while (idx < frames.length && packets.length < MAX_FRAMES_PER_PAGE) {
|
||||||
|
const pkt = frames[idx];
|
||||||
|
// createOggPage always appends a terminating lacing value, so a packet
|
||||||
|
// spans floor(len/255)+1 segments (including the extra 0 when len is an
|
||||||
|
// exact multiple of 255). Math.ceil would undercount those cases.
|
||||||
|
const pktSegs = Math.floor(pkt.length / 255) + 1;
|
||||||
|
if (segs + pktSegs > MAX_SEGMENTS_PER_PAGE && packets.length > 0) break;
|
||||||
|
|
||||||
|
packets.push(pkt);
|
||||||
|
segs += pktSegs;
|
||||||
|
granule += opusPacketSamples(pkt);
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLast = idx >= frames.length;
|
||||||
|
pages.push(
|
||||||
|
createOggPage(isLast ? 0x04 : 0x00, granule, serial, pageSeq, packets)
|
||||||
|
);
|
||||||
|
pageSeq += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concatenate pages into a single buffer
|
||||||
|
const total = pages.reduce((s, p) => s + p.length, 0);
|
||||||
|
const out = new Uint8Array(total);
|
||||||
|
let off = 0;
|
||||||
|
pages.forEach(p => {
|
||||||
|
out.set(p, off);
|
||||||
|
off += p.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Blob([out], { type: 'audio/ogg' });
|
||||||
|
}
|
||||||
@@ -375,7 +375,10 @@ export default {
|
|||||||
return `draft-${this.conversationIdByRoute}-${this.replyType}`;
|
return `draft-${this.conversationIdByRoute}-${this.replyType}`;
|
||||||
},
|
},
|
||||||
audioRecordFormat() {
|
audioRecordFormat() {
|
||||||
if (this.isAWhatsAppChannel || this.isATelegramChannel) {
|
if (this.isAWhatsAppChannel) {
|
||||||
|
return AUDIO_FORMATS.OGG;
|
||||||
|
}
|
||||||
|
if (this.isATelegramChannel) {
|
||||||
return AUDIO_FORMATS.MP3;
|
return AUDIO_FORMATS.MP3;
|
||||||
}
|
}
|
||||||
if (this.isAPIInbox) {
|
if (this.isAPIInbox) {
|
||||||
@@ -1008,14 +1011,18 @@ export default {
|
|||||||
onFinishRecorder(file) {
|
onFinishRecorder(file) {
|
||||||
this.recordingAudioState = 'stopped';
|
this.recordingAudioState = 'stopped';
|
||||||
this.hasRecordedAudio = true;
|
this.hasRecordedAudio = true;
|
||||||
// Added a new key isRecordedAudio to the file to find it's and recorded audio
|
// Added a new key isVoiceMessage to the file to identify recorded audio
|
||||||
// Because to filter and show only non recorded audio and other attachments
|
// Because to filter and show only non recorded audio and other attachments
|
||||||
const autoRecordedFile = {
|
const autoRecordedFile = {
|
||||||
...file,
|
...file,
|
||||||
isRecordedAudio: true,
|
isVoiceMessage: true,
|
||||||
};
|
};
|
||||||
return file && this.onFileUpload(autoRecordedFile);
|
return file && this.onFileUpload(autoRecordedFile);
|
||||||
},
|
},
|
||||||
|
onRecordError() {
|
||||||
|
this.toggleAudioRecorder();
|
||||||
|
useAlert(this.$t('CONVERSATION.REPLYBOX.AUDIO_CONVERSION_FAILED'));
|
||||||
|
},
|
||||||
toggleTyping(status) {
|
toggleTyping(status) {
|
||||||
const conversationId = this.currentChat.id;
|
const conversationId = this.currentChat.id;
|
||||||
const isPrivate = this.isPrivate;
|
const isPrivate = this.isPrivate;
|
||||||
@@ -1042,7 +1049,7 @@ export default {
|
|||||||
isPrivate: this.isPrivate,
|
isPrivate: this.isPrivate,
|
||||||
thumb: reader.result,
|
thumb: reader.result,
|
||||||
blobSignedId: blob ? blob.signed_id : undefined,
|
blobSignedId: blob ? blob.signed_id : undefined,
|
||||||
isRecordedAudio: file?.isRecordedAudio || false,
|
isVoiceMessage: file?.isVoiceMessage || false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1078,6 +1085,7 @@ export default {
|
|||||||
private: false,
|
private: false,
|
||||||
message: caption,
|
message: caption,
|
||||||
sender: this.sender,
|
sender: this.sender,
|
||||||
|
isVoiceMessage: attachment.isVoiceMessage || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
attachmentPayload = this.setReplyToInPayload(attachmentPayload);
|
attachmentPayload = this.setReplyToInPayload(attachmentPayload);
|
||||||
@@ -1127,6 +1135,9 @@ export default {
|
|||||||
this.attachedFiles.forEach(attachment => {
|
this.attachedFiles.forEach(attachment => {
|
||||||
if (this.globalConfig.directUploadsEnabled) {
|
if (this.globalConfig.directUploadsEnabled) {
|
||||||
messagePayload.files.push(attachment.blobSignedId);
|
messagePayload.files.push(attachment.blobSignedId);
|
||||||
|
if (attachment.isVoiceMessage) {
|
||||||
|
messagePayload.isVoiceMessage = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
messagePayload.files.push(attachment.resource.file);
|
messagePayload.files.push(attachment.resource.file);
|
||||||
}
|
}
|
||||||
@@ -1215,7 +1226,7 @@ export default {
|
|||||||
this.hasRecordedAudio = false;
|
this.hasRecordedAudio = false;
|
||||||
// Only clear the recorded audio when we click toggle button.
|
// Only clear the recorded audio when we click toggle button.
|
||||||
this.attachedFiles = this.attachedFiles.filter(
|
this.attachedFiles = this.attachedFiles.filter(
|
||||||
file => !file?.isRecordedAudio
|
file => !file?.isVoiceMessage
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
toggleEditorSize() {
|
toggleEditorSize() {
|
||||||
@@ -1293,6 +1304,7 @@ export default {
|
|||||||
:audio-record-format="audioRecordFormat"
|
:audio-record-format="audioRecordFormat"
|
||||||
@recorder-progress-changed="onRecordProgressChanged"
|
@recorder-progress-changed="onRecordProgressChanged"
|
||||||
@finish-record="onFinishRecorder"
|
@finish-record="onFinishRecorder"
|
||||||
|
@record-error="onRecordError"
|
||||||
@play="recordingAudioState = 'playing'"
|
@play="recordingAudioState = 'playing'"
|
||||||
@pause="recordingAudioState = 'paused'"
|
@pause="recordingAudioState = 'paused'"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ vi.mock('shared/helpers/mitt', () => ({
|
|||||||
|
|
||||||
vi.mock('dashboard/helper/AnalyticsHelper/index', async importOriginal => {
|
vi.mock('dashboard/helper/AnalyticsHelper/index', async importOriginal => {
|
||||||
const actual = await importOriginal();
|
const actual = await importOriginal();
|
||||||
actual.default = {
|
return {
|
||||||
track: vi.fn(),
|
...actual,
|
||||||
|
default: {
|
||||||
|
track: vi.fn(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return actual;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('useTrack', () => {
|
describe('useTrack', () => {
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ vi.mock('vue-i18n');
|
|||||||
vi.mock('dashboard/api/captain/tasks');
|
vi.mock('dashboard/api/captain/tasks');
|
||||||
vi.mock('dashboard/helper/AnalyticsHelper/index', async importOriginal => {
|
vi.mock('dashboard/helper/AnalyticsHelper/index', async importOriginal => {
|
||||||
const actual = await importOriginal();
|
const actual = await importOriginal();
|
||||||
actual.default = {
|
return {
|
||||||
track: vi.fn(),
|
...actual,
|
||||||
|
default: {
|
||||||
|
track: vi.fn(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return actual;
|
|
||||||
});
|
});
|
||||||
vi.mock('dashboard/helper/AnalyticsHelper/events', () => ({
|
vi.mock('dashboard/helper/AnalyticsHelper/events', () => ({
|
||||||
CAPTAIN_EVENTS: {
|
CAPTAIN_EVENTS: {
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ export function useAccount() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const finishOnboarding = async data => {
|
||||||
|
await store.dispatch('accounts/finishOnboarding', data);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accountId,
|
accountId,
|
||||||
route,
|
route,
|
||||||
@@ -61,5 +65,6 @@ export function useAccount() {
|
|||||||
isCloudFeatureEnabled,
|
isCloudFeatureEnabled,
|
||||||
isOnChatwootCloud,
|
isOnChatwootCloud,
|
||||||
updateAccount,
|
updateAccount,
|
||||||
|
finishOnboarding,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
||||||
"AGENT_SELECT_LABEL": "Select agent",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Go back",
|
|
||||||
"ASSIGN_LABEL": "Assign",
|
|
||||||
"NONE": "None",
|
"NONE": "None",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||||
"AGENT_LIST_LOADING": "Loading agents",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Change status",
|
"CHANGE_STATUS": "Change status",
|
||||||
"SNOOZE_UNTIL": "Snooze",
|
"SNOOZE_UNTIL": "Snooze",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Select team",
|
|
||||||
"NONE": "None",
|
"NONE": "None",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "በሂደት ላይ",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "በሂደት ላይ",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "ደውል",
|
"CALL": "ደውል",
|
||||||
"CALL_INITIATED": "ለእውነተኛው እውቀት መደወል እየተከናወነ ነው…",
|
"CALL_INITIATED": "ለእውነተኛው እውቀት መደወል እየተከናወነ ነው…",
|
||||||
"CALL_FAILED": "ጥሪውን መጀመር አልቻልንም። እባክዎ ደግመው ይሞክሩ።.",
|
"CALL_FAILED": "ጥሪውን መጀመር አልቻልንም። እባክዎ ደግመው ይሞክሩ።.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "የድምፅ ኢንቦክስ ይምረጡ"
|
"TITLE": "የድምፅ ኢንቦክስ ይምረጡ"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "መለያዎችን መሰጠት",
|
"ASSIGN_LABELS": "መለያዎችን መሰጠት",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "መለያዎች በተሳካ ሁኔታ ተመዝግበዋል።.",
|
"ASSIGN_LABELS_SUCCESS": "መለያዎች በተሳካ ሁኔታ ተመዝግበዋል።.",
|
||||||
"ASSIGN_LABELS_FAILED": "መለያዎችን ማስመዝገብ አልተሳካም",
|
"ASSIGN_LABELS_FAILED": "መለያዎችን ማስመዝገብ አልተሳካም",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "ለተመረጡት እውነተኛዎች የሚያክሉትን መለያዎች ይምረጡ።.",
|
"DESCRIPTION": "ለተመረጡት እውነተኛዎች የሚያክሉትን መለያዎች ይምረጡ።.",
|
||||||
"NO_LABELS_FOUND": "እስካሁን መለያዎች አልተገኙም።.",
|
"NO_LABELS_FOUND": "እስካሁን መለያዎች አልተገኙም።.",
|
||||||
"SELECTED_COUNT": "{count} ተመርጧል",
|
"SELECTED_COUNT": "{count} ተመርጧል",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
|
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
|
||||||
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
|
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
|
||||||
"NO_RESPONSE": "No response",
|
"NO_RESPONSE": "No response",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "ተፈትኗል",
|
"RESOLVE_ACTION": "ተፈትኗል",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Snoozed until next reply",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Snoozed until next reply",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Record audio",
|
"TIP_AUDIORECORDER_ICON": "Record audio",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Allow access to audio",
|
"TIP_AUDIORECORDER_PERMISSION": "Allow access to audio",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Could not open the audio",
|
"TIP_AUDIORECORDER_ERROR": "Could not open the audio",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Drag and drop here to attach",
|
"DRAG_DROP": "Drag and drop here to attach",
|
||||||
"START_AUDIO_RECORDING": "Start audio recording",
|
"START_AUDIO_RECORDING": "Start audio recording",
|
||||||
"STOP_AUDIO_RECORDING": "Stop audio recording",
|
"STOP_AUDIO_RECORDING": "Stop audio recording",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "እቅድ",
|
"DRAFT": "እቅድ",
|
||||||
"ARCHIVE": "አርክቭ",
|
"ARCHIVE": "አርክቭ",
|
||||||
"TRANSLATE": "Translate",
|
"TRANSLATE": "Translate",
|
||||||
|
"MOVE_TO_CATEGORY": "Category",
|
||||||
"DELETE": "Delete",
|
"DELETE": "Delete",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Delete",
|
"DELETE_CONFIRM": "Delete",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "ቅንብር አርትዕ"
|
"EDIT_CONFIGURATION": "ቅንብር አርትዕ"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "አስወግድ"
|
||||||
|
},
|
||||||
|
"SAVE": "ለውጦች አስቀምጥ"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "ፖርታል በተሳካ ሁኔታ ተፈጥሯል",
|
"SUCCESS_MESSAGE": "ፖርታል በተሳካ ሁኔታ ተፈጥሯል",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "ከMeta ጋር በመረጋገጥ ላይ ነው",
|
"AUTH_PROCESSING": "ከMeta ጋር በመረጋገጥ ላይ ነው",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "እባክዎ በMeta መስኮት ውስጥ የንግድ ቅንብር ያርኩ...",
|
"WAITING_FOR_BUSINESS_INFO": "እባክዎ በMeta መስኮት ውስጥ የንግድ ቅንብር ያርኩ...",
|
||||||
"PROCESSING": "የWhatsApp ቢዝነስ መለያዎን እየተዘጋጀ ነው",
|
"PROCESSING": "የWhatsApp ቢዝነስ መለያዎን እየተዘጋጀ ነው",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Facebook SDK እየተጫነ ነው...",
|
"LOADING_SDK": "Facebook SDK እየተጫነ ነው...",
|
||||||
"CANCELLED": "የWhatsApp ምዝገባ ተሰርዟል",
|
"CANCELLED": "የWhatsApp ምዝገባ ተሰርዟል",
|
||||||
"SUCCESS_TITLE": "የWhatsApp ቢዝነስ መለያ ተገናኝቷል!",
|
"SUCCESS_TITLE": "የWhatsApp ቢዝነስ መለያ ተገናኝቷል!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "ማረጋገጫ አልተጠናቀቀም። ሂደቱን እባክዎ ዳግም ይጀምሩ።.",
|
"AUTH_NOT_COMPLETED": "ማረጋገጫ አልተጠናቀቀም። ሂደቱን እባክዎ ዳግም ይጀምሩ።.",
|
||||||
"SUCCESS_FALLBACK": "የWhatsApp የንግድ መለያ በተሳካ ሁኔታ ተቋቋመ",
|
"SUCCESS_FALLBACK": "የWhatsApp የንግድ መለያ በተሳካ ሁኔታ ተቋቋመ",
|
||||||
"MANUAL_FALLBACK": "ቁጥርዎ ከWhatsApp Business Platform (API) ጋር ከተገናኘ እና ወይም እርስዎ የቴክኖሎጂ አቅራቢ ከሆኑ እና የእርስዎን ቁጥር በራስዎ ሲያስገቡ፣ እባክዎ የ{link} ሂደትን ይጠቀሙ",
|
"MANUAL_FALLBACK": "ቁጥርዎ ከWhatsApp Business Platform (API) ጋር ከተገናኘ እና ወይም እርስዎ የቴክኖሎጂ አቅራቢ ከሆኑ እና የእርስዎን ቁጥር በራስዎ ሲያስገቡ፣ እባክዎ የ{link} ሂደትን ይጠቀሙ",
|
||||||
"MANUAL_LINK_TEXT": "የእጅ ማቀናበሪያ ሂደት"
|
"MANUAL_LINK_TEXT": "የእጅ ማቀናበሪያ ሂደት",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "WhatsApp ቻናሉን ማስቀመጥ አልተቻለም"
|
"ERROR_MESSAGE": "WhatsApp ቻናሉን ማስቀመጥ አልተቻለም"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "ዋትስአፕ",
|
"TITLE": "ዋትስአፕ",
|
||||||
"DESCRIPTION": "በWhatsApp ላይ ደንበኞችዎን ድጋፍ ያድርጉ"
|
"DESCRIPTION": "በWhatsApp ላይ ደንበኞችዎን ድጋፍ ያድርጉ"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "ኢሜይል",
|
"TITLE": "ኢሜይል",
|
||||||
"DESCRIPTION": "ከGmail, Outlook ወይም ከሌሎች አቅራቢዎች ጋር ያገናኙ"
|
"DESCRIPTION": "ከGmail, Outlook ወይም ከሌሎች አቅራቢዎች ጋር ያገናኙ"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "የቦት ቅንብሮች",
|
"BOT_CONFIGURATION": "የቦት ቅንብሮች",
|
||||||
"ACCOUNT_HEALTH": "የመለያ ጤና",
|
"ACCOUNT_HEALTH": "የመለያ ጤና",
|
||||||
"CSAT": "የደንበኞች ደህንነት ግምገማ (CSAT)",
|
"CSAT": "የደንበኞች ደህንነት ግምገማ (CSAT)",
|
||||||
"VOICE": "ድምጽ"
|
"VOICE": "ድምጽ",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "የቻናል ቅድሚያዎች",
|
"CHANNEL_PREFERENCES": "የቻናል ቅድሚያዎች",
|
||||||
"WIDGET_FEATURES": "የዊጅት ባህሪያት",
|
"WIDGET_FEATURES": "የዊጅት ባህሪያት",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "ከWhatsApp መልእክት አብነቶች እጅግ በእጅ ማስተካከል ለእንደገና የሚገኙ አብነቶችን ያዘምኑ።.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "ከWhatsApp መልእክት አብነቶች እጅግ በእጅ ማስተካከል ለእንደገና የሚገኙ አብነቶችን ያዘምኑ።.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "አብነቶችን ያዘምኑ",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "አብነቶችን ያዘምኑ",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "የአብነት ማስተካከያ በተሳካ ሁኔታ ተጀምሯል። ለማዘመን ጥቂት ደቂቃዎች ሊወስድ ይችላል።.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "የአብነት ማስተካከያ በተሳካ ሁኔታ ተጀምሯል። ለማዘመን ጥቂት ደቂቃዎች ሊወስድ ይችላል።.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "የቀደም ቻት ቅጥያ ቅንብሮችን አዘምን"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "የቀደም ቻት ቅጥያ ቅንብሮችን አዘምን"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "እውቂያ ተፈጥሯል",
|
"CONTACT_CREATED": "እውቂያ ተፈጥሯል",
|
||||||
"CONTACT_UPDATED": "እውቂያ ተሻሽሏል",
|
"CONTACT_UPDATED": "እውቂያ ተሻሽሏል",
|
||||||
"CONVERSATION_TYPING_ON": "ውይይት ማስተካከያ በተጠቃሚ ላይ ነው",
|
"CONVERSATION_TYPING_ON": "ውይይት ማስተካከያ በተጠቃሚ ላይ ነው",
|
||||||
"CONVERSATION_TYPING_OFF": "ውይይት ማስተካከያ ከተጠቃሚ ላይ አልተጠቀሰም"
|
"CONVERSATION_TYPING_OFF": "ውይይት ማስተካከያ ከተጠቃሚ ላይ አልተጠቀሰም",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} المحادثات المحددة",
|
"CONVERSATIONS_SELECTED": "{conversationCount} المحادثات المحددة",
|
||||||
"AGENT_SELECT_LABEL": "اختر وكيل",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "هل أنت متأكد من أنك تريد تعيين {conversationCount} {conversationLabel} إلى",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "هل أنت متأكد من إلغاء تعيين {conversationCount} {conversationLabel}؟",
|
|
||||||
"GO_BACK_LABEL": "العودة للخلف",
|
|
||||||
"ASSIGN_LABEL": "تكليف",
|
|
||||||
"NONE": "لا شيء",
|
"NONE": "لا شيء",
|
||||||
"CLEAR_SELECTION": "مسح",
|
"CLEAR_SELECTION": "مسح",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "تم تسوية المحادثات بنجاح.",
|
"RESOLVE_SUCCESFUL": "تم تسوية المحادثات بنجاح.",
|
||||||
"RESOLVE_FAILED": "فشل في حل المحادثات، يرجى المحاولة مرة أخرى.",
|
"RESOLVE_FAILED": "فشل في حل المحادثات، يرجى المحاولة مرة أخرى.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "المحادثات المرئية في هذه الصفحة هي المحددة فقط.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "المحادثات المرئية في هذه الصفحة هي المحددة فقط.",
|
||||||
"AGENT_LIST_LOADING": "جاري جلب الوكلاء",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "تغيير الحالة",
|
"CHANGE_STATUS": "تغيير الحالة",
|
||||||
"SNOOZE_UNTIL": "تأجيل",
|
"SNOOZE_UNTIL": "تأجيل",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "إضافة وسم",
|
"ASSIGN_LABELS": "إضافة وسم",
|
||||||
"NO_LABELS_FOUND": "لم يتم العثور على تصنيفات",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "تعيين التسميات المحددة",
|
"ASSIGN_SELECTED_LABELS": "تعيين التسميات المحددة",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "تم تعيين التسميات بنجاح.",
|
"ASSIGN_SUCCESFUL": "تم تعيين التسميات بنجاح.",
|
||||||
"ASSIGN_FAILED": "فشل في تعيين التسميات ، الرجاء المحاولة مرة أخرى."
|
"ASSIGN_FAILED": "فشل في تعيين التسميات ، الرجاء المحاولة مرة أخرى.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "اختر فريق",
|
|
||||||
"NONE": "لا شيء",
|
"NONE": "لا شيء",
|
||||||
"NO_TEAMS_AVAILABLE": "لا توجد فرق مضافة إلى هذا الحساب حتى الآن.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "تعيين فريق محدد.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "تم تعيين الفرق بنجاح.",
|
"ASSIGN_SUCCESFUL": "تم تعيين الفرق بنجاح.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "مكتمل",
|
"COMPLETED": "مكتمل",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "مكتمل",
|
"COMPLETED": "مكتمل",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "جار الاتصال بجهة الاتصال…",
|
"CALL_INITIATED": "جار الاتصال بجهة الاتصال…",
|
||||||
"CALL_FAILED": "تعذر بدء المكالمة. الرجاء المحاولة مرة أخرى.",
|
"CALL_FAILED": "تعذر بدء المكالمة. الرجاء المحاولة مرة أخرى.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "تعيين التسميات",
|
"ASSIGN_LABELS": "تعيين التسميات",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "تم تعيين التسميات بنجاح.",
|
"ASSIGN_LABELS_SUCCESS": "تم تعيين التسميات بنجاح.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "هذه الرسالة غير مدعومة، يمكنك مشاهدة هذه الرسالة على تطبيق فيسبوك (Messenger).",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "هذه الرسالة غير مدعومة، يمكنك مشاهدة هذه الرسالة على تطبيق فيسبوك (Messenger).",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "هذه الرسالة غير مدعومة، يمكنك عرض هذه الرسالة على تطبيق Instagram.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "هذه الرسالة غير مدعومة، يمكنك عرض هذه الرسالة على تطبيق Instagram.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "هذه الرسالة غير مدعومة. يمكنك مشاهدة هذه الرسالة على تطبيق TikTok.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "هذه الرسالة غير مدعومة. يمكنك مشاهدة هذه الرسالة على تطبيق TikTok.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "تم حذف الرسالة بنجاح",
|
"SUCCESS_DELETE_MESSAGE": "تم حذف الرسالة بنجاح",
|
||||||
"FAIL_DELETE_MESSSAGE": "تعذر حذف الرسالة! حاول مرة أخرى",
|
"FAIL_DELETE_MESSSAGE": "تعذر حذف الرسالة! حاول مرة أخرى",
|
||||||
"NO_RESPONSE": "لا توجد استجابة",
|
"NO_RESPONSE": "لا توجد استجابة",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "انضم إلى المكالمة"
|
"JOIN_CALL": "انضم إلى المكالمة",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "حل المحادثة",
|
"RESOLVE_ACTION": "حل المحادثة",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "تأجيل حتى الغد",
|
"SNOOZED_UNTIL_TOMORROW": "تأجيل حتى الغد",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "تأجيل حتى الأسبوع القادم",
|
"SNOOZED_UNTIL_NEXT_WEEK": "تأجيل حتى الأسبوع القادم",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "تأجيل حتى الرد التالي",
|
"SNOOZED_UNTIL_NEXT_REPLY": "تأجيل حتى الرد التالي",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "تسجيل الصوت",
|
"TIP_AUDIORECORDER_ICON": "تسجيل الصوت",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "السماح بالوصول إلى الصوت",
|
"TIP_AUDIORECORDER_PERMISSION": "السماح بالوصول إلى الصوت",
|
||||||
"TIP_AUDIORECORDER_ERROR": "تعذر فتح الصوت",
|
"TIP_AUDIORECORDER_ERROR": "تعذر فتح الصوت",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "اسحب و أسقط هنا للإرفاق",
|
"DRAG_DROP": "اسحب و أسقط هنا للإرفاق",
|
||||||
"START_AUDIO_RECORDING": "بدء التسجيل الصوتي",
|
"START_AUDIO_RECORDING": "بدء التسجيل الصوتي",
|
||||||
"STOP_AUDIO_RECORDING": "إيقاف التسجيل الصوتي",
|
"STOP_AUDIO_RECORDING": "إيقاف التسجيل الصوتي",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "لم يتم الرد بعد",
|
"NOT_ANSWERED_YET": "لم يتم الرد بعد",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "يتم التعامل معها في علامة تبويب أخرى",
|
"HANDLED_IN_ANOTHER_TAB": "يتم التعامل معها في علامة تبويب أخرى",
|
||||||
"REJECT_CALL": "رفض",
|
"REJECT_CALL": "رفض",
|
||||||
|
"DISMISS_CALL": "تجاهل",
|
||||||
"JOIN_CALL": "انضم إلى المكالمة",
|
"JOIN_CALL": "انضم إلى المكالمة",
|
||||||
"END_CALL": "إنهاء المكالمة"
|
"END_CALL": "إنهاء المكالمة",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "مسودة",
|
"DRAFT": "مسودة",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "ترجم",
|
"TRANSLATE": "ترجم",
|
||||||
|
"MOVE_TO_CATEGORY": "الفئة",
|
||||||
"DELETE": "حذف",
|
"DELETE": "حذف",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "حذف",
|
"DELETE_CONFIRM": "حذف",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "المظهر",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "حذف"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "تم إنشاء البوابة بنجاح",
|
"SUCCESS_MESSAGE": "تم إنشاء البوابة بنجاح",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Authenticating with Meta",
|
"AUTH_PROCESSING": "Authenticating with Meta",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
||||||
"PROCESSING": "Setting up your WhatsApp Business Account",
|
"PROCESSING": "Setting up your WhatsApp Business Account",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Loading Facebook SDK...",
|
"LOADING_SDK": "Loading Facebook SDK...",
|
||||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
||||||
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
||||||
"MANUAL_LINK_TEXT": "manual setup flow"
|
"MANUAL_LINK_TEXT": "manual setup flow",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "لم نتمكن من حفظ قناة واتساب"
|
"ERROR_MESSAGE": "لم نتمكن من حفظ قناة واتساب"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "واتساب",
|
"TITLE": "واتساب",
|
||||||
"DESCRIPTION": "Support your customers on WhatsApp"
|
"DESCRIPTION": "Support your customers on WhatsApp"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "البريد الإلكتروني",
|
"TITLE": "البريد الإلكتروني",
|
||||||
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "اعدادات البوت",
|
"BOT_CONFIGURATION": "اعدادات البوت",
|
||||||
"ACCOUNT_HEALTH": "Account Health",
|
"ACCOUNT_HEALTH": "Account Health",
|
||||||
"CSAT": "تقييم رضاء العملاء",
|
"CSAT": "تقييم رضاء العملاء",
|
||||||
"VOICE": "Voice"
|
"VOICE": "Voice",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Channel Preferences",
|
"CHANNEL_PREFERENCES": "Channel Preferences",
|
||||||
"WIDGET_FEATURES": "Widget features",
|
"WIDGET_FEATURES": "Widget features",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Contact created",
|
"CONTACT_CREATED": "Contact created",
|
||||||
"CONTACT_UPDATED": "Contact updated",
|
"CONTACT_UPDATED": "Contact updated",
|
||||||
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
||||||
"CONVERSATION_TYPING_OFF": "Conversation Typing Off"
|
"CONVERSATION_TYPING_OFF": "Conversation Typing Off",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
||||||
"AGENT_SELECT_LABEL": "Select agent",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Go back",
|
|
||||||
"ASSIGN_LABEL": "Assign",
|
|
||||||
"NONE": "Heç biri",
|
"NONE": "Heç biri",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||||
"AGENT_LIST_LOADING": "Loading agents",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Change status",
|
"CHANGE_STATUS": "Change status",
|
||||||
"SNOOZE_UNTIL": "Snooze",
|
"SNOOZE_UNTIL": "Snooze",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Select team",
|
|
||||||
"NONE": "None",
|
"NONE": "None",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Zəng et",
|
"CALL": "Zəng et",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Assign Labels",
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} seçildi",
|
"SELECTED_COUNT": "{count} seçildi",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "Bu mesaj dəstəklənmir. Bu mesajı Facebook Messenger tətbiqində görə bilərsiniz.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "Bu mesaj dəstəklənmir. Bu mesajı Facebook Messenger tətbiqində görə bilərsiniz.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Bu mesaj dəstəklənmir. Bu mesajı Instagram tətbiqində görə bilərsiniz.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Bu mesaj dəstəklənmir. Bu mesajı Instagram tətbiqində görə bilərsiniz.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "Bu mesaj dəstəklənmir. Bu mesajı TikTok tətbiqində görə bilərsiniz.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "Bu mesaj dəstəklənmir. Bu mesajı TikTok tətbiqində görə bilərsiniz.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Mesaj uğurla silindi",
|
"SUCCESS_DELETE_MESSAGE": "Mesaj uğurla silindi",
|
||||||
"FAIL_DELETE_MESSSAGE": "Mesajı silmək mümkün olmadı! Yenidən cəhd edin",
|
"FAIL_DELETE_MESSSAGE": "Mesajı silmək mümkün olmadı! Yenidən cəhd edin",
|
||||||
"NO_RESPONSE": "Cavab yoxdur",
|
"NO_RESPONSE": "Cavab yoxdur",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Gedən zəng",
|
"OUTGOING_CALL": "Gedən zəng",
|
||||||
"CALL_IN_PROGRESS": "Zəng davam edir",
|
"CALL_IN_PROGRESS": "Zəng davam edir",
|
||||||
"NO_ANSWER": "Cavab yoxdur",
|
"NO_ANSWER": "Cavab yoxdur",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "Cavab yoxdur",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Qeyri-işlək zəng",
|
"MISSED_CALL": "Qeyri-işlək zəng",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Zəng bitdi",
|
"CALL_ENDED": "Zəng bitdi",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Hələ cavab verilməyib",
|
"NOT_ANSWERED_YET": "Hələ cavab verilməyib",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "Onlar cavab verdi",
|
"THEY_ANSWERED": "Onlar cavab verdi",
|
||||||
"YOU_ANSWERED": "Siz cavab verdiniz",
|
"YOU_ANSWERED": "Siz cavab verdiniz",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Zəngə qoşul"
|
"JOIN_CALL": "Zəngə qoşul",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Həll et",
|
"RESOLVE_ACTION": "Həll et",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Sabaha qədər təxirə salındı",
|
"SNOOZED_UNTIL_TOMORROW": "Sabaha qədər təxirə salındı",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Gələn həftəyə qədər təxirə salındı",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Gələn həftəyə qədər təxirə salındı",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Növbəti cavaba qədər təxirə salındı",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Növbəti cavaba qədər təxirə salındı",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Səs yaz",
|
"TIP_AUDIORECORDER_ICON": "Səs yaz",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Səsə girişə icazə ver",
|
"TIP_AUDIORECORDER_PERMISSION": "Səsə girişə icazə ver",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Səsi açmaq mümkün olmadı",
|
"TIP_AUDIORECORDER_ERROR": "Səsi açmaq mümkün olmadı",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Qoşmaq üçün buraya sürükləyin və buraxın",
|
"DRAG_DROP": "Qoşmaq üçün buraya sürükləyin və buraxın",
|
||||||
"START_AUDIO_RECORDING": "Səs yazısını başla",
|
"START_AUDIO_RECORDING": "Səs yazısını başla",
|
||||||
"STOP_AUDIO_RECORDING": "Səs yazısını dayandırın",
|
"STOP_AUDIO_RECORDING": "Səs yazısını dayandırın",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Hələ cavab verilməyib",
|
"NOT_ANSWERED_YET": "Hələ cavab verilməyib",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Başqa sekmədə işlənir",
|
"HANDLED_IN_ANOTHER_TAB": "Başqa sekmədə işlənir",
|
||||||
"REJECT_CALL": "İmtina et",
|
"REJECT_CALL": "İmtina et",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "Zəngə qoşul",
|
"JOIN_CALL": "Zəngə qoşul",
|
||||||
"END_CALL": "Zəngi bitir"
|
"END_CALL": "Zəngi bitir",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "Qaralama",
|
"DRAFT": "Qaralama",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "Tərcümə et",
|
"TRANSLATE": "Tərcümə et",
|
||||||
|
"MOVE_TO_CATEGORY": "Category",
|
||||||
"DELETE": "Delete",
|
"DELETE": "Delete",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Delete",
|
"DELETE_CONFIRM": "Delete",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "Sil"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "Portal created successfully",
|
"SUCCESS_MESSAGE": "Portal created successfully",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Meta ilə autentifikasiya olunur",
|
"AUTH_PROCESSING": "Meta ilə autentifikasiya olunur",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Zəhmət olmasa Meta pəncərəsində biznes quraşdırmasını tamamlayın...",
|
"WAITING_FOR_BUSINESS_INFO": "Zəhmət olmasa Meta pəncərəsində biznes quraşdırmasını tamamlayın...",
|
||||||
"PROCESSING": "WhatsApp Biznes Hesabınızı quraşdırırıq",
|
"PROCESSING": "WhatsApp Biznes Hesabınızı quraşdırırıq",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Facebook SDK yüklənir...",
|
"LOADING_SDK": "Facebook SDK yüklənir...",
|
||||||
"CANCELLED": "WhatsApp Qeydiyyatı ləğv edildi",
|
"CANCELLED": "WhatsApp Qeydiyyatı ləğv edildi",
|
||||||
"SUCCESS_TITLE": "WhatsApp Biznes Hesabı Qoşuldu!",
|
"SUCCESS_TITLE": "WhatsApp Biznes Hesabı Qoşuldu!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Autentifikasiya tamamlanmadı. Zəhmət olmasa prosesi yenidən başladın.",
|
"AUTH_NOT_COMPLETED": "Autentifikasiya tamamlanmadı. Zəhmət olmasa prosesi yenidən başladın.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Biznes Hesabı uğurla konfiqurasiya edildi",
|
"SUCCESS_FALLBACK": "WhatsApp Biznes Hesabı uğurla konfiqurasiya edildi",
|
||||||
"MANUAL_FALLBACK": "Əgər nömrəniz artıq WhatsApp Business Platformasına (API) qoşulubsa və ya texnoloji təminatçı olaraq öz nömrənizi əlavə edirsinizsə, zəhmət olmasa {link} prosesindən istifadə edin",
|
"MANUAL_FALLBACK": "Əgər nömrəniz artıq WhatsApp Business Platformasına (API) qoşulubsa və ya texnoloji təminatçı olaraq öz nömrənizi əlavə edirsinizsə, zəhmət olmasa {link} prosesindən istifadə edin",
|
||||||
"MANUAL_LINK_TEXT": "əl ilə qurma prosesi"
|
"MANUAL_LINK_TEXT": "əl ilə qurma prosesi",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "WhatsApp kanalını yadda saxlaya bilmədik"
|
"ERROR_MESSAGE": "WhatsApp kanalını yadda saxlaya bilmədik"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "Müştərilərinizi WhatsApp-da dəstəkləyin"
|
"DESCRIPTION": "Müştərilərinizi WhatsApp-da dəstəkləyin"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "Elektron Poçt",
|
"TITLE": "Elektron Poçt",
|
||||||
"DESCRIPTION": "Gmail, Outlook və ya digər təminatçılarla qoşulun"
|
"DESCRIPTION": "Gmail, Outlook və ya digər təminatçılarla qoşulun"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "Bot Konfiqurasiyası",
|
"BOT_CONFIGURATION": "Bot Konfiqurasiyası",
|
||||||
"ACCOUNT_HEALTH": "Hesabın sağlamlığı",
|
"ACCOUNT_HEALTH": "Hesabın sağlamlığı",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "Səs"
|
"VOICE": "Səs",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Kanal üstünlükləri",
|
"CHANNEL_PREFERENCES": "Kanal üstünlükləri",
|
||||||
"WIDGET_FEATURES": "Widget xüsusiyyətləri",
|
"WIDGET_FEATURES": "Widget xüsusiyyətləri",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Mövcud şablonlarınızı yeniləmək üçün WhatsApp-dan mesaj şablonlarını əl ilə sinxronlaşdırın.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Mövcud şablonlarınızı yeniləmək üçün WhatsApp-dan mesaj şablonlarını əl ilə sinxronlaşdırın.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Şablonları sinxronlaşdır",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Şablonları sinxronlaşdır",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Şablonların sinxronizasiyası uğurla başlandı. Yenilənməsi bir neçə dəqiqə çəkə bilər.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Şablonların sinxronizasiyası uğurla başlandı. Yenilənməsi bir neçə dəqiqə çəkə bilər.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Pre Chat Form Parametrlərini Yeniləyin"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Pre Chat Form Parametrlərini Yeniləyin"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Əlaqə yaradıldı",
|
"CONTACT_CREATED": "Əlaqə yaradıldı",
|
||||||
"CONTACT_UPDATED": "Əlaqə yeniləndi",
|
"CONTACT_UPDATED": "Əlaqə yeniləndi",
|
||||||
"CONVERSATION_TYPING_ON": "Söhbət Yazılır",
|
"CONVERSATION_TYPING_ON": "Söhbət Yazılır",
|
||||||
"CONVERSATION_TYPING_OFF": "Söhbət Yazması Söndürülüb"
|
"CONVERSATION_TYPING_OFF": "Söhbət Yazması Söndürülüb",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
||||||
"AGENT_SELECT_LABEL": "Изберете агент",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Go back",
|
|
||||||
"ASSIGN_LABEL": "Assign",
|
|
||||||
"NONE": "None",
|
"NONE": "None",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||||
"AGENT_LIST_LOADING": "Loading agents",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Change status",
|
"CHANGE_STATUS": "Change status",
|
||||||
"SNOOZE_UNTIL": "Snooze",
|
"SNOOZE_UNTIL": "Snooze",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "Няма намерени етикети",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Изберете екип",
|
|
||||||
"NONE": "Нито един",
|
"NONE": "Нито един",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Завършено",
|
"COMPLETED": "Завършено",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Завършено",
|
"COMPLETED": "Завършено",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Assign Labels",
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
|
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
|
||||||
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
|
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
|
||||||
"NO_RESPONSE": "No response",
|
"NO_RESPONSE": "No response",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Resolve",
|
"RESOLVE_ACTION": "Resolve",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Snoozed until next reply",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Snoozed until next reply",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Record audio",
|
"TIP_AUDIORECORDER_ICON": "Record audio",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Allow access to audio",
|
"TIP_AUDIORECORDER_PERMISSION": "Allow access to audio",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Could not open the audio",
|
"TIP_AUDIORECORDER_ERROR": "Could not open the audio",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Drag and drop here to attach",
|
"DRAG_DROP": "Drag and drop here to attach",
|
||||||
"START_AUDIO_RECORDING": "Start audio recording",
|
"START_AUDIO_RECORDING": "Start audio recording",
|
||||||
"STOP_AUDIO_RECORDING": "Stop audio recording",
|
"STOP_AUDIO_RECORDING": "Stop audio recording",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "Draft",
|
"DRAFT": "Draft",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "Translate",
|
"TRANSLATE": "Translate",
|
||||||
|
"MOVE_TO_CATEGORY": "Category",
|
||||||
"DELETE": "Изтрий",
|
"DELETE": "Изтрий",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Изтрий",
|
"DELETE_CONFIRM": "Изтрий",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "Remove"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "Portal created successfully",
|
"SUCCESS_MESSAGE": "Portal created successfully",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Authenticating with Meta",
|
"AUTH_PROCESSING": "Authenticating with Meta",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
||||||
"PROCESSING": "Setting up your WhatsApp Business Account",
|
"PROCESSING": "Setting up your WhatsApp Business Account",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Loading Facebook SDK...",
|
"LOADING_SDK": "Loading Facebook SDK...",
|
||||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
||||||
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
||||||
"MANUAL_LINK_TEXT": "manual setup flow"
|
"MANUAL_LINK_TEXT": "manual setup flow",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
|
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "Support your customers on WhatsApp"
|
"DESCRIPTION": "Support your customers on WhatsApp"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "Email",
|
"TITLE": "Email",
|
||||||
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "Bot Configuration",
|
"BOT_CONFIGURATION": "Bot Configuration",
|
||||||
"ACCOUNT_HEALTH": "Account Health",
|
"ACCOUNT_HEALTH": "Account Health",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "Voice"
|
"VOICE": "Voice",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Channel Preferences",
|
"CHANNEL_PREFERENCES": "Channel Preferences",
|
||||||
"WIDGET_FEATURES": "Widget features",
|
"WIDGET_FEATURES": "Widget features",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Contact created",
|
"CONTACT_CREATED": "Contact created",
|
||||||
"CONTACT_UPDATED": "Contact updated",
|
"CONTACT_UPDATED": "Contact updated",
|
||||||
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
||||||
"CONVERSATION_TYPING_OFF": "Conversation Typing Off"
|
"CONVERSATION_TYPING_OFF": "Conversation Typing Off",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
||||||
"AGENT_SELECT_LABEL": "Select agent",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Go back",
|
|
||||||
"ASSIGN_LABEL": "Assign",
|
|
||||||
"NONE": "কিছুই না",
|
"NONE": "কিছুই না",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||||
"AGENT_LIST_LOADING": "Loading agents",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Change status",
|
"CHANGE_STATUS": "Change status",
|
||||||
"SNOOZE_UNTIL": "Snooze",
|
"SNOOZE_UNTIL": "Snooze",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Select team",
|
|
||||||
"NONE": "None",
|
"NONE": "None",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "প্রক্রিয়াধীন",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "প্রক্রিয়াধীন",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Assign Labels",
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "এই বার্তাটি সমর্থিত নয়। আপনি Facebook Messenger অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "এই বার্তাটি সমর্থিত নয়। আপনি Facebook Messenger অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "এই বার্তাটি সমর্থিত নয়। আপনি Instagram অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "এই বার্তাটি সমর্থিত নয়। আপনি Instagram অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "এই বার্তাটি সমর্থিত নয়। TikTok অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "এই বার্তাটি সমর্থিত নয়। TikTok অ্যাপে এই বার্তাটি দেখতে পারেন।",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "বার্তা সফলভাবে মুছে ফেলা হয়েছে",
|
"SUCCESS_DELETE_MESSAGE": "বার্তা সফলভাবে মুছে ফেলা হয়েছে",
|
||||||
"FAIL_DELETE_MESSSAGE": "বার্তা মুছে ফেলা যায়নি! আবার চেষ্টা করুন",
|
"FAIL_DELETE_MESSSAGE": "বার্তা মুছে ফেলা যায়নি! আবার চেষ্টা করুন",
|
||||||
"NO_RESPONSE": "কোনো উত্তর নেই",
|
"NO_RESPONSE": "কোনো উত্তর নেই",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "আউটগোয়িং কল",
|
"OUTGOING_CALL": "আউটগোয়িং কল",
|
||||||
"CALL_IN_PROGRESS": "কল চলছে",
|
"CALL_IN_PROGRESS": "কল চলছে",
|
||||||
"NO_ANSWER": "উত্তর নেই",
|
"NO_ANSWER": "উত্তর নেই",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "উত্তর নেই",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "মিসড কল",
|
"MISSED_CALL": "মিসড কল",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "কল শেষ হয়েছে",
|
"CALL_ENDED": "কল শেষ হয়েছে",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "এখনও উত্তর পাওয়া যায়নি",
|
"NOT_ANSWERED_YET": "এখনও উত্তর পাওয়া যায়নি",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "তারা উত্তর দিয়েছে",
|
"THEY_ANSWERED": "তারা উত্তর দিয়েছে",
|
||||||
"YOU_ANSWERED": "আপনি উত্তর দিয়েছেন",
|
"YOU_ANSWERED": "আপনি উত্তর দিয়েছেন",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "কলে যোগ দিন"
|
"JOIN_CALL": "কলে যোগ দিন",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "সমাধান করুন",
|
"RESOLVE_ACTION": "সমাধান করুন",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "আগামীকাল পর্যন্ত স্থগিত",
|
"SNOOZED_UNTIL_TOMORROW": "আগামীকাল পর্যন্ত স্থগিত",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "পরবর্তী সপ্তাহ পর্যন্ত স্থগিত",
|
"SNOOZED_UNTIL_NEXT_WEEK": "পরবর্তী সপ্তাহ পর্যন্ত স্থগিত",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "পরবর্তী উত্তর পর্যন্ত স্থগিত",
|
"SNOOZED_UNTIL_NEXT_REPLY": "পরবর্তী উত্তর পর্যন্ত স্থগিত",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "অডিও রেকর্ড করুন",
|
"TIP_AUDIORECORDER_ICON": "অডিও রেকর্ড করুন",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "অডিও অ্যাক্সেসের অনুমতি দিন",
|
"TIP_AUDIORECORDER_PERMISSION": "অডিও অ্যাক্সেসের অনুমতি দিন",
|
||||||
"TIP_AUDIORECORDER_ERROR": "অডিও খোলা যায়নি",
|
"TIP_AUDIORECORDER_ERROR": "অডিও খোলা যায়নি",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "সংযুক্ত করতে এখানে ড্র্যাগ ও ড্রপ করুন",
|
"DRAG_DROP": "সংযুক্ত করতে এখানে ড্র্যাগ ও ড্রপ করুন",
|
||||||
"START_AUDIO_RECORDING": "অডিও রেকর্ডিং শুরু করুন",
|
"START_AUDIO_RECORDING": "অডিও রেকর্ডিং শুরু করুন",
|
||||||
"STOP_AUDIO_RECORDING": "অডিও রেকর্ডিং বন্ধ করুন",
|
"STOP_AUDIO_RECORDING": "অডিও রেকর্ডিং বন্ধ করুন",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "এখনও উত্তর পাওয়া যায়নি",
|
"NOT_ANSWERED_YET": "এখনও উত্তর পাওয়া যায়নি",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "অন্য ট্যাবে পরিচালিত হচ্ছে",
|
"HANDLED_IN_ANOTHER_TAB": "অন্য ট্যাবে পরিচালিত হচ্ছে",
|
||||||
"REJECT_CALL": "প্রত্যাখ্যান করুন",
|
"REJECT_CALL": "প্রত্যাখ্যান করুন",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "কলে যোগ দিন",
|
"JOIN_CALL": "কলে যোগ দিন",
|
||||||
"END_CALL": "কল শেষ করুন"
|
"END_CALL": "কল শেষ করুন",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "খসড়া",
|
"DRAFT": "খসড়া",
|
||||||
"ARCHIVE": "আর্কাইভ",
|
"ARCHIVE": "আর্কাইভ",
|
||||||
"TRANSLATE": "অনুবাদ করুন",
|
"TRANSLATE": "অনুবাদ করুন",
|
||||||
|
"MOVE_TO_CATEGORY": "Category",
|
||||||
"DELETE": "মুছে ফেলুন",
|
"DELETE": "মুছে ফেলুন",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "মুছে ফেলুন",
|
"DELETE_CONFIRM": "মুছে ফেলুন",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "কনফিগারেশন সম্পাদনা করুন"
|
"EDIT_CONFIGURATION": "কনফিগারেশন সম্পাদনা করুন"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "সরান"
|
||||||
|
},
|
||||||
|
"SAVE": "পরিবর্তন সংরক্ষণ করুন"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "পোর্টাল সফলভাবে তৈরি হয়েছে",
|
"SUCCESS_MESSAGE": "পোর্টাল সফলভাবে তৈরি হয়েছে",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Meta-র সাথে প্রমাণীকরণ চলছে",
|
"AUTH_PROCESSING": "Meta-র সাথে প্রমাণীকরণ চলছে",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "অনুগ্রহ করে Meta উইন্ডোতে ব্যবসার সেটআপ সম্পন্ন করুন...",
|
"WAITING_FOR_BUSINESS_INFO": "অনুগ্রহ করে Meta উইন্ডোতে ব্যবসার সেটআপ সম্পন্ন করুন...",
|
||||||
"PROCESSING": "আপনার WhatsApp Business Account সেটআপ করা হচ্ছে",
|
"PROCESSING": "আপনার WhatsApp Business Account সেটআপ করা হচ্ছে",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Facebook SDK লোড হচ্ছে...",
|
"LOADING_SDK": "Facebook SDK লোড হচ্ছে...",
|
||||||
"CANCELLED": "WhatsApp সাইনআপ বাতিল করা হয়েছে",
|
"CANCELLED": "WhatsApp সাইনআপ বাতিল করা হয়েছে",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account সংযুক্ত হয়েছে!",
|
"SUCCESS_TITLE": "WhatsApp Business Account সংযুক্ত হয়েছে!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "প্রমাণীকরণ সম্পন্ন হয়নি। অনুগ্রহ করে প্রক্রিয়াটি পুনরায় শুরু করুন।.",
|
"AUTH_NOT_COMPLETED": "প্রমাণীকরণ সম্পন্ন হয়নি। অনুগ্রহ করে প্রক্রিয়াটি পুনরায় শুরু করুন।.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account সফলভাবে কনফিগার করা হয়েছে",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account সফলভাবে কনফিগার করা হয়েছে",
|
||||||
"MANUAL_FALLBACK": "আপনার নম্বর যদি ইতিমধ্যে WhatsApp Business Platform (API)-এর সাথে সংযুক্ত থাকে, অথবা আপনি যদি নিজস্ব নম্বর অনবোর্ড করতে টেক প্রোভাইডার হন, তাহলে অনুগ্রহ করে {link} ফ্লো ব্যবহার করুন",
|
"MANUAL_FALLBACK": "আপনার নম্বর যদি ইতিমধ্যে WhatsApp Business Platform (API)-এর সাথে সংযুক্ত থাকে, অথবা আপনি যদি নিজস্ব নম্বর অনবোর্ড করতে টেক প্রোভাইডার হন, তাহলে অনুগ্রহ করে {link} ফ্লো ব্যবহার করুন",
|
||||||
"MANUAL_LINK_TEXT": "ম্যানুয়াল সেটআপ ফ্লো"
|
"MANUAL_LINK_TEXT": "ম্যানুয়াল সেটআপ ফ্লো",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "আমরা WhatsApp চ্যানেল সংরক্ষণ করতে পারিনি"
|
"ERROR_MESSAGE": "আমরা WhatsApp চ্যানেল সংরক্ষণ করতে পারিনি"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "WhatsApp-এ আপনার গ্রাহকদের সহায়তা দিন"
|
"DESCRIPTION": "WhatsApp-এ আপনার গ্রাহকদের সহায়তা দিন"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "ইমেইল",
|
"TITLE": "ইমেইল",
|
||||||
"DESCRIPTION": "Gmail, Outlook, অথবা অন্যান্য প্রদানকারীর সাথে সংযোগ করুন"
|
"DESCRIPTION": "Gmail, Outlook, অথবা অন্যান্য প্রদানকারীর সাথে সংযোগ করুন"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "বট কনফিগারেশন",
|
"BOT_CONFIGURATION": "বট কনফিগারেশন",
|
||||||
"ACCOUNT_HEALTH": "অ্যাকাউন্টের স্বাস্থ্য",
|
"ACCOUNT_HEALTH": "অ্যাকাউন্টের স্বাস্থ্য",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "ভয়েস"
|
"VOICE": "ভয়েস",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "চ্যানেল পছন্দসমূহ",
|
"CHANNEL_PREFERENCES": "চ্যানেল পছন্দসমূহ",
|
||||||
"WIDGET_FEATURES": "উইজেট ফিচারসমূহ",
|
"WIDGET_FEATURES": "উইজেট ফিচারসমূহ",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "আপনার উপলব্ধ টেমপ্লেট আপডেট করতে WhatsApp থেকে মেসেজ টেমপ্লেটগুলো ম্যানুয়ালি সিঙ্ক করুন।.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "আপনার উপলব্ধ টেমপ্লেট আপডেট করতে WhatsApp থেকে মেসেজ টেমপ্লেটগুলো ম্যানুয়ালি সিঙ্ক করুন।.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "টেমপ্লেট সিঙ্ক করুন",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "টেমপ্লেট সিঙ্ক করুন",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "টেমপ্লেট সিঙ্ক সফলভাবে শুরু হয়েছে। আপডেট হতে কয়েক মিনিট সময় লাগতে পারে।.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "টেমপ্লেট সিঙ্ক সফলভাবে শুরু হয়েছে। আপডেট হতে কয়েক মিনিট সময় লাগতে পারে।.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "প্রি-চ্যাট ফর্ম সেটিংস আপডেট করুন"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "প্রি-চ্যাট ফর্ম সেটিংস আপডেট করুন"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "যোগাযোগ তৈরি হয়েছে",
|
"CONTACT_CREATED": "যোগাযোগ তৈরি হয়েছে",
|
||||||
"CONTACT_UPDATED": "যোগাযোগ আপডেট হয়েছে",
|
"CONTACT_UPDATED": "যোগাযোগ আপডেট হয়েছে",
|
||||||
"CONVERSATION_TYPING_ON": "কথোপকথন টাইপিং চালু আছে",
|
"CONVERSATION_TYPING_ON": "কথোপকথন টাইপিং চালু আছে",
|
||||||
"CONVERSATION_TYPING_OFF": "কথোপকথন টাইপিং বন্ধ আছে"
|
"CONVERSATION_TYPING_OFF": "কথোপকথন টাইপিং বন্ধ আছে",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} converses seleccionades",
|
"CONVERSATIONS_SELECTED": "{conversationCount} converses seleccionades",
|
||||||
"AGENT_SELECT_LABEL": "Seleccionar Agent",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Estas segur d'assignar {conversationCount} {conversationLabel} a",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Estàs segur de desassignar {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Torna",
|
|
||||||
"ASSIGN_LABEL": "Assignar",
|
|
||||||
"NONE": "Ningú",
|
"NONE": "Ningú",
|
||||||
"CLEAR_SELECTION": "Neteja",
|
"CLEAR_SELECTION": "Neteja",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Les converses s'han resolt correctament.",
|
"RESOLVE_SUCCESFUL": "Les converses s'han resolt correctament.",
|
||||||
"RESOLVE_FAILED": "No s'han pogut resoldre les converses. Torna-ho a provar.",
|
"RESOLVE_FAILED": "No s'han pogut resoldre les converses. Torna-ho a provar.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Les converses visibles en aquesta pàgina només estan seleccionades.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Les converses visibles en aquesta pàgina només estan seleccionades.",
|
||||||
"AGENT_LIST_LOADING": "S'estan carregant els agents",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Canvia l'estat",
|
"CHANGE_STATUS": "Canvia l'estat",
|
||||||
"SNOOZE_UNTIL": "Posposat",
|
"SNOOZE_UNTIL": "Posposat",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assignar etiquetes",
|
"ASSIGN_LABELS": "Assignar etiquetes",
|
||||||
"NO_LABELS_FOUND": "No s'han trobat etiquetes",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assigna les etiquetes seleccionades",
|
"ASSIGN_SELECTED_LABELS": "Assigna les etiquetes seleccionades",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "L'etiqueta s'ha assignat correctament.",
|
"ASSIGN_SUCCESFUL": "L'etiqueta s'ha assignat correctament.",
|
||||||
"ASSIGN_FAILED": "No s'han pogut assignar les etiquetes. Torna-ho a provar."
|
"ASSIGN_FAILED": "No s'han pogut assignar les etiquetes. Torna-ho a provar.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Selecciona equip",
|
|
||||||
"NONE": "Ningú",
|
"NONE": "Ningú",
|
||||||
"NO_TEAMS_AVAILABLE": "Encara no hi ha cap equip afegit a aquest compte.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assigna l'equip seleccionat.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Equips assignats correctament.",
|
"ASSIGN_SUCCESFUL": "Equips assignats correctament.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completat",
|
"COMPLETED": "Completat",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completat",
|
"COMPLETED": "Completat",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Assign Labels",
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "L'etiqueta s'ha assignat correctament.",
|
"ASSIGN_LABELS_SUCCESS": "L'etiqueta s'ha assignat correctament.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "Aquest missatge no està suportat. Pots veure aquest missatge a l'aplicació Facebook Messenger.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "Aquest missatge no està suportat. Pots veure aquest missatge a l'aplicació Facebook Messenger.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Aquest missatge no està suportat. Pots veure aquest missatge a l'aplicació d'Instagram.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Aquest missatge no està suportat. Pots veure aquest missatge a l'aplicació d'Instagram.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "El missatge s'ha suprimit correctament",
|
"SUCCESS_DELETE_MESSAGE": "El missatge s'ha suprimit correctament",
|
||||||
"FAIL_DELETE_MESSSAGE": "No s'ha pogut suprimir el missatge! Torna-ho a provar",
|
"FAIL_DELETE_MESSSAGE": "No s'ha pogut suprimir el missatge! Torna-ho a provar",
|
||||||
"NO_RESPONSE": "Sense resposta",
|
"NO_RESPONSE": "Sense resposta",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Resoldre",
|
"RESOLVE_ACTION": "Resoldre",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Posposat fins demà",
|
"SNOOZED_UNTIL_TOMORROW": "Posposat fins demà",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Posposat fins a la setmana vinent",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Posposat fins a la setmana vinent",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Posposat fins a la següent resposta",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Posposat fins a la següent resposta",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Gravar àudio",
|
"TIP_AUDIORECORDER_ICON": "Gravar àudio",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Permet l'accés a l'àudio",
|
"TIP_AUDIORECORDER_PERMISSION": "Permet l'accés a l'àudio",
|
||||||
"TIP_AUDIORECORDER_ERROR": "No s'ha pogut obrir l'àudio",
|
"TIP_AUDIORECORDER_ERROR": "No s'ha pogut obrir l'àudio",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Arrossega i deixa anar aquí per adjuntar-lo",
|
"DRAG_DROP": "Arrossega i deixa anar aquí per adjuntar-lo",
|
||||||
"START_AUDIO_RECORDING": "Inicia la gravació d'àudio",
|
"START_AUDIO_RECORDING": "Inicia la gravació d'àudio",
|
||||||
"STOP_AUDIO_RECORDING": "Atura la gravació d'àudio",
|
"STOP_AUDIO_RECORDING": "Atura la gravació d'àudio",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Descartar",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "Esborrany",
|
"DRAFT": "Esborrany",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "Tradueix",
|
"TRANSLATE": "Tradueix",
|
||||||
|
"MOVE_TO_CATEGORY": "Categoria",
|
||||||
"DELETE": "Esborrar",
|
"DELETE": "Esborrar",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Esborrar",
|
"DELETE_CONFIRM": "Esborrar",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Aparença",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "Suprimeix"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "Portal creat correctament",
|
"SUCCESS_MESSAGE": "Portal creat correctament",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Authenticating with Meta",
|
"AUTH_PROCESSING": "Authenticating with Meta",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
||||||
"PROCESSING": "Setting up your WhatsApp Business Account",
|
"PROCESSING": "Setting up your WhatsApp Business Account",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Loading Facebook SDK...",
|
"LOADING_SDK": "Loading Facebook SDK...",
|
||||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
||||||
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
||||||
"MANUAL_LINK_TEXT": "manual setup flow"
|
"MANUAL_LINK_TEXT": "manual setup flow",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "No hem pogut desar el canal WhatsApp"
|
"ERROR_MESSAGE": "No hem pogut desar el canal WhatsApp"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "Support your customers on WhatsApp"
|
"DESCRIPTION": "Support your customers on WhatsApp"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "Correu electrònic",
|
"TITLE": "Correu electrònic",
|
||||||
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "Configuracions del bot",
|
"BOT_CONFIGURATION": "Configuracions del bot",
|
||||||
"ACCOUNT_HEALTH": "Account Health",
|
"ACCOUNT_HEALTH": "Account Health",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "Voice"
|
"VOICE": "Voice",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Channel Preferences",
|
"CHANNEL_PREFERENCES": "Channel Preferences",
|
||||||
"WIDGET_FEATURES": "Widget features",
|
"WIDGET_FEATURES": "Widget features",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Actualitza la configuració del formulari de xat prèvia"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Actualitza la configuració del formulari de xat prèvia"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Contacte creat",
|
"CONTACT_CREATED": "Contacte creat",
|
||||||
"CONTACT_UPDATED": "Contacte actualitzat",
|
"CONTACT_UPDATED": "Contacte actualitzat",
|
||||||
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
||||||
"CONVERSATION_TYPING_OFF": "Conversation Typing Off"
|
"CONVERSATION_TYPING_OFF": "Conversation Typing Off",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
"CONVERSATIONS_SELECTED": "{conversationCount} conversations selected",
|
||||||
"AGENT_SELECT_LABEL": "Vybrat agenta",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Go back",
|
|
||||||
"ASSIGN_LABEL": "Přiřadit",
|
|
||||||
"NONE": "Nic",
|
"NONE": "Nic",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
"RESOLVE_SUCCESFUL": "Conversations resolved successfully.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||||
"AGENT_LIST_LOADING": "Načítání agentů",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Change status",
|
"CHANGE_STATUS": "Change status",
|
||||||
"SNOOZE_UNTIL": "Odložit",
|
"SNOOZE_UNTIL": "Odložit",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Vybrat tým",
|
|
||||||
"NONE": "Nic",
|
"NONE": "Nic",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Completed",
|
"COMPLETED": "Completed",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Assign Labels",
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Zpráva byla úspěšně smazána",
|
"SUCCESS_DELETE_MESSAGE": "Zpráva byla úspěšně smazána",
|
||||||
"FAIL_DELETE_MESSSAGE": "Zpráva se nepodařilo odstranit! Zkuste to znovu",
|
"FAIL_DELETE_MESSSAGE": "Zpráva se nepodařilo odstranit! Zkuste to znovu",
|
||||||
"NO_RESPONSE": "Bez odpovědi",
|
"NO_RESPONSE": "Bez odpovědi",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Vyřešit",
|
"RESOLVE_ACTION": "Vyřešit",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Odloženo do zítřka",
|
"SNOOZED_UNTIL_TOMORROW": "Odloženo do zítřka",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Odloženo do příštího týdne",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Odloženo do příštího týdne",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Odloženo do další odpovědi",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Odloženo do další odpovědi",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Nahrát zvuk",
|
"TIP_AUDIORECORDER_ICON": "Nahrát zvuk",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Povolit přístup ke zvuku",
|
"TIP_AUDIORECORDER_PERMISSION": "Povolit přístup ke zvuku",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Zvuk se nepodařilo otevřít",
|
"TIP_AUDIORECORDER_ERROR": "Zvuk se nepodařilo otevřít",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Přetažením sem připojíte",
|
"DRAG_DROP": "Přetažením sem připojíte",
|
||||||
"START_AUDIO_RECORDING": "Spustit nahrávání zvuku",
|
"START_AUDIO_RECORDING": "Spustit nahrávání zvuku",
|
||||||
"STOP_AUDIO_RECORDING": "Zastavit nahrávání zvuku",
|
"STOP_AUDIO_RECORDING": "Zastavit nahrávání zvuku",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "Koncept",
|
"DRAFT": "Koncept",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "Translate",
|
"TRANSLATE": "Translate",
|
||||||
|
"MOVE_TO_CATEGORY": "Category",
|
||||||
"DELETE": "Vymazat",
|
"DELETE": "Vymazat",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Vymazat",
|
"DELETE_CONFIRM": "Vymazat",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "Odebrat"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "Portal created successfully",
|
"SUCCESS_MESSAGE": "Portal created successfully",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Authenticating with Meta",
|
"AUTH_PROCESSING": "Authenticating with Meta",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
||||||
"PROCESSING": "Setting up your WhatsApp Business Account",
|
"PROCESSING": "Setting up your WhatsApp Business Account",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Loading Facebook SDK...",
|
"LOADING_SDK": "Loading Facebook SDK...",
|
||||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
||||||
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
||||||
"MANUAL_LINK_TEXT": "manual setup flow"
|
"MANUAL_LINK_TEXT": "manual setup flow",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
|
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "Support your customers on WhatsApp"
|
"DESCRIPTION": "Support your customers on WhatsApp"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "E-mailová adresa",
|
"TITLE": "E-mailová adresa",
|
||||||
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "Bot Configuration",
|
"BOT_CONFIGURATION": "Bot Configuration",
|
||||||
"ACCOUNT_HEALTH": "Account Health",
|
"ACCOUNT_HEALTH": "Account Health",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "Voice"
|
"VOICE": "Voice",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Channel Preferences",
|
"CHANNEL_PREFERENCES": "Channel Preferences",
|
||||||
"WIDGET_FEATURES": "Widget features",
|
"WIDGET_FEATURES": "Widget features",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Contact created",
|
"CONTACT_CREATED": "Contact created",
|
||||||
"CONTACT_UPDATED": "Contact updated",
|
"CONTACT_UPDATED": "Contact updated",
|
||||||
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
||||||
"CONVERSATION_TYPING_OFF": "Conversation Typing Off"
|
"CONVERSATION_TYPING_OFF": "Conversation Typing Off",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} samtaler valgt",
|
"CONVERSATIONS_SELECTED": "{conversationCount} samtaler valgt",
|
||||||
"AGENT_SELECT_LABEL": "Vælg agent",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign {conversationCount} {conversationLabel} to",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign {conversationCount} {conversationLabel}?",
|
|
||||||
"GO_BACK_LABEL": "Gå tilbage",
|
|
||||||
"ASSIGN_LABEL": "Tildel",
|
|
||||||
"NONE": "Ingen",
|
"NONE": "Ingen",
|
||||||
"CLEAR_SELECTION": "Clear",
|
"CLEAR_SELECTION": "Clear",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Samtaler løst med succes.",
|
"RESOLVE_SUCCESFUL": "Samtaler løst med succes.",
|
||||||
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
"RESOLVE_FAILED": "Failed to resolve conversations. Please try again.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Samtaler synlig på denne side er kun valgt.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Samtaler synlig på denne side er kun valgt.",
|
||||||
"AGENT_LIST_LOADING": "Indlæser agenter",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Skift status",
|
"CHANGE_STATUS": "Skift status",
|
||||||
"SNOOZE_UNTIL": "Udsæt",
|
"SNOOZE_UNTIL": "Udsæt",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "Ingen labels fundet",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Tildel valgte etiketter",
|
"ASSIGN_SELECTED_LABELS": "Tildel valgte etiketter",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Etiketter tildelt med succes.",
|
"ASSIGN_SUCCESFUL": "Etiketter tildelt med succes.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Vælg hold",
|
|
||||||
"NONE": "Ingen",
|
"NONE": "Ingen",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Tildel det valgte team.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Teams assigned successfully.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Afsluttet",
|
"COMPLETED": "Afsluttet",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Afsluttet",
|
"COMPLETED": "Afsluttet",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Call",
|
"CALL": "Call",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Choose a voice inbox"
|
"TITLE": "Choose a voice inbox"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Tildel Etiketter",
|
"ASSIGN_LABELS": "Tildel Etiketter",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Etiketter tildelt med succes.",
|
"ASSIGN_LABELS_SUCCESS": "Etiketter tildelt med succes.",
|
||||||
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
"NO_LABELS_FOUND": "No labels available yet.",
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Besked slettet",
|
"SUCCESS_DELETE_MESSAGE": "Besked slettet",
|
||||||
"FAIL_DELETE_MESSSAGE": "Kunne ikke slette beskeden! Prøv igen",
|
"FAIL_DELETE_MESSSAGE": "Kunne ikke slette beskeden! Prøv igen",
|
||||||
"NO_RESPONSE": "Intet svar",
|
"NO_RESPONSE": "Intet svar",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Outgoing call",
|
"OUTGOING_CALL": "Outgoing call",
|
||||||
"CALL_IN_PROGRESS": "Call in progress",
|
"CALL_IN_PROGRESS": "Call in progress",
|
||||||
"NO_ANSWER": "No answer",
|
"NO_ANSWER": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "No answer",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Missed call",
|
"MISSED_CALL": "Missed call",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Call ended",
|
"CALL_ENDED": "Call ended",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "They answered",
|
"THEY_ANSWERED": "They answered",
|
||||||
"YOU_ANSWERED": "You answered",
|
"YOU_ANSWERED": "You answered",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Løs",
|
"RESOLVE_ACTION": "Løs",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Udsat til i morgen",
|
"SNOOZED_UNTIL_TOMORROW": "Udsat til i morgen",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Udsat indtil næste uge",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Udsat indtil næste uge",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Udsat indtil næste svar",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Udsat indtil næste svar",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Optag lyd",
|
"TIP_AUDIORECORDER_ICON": "Optag lyd",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Tillad adgang til lyd",
|
"TIP_AUDIORECORDER_PERMISSION": "Tillad adgang til lyd",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Kunne ikke åbne lyden",
|
"TIP_AUDIORECORDER_ERROR": "Kunne ikke åbne lyden",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Træk og slip her for at vedhæfte",
|
"DRAG_DROP": "Træk og slip her for at vedhæfte",
|
||||||
"START_AUDIO_RECORDING": "Start lydoptagelse",
|
"START_AUDIO_RECORDING": "Start lydoptagelse",
|
||||||
"STOP_AUDIO_RECORDING": "Stop lydoptagelse",
|
"STOP_AUDIO_RECORDING": "Stop lydoptagelse",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Not answered yet",
|
"NOT_ANSWERED_YET": "Not answered yet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Dismiss",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
@@ -607,9 +607,12 @@
|
|||||||
"DRAFT": "Kladde",
|
"DRAFT": "Kladde",
|
||||||
"ARCHIVE": "Archive",
|
"ARCHIVE": "Archive",
|
||||||
"TRANSLATE": "Translate",
|
"TRANSLATE": "Translate",
|
||||||
|
"MOVE_TO_CATEGORY": "Kategori",
|
||||||
"DELETE": "Slet",
|
"DELETE": "Slet",
|
||||||
"STATUS_SUCCESS": "Articles updated successfully",
|
"STATUS_SUCCESS": "Articles updated successfully",
|
||||||
"STATUS_ERROR": "Failed to update articles",
|
"STATUS_ERROR": "Failed to update articles",
|
||||||
|
"CATEGORY_SUCCESS": "Articles moved successfully",
|
||||||
|
"CATEGORY_ERROR": "Failed to move articles",
|
||||||
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
"DELETE_CONFIRM_TITLE": "Delete article | Delete {count} articles",
|
||||||
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
"DELETE_CONFIRM_DESCRIPTION": "This will permanently delete the selected article. This action cannot be undone. | This will permanently delete {count} selected articles. This action cannot be undone.",
|
||||||
"DELETE_CONFIRM": "Slet",
|
"DELETE_CONFIRM": "Slet",
|
||||||
@@ -866,6 +869,28 @@
|
|||||||
},
|
},
|
||||||
"EDIT_CONFIGURATION": "Edit configuration"
|
"EDIT_CONFIGURATION": "Edit configuration"
|
||||||
},
|
},
|
||||||
|
"LAYOUT_CONTENT": {
|
||||||
|
"HEADER": "Appearance",
|
||||||
|
"DESCRIPTION": "Pick the layout that fits how your visitors read.",
|
||||||
|
"LAYOUT": {
|
||||||
|
"CLASSIC": {
|
||||||
|
"TITLE": "Classic",
|
||||||
|
"DESCRIPTION": "A welcoming home page with search and featured topics."
|
||||||
|
},
|
||||||
|
"SIDEBAR": {
|
||||||
|
"TITLE": "Documentation",
|
||||||
|
"DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SOCIAL_LINKS": {
|
||||||
|
"HEADER": "Social links",
|
||||||
|
"DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
|
||||||
|
"PLACEHOLDER": "handle",
|
||||||
|
"ADD": "Add social link",
|
||||||
|
"REMOVE": "Fjern"
|
||||||
|
},
|
||||||
|
"SAVE": "Save changes"
|
||||||
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"CREATE_PORTAL": {
|
"CREATE_PORTAL": {
|
||||||
"SUCCESS_MESSAGE": "Portal oprettet",
|
"SUCCESS_MESSAGE": "Portal oprettet",
|
||||||
|
|||||||
@@ -308,6 +308,7 @@
|
|||||||
"AUTH_PROCESSING": "Authenticating with Meta",
|
"AUTH_PROCESSING": "Authenticating with Meta",
|
||||||
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
"WAITING_FOR_BUSINESS_INFO": "Please complete business setup in the Meta window...",
|
||||||
"PROCESSING": "Setting up your WhatsApp Business Account",
|
"PROCESSING": "Setting up your WhatsApp Business Account",
|
||||||
|
"ENABLING_CALLING": "Enabling WhatsApp Calling on your number…",
|
||||||
"LOADING_SDK": "Loading Facebook SDK...",
|
"LOADING_SDK": "Loading Facebook SDK...",
|
||||||
"CANCELLED": "WhatsApp Signup was cancelled",
|
"CANCELLED": "WhatsApp Signup was cancelled",
|
||||||
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
"SUCCESS_TITLE": "WhatsApp Business Account Connected!",
|
||||||
@@ -317,7 +318,8 @@
|
|||||||
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
"AUTH_NOT_COMPLETED": "Authentication not completed. Please restart the process.",
|
||||||
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
"SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured",
|
||||||
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
"MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow",
|
||||||
"MANUAL_LINK_TEXT": "manual setup flow"
|
"MANUAL_LINK_TEXT": "manual setup flow",
|
||||||
|
"CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings."
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"ERROR_MESSAGE": "Vi kunne ikke gemme WhatsApp-kanalen"
|
"ERROR_MESSAGE": "Vi kunne ikke gemme WhatsApp-kanalen"
|
||||||
@@ -465,6 +467,10 @@
|
|||||||
"TITLE": "WhatsApp",
|
"TITLE": "WhatsApp",
|
||||||
"DESCRIPTION": "Support your customers on WhatsApp"
|
"DESCRIPTION": "Support your customers on WhatsApp"
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALL": {
|
||||||
|
"TITLE": "WhatsApp Call",
|
||||||
|
"DESCRIPTION": "Take voice calls on your WhatsApp number"
|
||||||
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"TITLE": "E-mail",
|
"TITLE": "E-mail",
|
||||||
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
"DESCRIPTION": "Connect with Gmail, Outlook, or other providers"
|
||||||
@@ -637,7 +643,8 @@
|
|||||||
"BOT_CONFIGURATION": "Bot konfiguration",
|
"BOT_CONFIGURATION": "Bot konfiguration",
|
||||||
"ACCOUNT_HEALTH": "Account Health",
|
"ACCOUNT_HEALTH": "Account Health",
|
||||||
"CSAT": "CSAT",
|
"CSAT": "CSAT",
|
||||||
"VOICE": "Voice"
|
"VOICE": "Voice",
|
||||||
|
"CALLS": "Calls"
|
||||||
},
|
},
|
||||||
"VOICE_CONFIGURATION": {
|
"VOICE_CONFIGURATION": {
|
||||||
"ENABLE_VOICE": {
|
"ENABLE_VOICE": {
|
||||||
@@ -648,6 +655,26 @@
|
|||||||
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
"DESCRIPTION": "Voice calling requires Twilio API Key credentials. These are used to generate tokens for agent voice connections."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WHATSAPP_CALLING": {
|
||||||
|
"ENABLE": {
|
||||||
|
"LABEL": "Enable WhatsApp Calling",
|
||||||
|
"DESCRIPTION": "Allow agents to receive and place WhatsApp Cloud calls on this inbox. Customers can call this business number directly from WhatsApp."
|
||||||
|
},
|
||||||
|
"ENABLE_FAILED": "Voice calling couldn't be turned on for this number — it isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then try again.",
|
||||||
|
"PHONE_NUMBER": {
|
||||||
|
"LABEL": "Business phone number",
|
||||||
|
"HELP_TEXT": "WhatsApp number that customers will call."
|
||||||
|
},
|
||||||
|
"HOW_IT_WORKS": {
|
||||||
|
"LABEL": "How it works",
|
||||||
|
"DESCRIPTION": "Calls are placed peer-to-peer between the agent's browser and Meta — no extra credentials are required. Make sure the agent's browser has microphone permission for this site."
|
||||||
|
},
|
||||||
|
"PERMISSION_REQUEST_BODY": {
|
||||||
|
"LABEL": "Call permission request message",
|
||||||
|
"HELP_TEXT": "Shown to the contact when they haven't yet consented to receive calls. Leave blank to use the default.",
|
||||||
|
"PLACEHOLDER": "We would like to call you regarding your conversation."
|
||||||
|
}
|
||||||
|
},
|
||||||
"CHANNEL_PREFERENCES": "Channel Preferences",
|
"CHANNEL_PREFERENCES": "Channel Preferences",
|
||||||
"WIDGET_FEATURES": "Widget features",
|
"WIDGET_FEATURES": "Widget features",
|
||||||
"ACCOUNT_HEALTH": {
|
"ACCOUNT_HEALTH": {
|
||||||
@@ -800,6 +827,10 @@
|
|||||||
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
"WHATSAPP_TEMPLATES_SYNC_SUBHEADER": "Manually sync message templates from WhatsApp to update your available templates.",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
"WHATSAPP_TEMPLATES_SYNC_BUTTON": "Sync Templates",
|
||||||
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
"WHATSAPP_TEMPLATES_SYNC_SUCCESS": "Templates sync initiated successfully. It may take a couple of minutes to update.",
|
||||||
|
"WHATSAPP_CALLING_ENABLED": {
|
||||||
|
"LABEL": "Enable voice calling",
|
||||||
|
"DESCRIPTION": "Allow agents to start and receive WhatsApp voice calls on this inbox. Available only on embedded-signup WhatsApp Cloud channels with calling permission granted by Meta."
|
||||||
|
},
|
||||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||||
},
|
},
|
||||||
"HELP_CENTER": {
|
"HELP_CENTER": {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"CONTACT_CREATED": "Contact created",
|
"CONTACT_CREATED": "Contact created",
|
||||||
"CONTACT_UPDATED": "Contact updated",
|
"CONTACT_UPDATED": "Contact updated",
|
||||||
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
"CONVERSATION_TYPING_ON": "Conversation Typing On",
|
||||||
"CONVERSATION_TYPING_OFF": "Conversation Typing Off"
|
"CONVERSATION_TYPING_OFF": "Conversation Typing Off",
|
||||||
|
"INBOX_UPDATED": "Inbox updated"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NAME": {
|
"NAME": {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "{conversationCount} Konversationen ausgewählt",
|
"CONVERSATIONS_SELECTED": "{conversationCount} Konversationen ausgewählt",
|
||||||
"AGENT_SELECT_LABEL": "Agent auswählen",
|
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Sind Sie sicher, {conversationCount} {conversationLabel} zuzuweisen",
|
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Möchten Sie die Zuweisung von {conversationCount} {conversationLabel} wirklich aufheben?",
|
|
||||||
"GO_BACK_LABEL": "Zurück",
|
|
||||||
"ASSIGN_LABEL": "Zuordnen",
|
|
||||||
"NONE": "Keine",
|
"NONE": "Keine",
|
||||||
"CLEAR_SELECTION": "Leeren",
|
"CLEAR_SELECTION": "Leeren",
|
||||||
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
"ASSIGN_AGENT_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {agentName}? | Are you sure you want to assign {n} conversations to {agentName}?",
|
||||||
@@ -20,7 +15,6 @@
|
|||||||
"RESOLVE_SUCCESFUL": "Konversationen erfolgreich gelöst.",
|
"RESOLVE_SUCCESFUL": "Konversationen erfolgreich gelöst.",
|
||||||
"RESOLVE_FAILED": "Konversationen konnten nicht gelöst werden. Bitte versuchen Sie es erneut.",
|
"RESOLVE_FAILED": "Konversationen konnten nicht gelöst werden. Bitte versuchen Sie es erneut.",
|
||||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Nur auf dieser Seite sichtbaren Konversationen sind ausgewählt.",
|
"ALL_CONVERSATIONS_SELECTED_ALERT": "Nur auf dieser Seite sichtbaren Konversationen sind ausgewählt.",
|
||||||
"AGENT_LIST_LOADING": "Agenten werden geladen",
|
|
||||||
"UPDATE": {
|
"UPDATE": {
|
||||||
"CHANGE_STATUS": "Status ändern",
|
"CHANGE_STATUS": "Status ändern",
|
||||||
"SNOOZE_UNTIL": "Erinnern",
|
"SNOOZE_UNTIL": "Erinnern",
|
||||||
@@ -33,16 +27,16 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Labels zuweisen",
|
"ASSIGN_LABELS": "Labels zuweisen",
|
||||||
"NO_LABELS_FOUND": "Keine Labels gefunden",
|
"REMOVE_LABELS": "Remove labels",
|
||||||
"ASSIGN_SELECTED_LABELS": "Ausgewählte Labels zuweisen",
|
"ASSIGN_SELECTED_LABELS": "Ausgewählte Labels zuweisen",
|
||||||
|
"REMOVE_SELECTED_LABELS": "Remove selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels erfolgreich zugewiesen.",
|
"ASSIGN_SUCCESFUL": "Labels erfolgreich zugewiesen.",
|
||||||
"ASSIGN_FAILED": "Labels konnten nicht zugewiesen werden. Bitte versuchen Sie es erneut."
|
"ASSIGN_FAILED": "Labels konnten nicht zugewiesen werden. Bitte versuchen Sie es erneut.",
|
||||||
|
"REMOVE_SUCCESFUL": "Labels removed successfully.",
|
||||||
|
"REMOVE_FAILED": "Failed to remove labels. Please try again."
|
||||||
},
|
},
|
||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "Team auswählen",
|
|
||||||
"NONE": "Keine",
|
"NONE": "Keine",
|
||||||
"NO_TEAMS_AVAILABLE": "Es wurden noch keine Teams zu diesem Konto hinzugefügt.",
|
|
||||||
"ASSIGN_SELECTED_TEAMS": "Ausgewähltes Team zuweisen.",
|
|
||||||
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
"ASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to assign {n} conversation to {teamName}? | Are you sure you want to assign {n} conversations to {teamName}?",
|
||||||
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
"UNASSIGN_TEAM_CONFIRMATION_LABEL": "Are you sure you want to unassign {n} conversation? | Are you sure you want to unassign {n} conversations?",
|
||||||
"ASSIGN_SUCCESFUL": "Teams erfolgreich zugewiesen.",
|
"ASSIGN_SUCCESFUL": "Teams erfolgreich zugewiesen.",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Erledigt",
|
"COMPLETED": "Erledigt",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
},
|
},
|
||||||
"CARD": {
|
"CARD": {
|
||||||
"STATUS": {
|
"STATUS": {
|
||||||
|
"PROCESSING": "Processing",
|
||||||
"COMPLETED": "Erledigt",
|
"COMPLETED": "Erledigt",
|
||||||
"SCHEDULED": "Scheduled"
|
"SCHEDULED": "Scheduled"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"CODE": "Code",
|
"CODE": "Code",
|
||||||
"BULLET_LIST": "Bullet List",
|
"BULLET_LIST": "Bullet List",
|
||||||
"ORDERED_LIST": "Ordered List",
|
"ORDERED_LIST": "Ordered List",
|
||||||
"TABLE": "Table"
|
"TABLE": "Table",
|
||||||
|
"IMAGE": "Image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
"CALL": "Anruf",
|
"CALL": "Anruf",
|
||||||
"CALL_INITIATED": "Calling the contact…",
|
"CALL_INITIATED": "Calling the contact…",
|
||||||
"CALL_FAILED": "Unable to start the call. Please try again.",
|
"CALL_FAILED": "Unable to start the call. Please try again.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"CLICK_TO_EDIT": "Click to edit",
|
"CLICK_TO_EDIT": "Click to edit",
|
||||||
"VOICE_INBOX_PICKER": {
|
"VOICE_INBOX_PICKER": {
|
||||||
"TITLE": "Spracheingang wählen"
|
"TITLE": "Spracheingang wählen"
|
||||||
@@ -583,8 +585,11 @@
|
|||||||
},
|
},
|
||||||
"CONTACTS_BULK_ACTIONS": {
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
"ASSIGN_LABELS": "Labels zuweisen",
|
"ASSIGN_LABELS": "Labels zuweisen",
|
||||||
|
"REMOVE_LABELS": "Remove Labels",
|
||||||
"ASSIGN_LABELS_SUCCESS": "Labels erfolgreich zugewiesen.",
|
"ASSIGN_LABELS_SUCCESS": "Labels erfolgreich zugewiesen.",
|
||||||
"ASSIGN_LABELS_FAILED": "Fehler beim Zuweisen der Labels",
|
"ASSIGN_LABELS_FAILED": "Fehler beim Zuweisen der Labels",
|
||||||
|
"REMOVE_LABELS_SUCCESS": "Labels removed successfully.",
|
||||||
|
"REMOVE_LABELS_FAILED": "Failed to remove labels",
|
||||||
"DESCRIPTION": "Wählen Sie die Labels aus, die zu den ausgewählten Kontakten hinzugefügt werden sollen.",
|
"DESCRIPTION": "Wählen Sie die Labels aus, die zu den ausgewählten Kontakten hinzugefügt werden sollen.",
|
||||||
"NO_LABELS_FOUND": "Noch keine Labels vorhanden.",
|
"NO_LABELS_FOUND": "Noch keine Labels vorhanden.",
|
||||||
"SELECTED_COUNT": "{count} selected",
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"UNSUPPORTED_MESSAGE_FACEBOOK": "Diese Nachricht wird nicht unterstützt. Sie können diese Nachricht in der Facebook-Messenger-App sehen.",
|
"UNSUPPORTED_MESSAGE_FACEBOOK": "Diese Nachricht wird nicht unterstützt. Sie können diese Nachricht in der Facebook-Messenger-App sehen.",
|
||||||
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Diese Nachricht wird nicht unterstützt. Sie können diese Nachricht in der Instagram-App sehen.",
|
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Diese Nachricht wird nicht unterstützt. Sie können diese Nachricht in der Instagram-App sehen.",
|
||||||
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
"UNSUPPORTED_MESSAGE_TIKTOK": "This message is unsupported. You can view this message on the TikTok app.",
|
||||||
|
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
|
||||||
"SUCCESS_DELETE_MESSAGE": "Nachricht erfolgreich gelöscht",
|
"SUCCESS_DELETE_MESSAGE": "Nachricht erfolgreich gelöscht",
|
||||||
"FAIL_DELETE_MESSSAGE": "Nachricht konnte nicht gelöscht werden! Versuchen Sie es erneut",
|
"FAIL_DELETE_MESSSAGE": "Nachricht konnte nicht gelöscht werden! Versuchen Sie es erneut",
|
||||||
"NO_RESPONSE": "Keine Antwort",
|
"NO_RESPONSE": "Keine Antwort",
|
||||||
@@ -79,13 +80,22 @@
|
|||||||
"OUTGOING_CALL": "Ausgehender Anruf",
|
"OUTGOING_CALL": "Ausgehender Anruf",
|
||||||
"CALL_IN_PROGRESS": "Anruf läuft",
|
"CALL_IN_PROGRESS": "Anruf läuft",
|
||||||
"NO_ANSWER": "Keine Antwort",
|
"NO_ANSWER": "Keine Antwort",
|
||||||
|
"NO_ANSWER_OUTBOUND_LABEL": "Keine Antwort",
|
||||||
|
"NO_ANSWER_OUTBOUND_SUBTEXT": "Contact didn't pick up",
|
||||||
"MISSED_CALL": "Entgangener Anruf",
|
"MISSED_CALL": "Entgangener Anruf",
|
||||||
|
"MISSED_CALL_INBOUND_SUBTEXT": "No agent picked up",
|
||||||
|
"MISSED_CALL_DECLINED_BY": "Declined by {agentName}",
|
||||||
"CALL_ENDED": "Anruf beendet",
|
"CALL_ENDED": "Anruf beendet",
|
||||||
|
"HANDLED_BY": "Handled by {agentName}",
|
||||||
"NOT_ANSWERED_YET": "Noch nicht beantwortet",
|
"NOT_ANSWERED_YET": "Noch nicht beantwortet",
|
||||||
|
"CALLING": "Calling…",
|
||||||
"THEY_ANSWERED": "Sie antworteten",
|
"THEY_ANSWERED": "Sie antworteten",
|
||||||
"YOU_ANSWERED": "Sie haben beantwortet",
|
"YOU_ANSWERED": "Sie haben beantwortet",
|
||||||
"AGENT_ANSWERED": "{agentName} answered",
|
"AGENT_ANSWERED": "{agentName} answered",
|
||||||
"JOIN_CALL": "Join call"
|
"JOIN_CALL": "Join call",
|
||||||
|
"CALL_BACK": "Call back",
|
||||||
|
"TRANSCRIPT_SHOW_MORE": "Show more",
|
||||||
|
"TRANSCRIPT_SHOW_LESS": "Show less"
|
||||||
},
|
},
|
||||||
"HEADER": {
|
"HEADER": {
|
||||||
"RESOLVE_ACTION": "Fall schließen",
|
"RESOLVE_ACTION": "Fall schließen",
|
||||||
@@ -100,6 +110,12 @@
|
|||||||
"SNOOZED_UNTIL_TOMORROW": "Schlummern bis morgen",
|
"SNOOZED_UNTIL_TOMORROW": "Schlummern bis morgen",
|
||||||
"SNOOZED_UNTIL_NEXT_WEEK": "Schlummern bis nächste Woche",
|
"SNOOZED_UNTIL_NEXT_WEEK": "Schlummern bis nächste Woche",
|
||||||
"SNOOZED_UNTIL_NEXT_REPLY": "Schlummern bis zur nächsten Antwort",
|
"SNOOZED_UNTIL_NEXT_REPLY": "Schlummern bis zur nächsten Antwort",
|
||||||
|
"WHATSAPP_CALL": "Start WhatsApp call",
|
||||||
|
"WHATSAPP_CALL_FAILED": "Could not start the WhatsApp call.",
|
||||||
|
"VOICE_CALL": "Start call",
|
||||||
|
"VOICE_CALL_FAILED": "Could not start the call.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_REQUESTED": "Sent a call permission request to the contact. Try again once they accept.",
|
||||||
|
"WHATSAPP_CALL_PERMISSION_PENDING": "Call permission request already sent recently. Try again once the contact accepts.",
|
||||||
"SLA_STATUS": {
|
"SLA_STATUS": {
|
||||||
"FRT": "FRT {status}",
|
"FRT": "FRT {status}",
|
||||||
"NRT": "NRT {status}",
|
"NRT": "NRT {status}",
|
||||||
@@ -215,6 +231,7 @@
|
|||||||
"TIP_AUDIORECORDER_ICON": "Audio aufzeichnen",
|
"TIP_AUDIORECORDER_ICON": "Audio aufzeichnen",
|
||||||
"TIP_AUDIORECORDER_PERMISSION": "Zugriff auf Audio zulassen",
|
"TIP_AUDIORECORDER_PERMISSION": "Zugriff auf Audio zulassen",
|
||||||
"TIP_AUDIORECORDER_ERROR": "Audio konnte nicht geöffnet werden",
|
"TIP_AUDIORECORDER_ERROR": "Audio konnte nicht geöffnet werden",
|
||||||
|
"AUDIO_CONVERSION_FAILED": "Audio conversion failed. Please try again.",
|
||||||
"DRAG_DROP": "Zum Anhängen hierher ziehen und ablegen",
|
"DRAG_DROP": "Zum Anhängen hierher ziehen und ablegen",
|
||||||
"START_AUDIO_RECORDING": "Audioaufzeichnung starten",
|
"START_AUDIO_RECORDING": "Audioaufzeichnung starten",
|
||||||
"STOP_AUDIO_RECORDING": "Audioaufzeichnung stoppen",
|
"STOP_AUDIO_RECORDING": "Audioaufzeichnung stoppen",
|
||||||
@@ -299,8 +316,13 @@
|
|||||||
"NOT_ANSWERED_YET": "Noch nicht beantwortet",
|
"NOT_ANSWERED_YET": "Noch nicht beantwortet",
|
||||||
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
"HANDLED_IN_ANOTHER_TAB": "Being handled in another tab",
|
||||||
"REJECT_CALL": "Reject",
|
"REJECT_CALL": "Reject",
|
||||||
|
"DISMISS_CALL": "Verwerfen",
|
||||||
"JOIN_CALL": "Join call",
|
"JOIN_CALL": "Join call",
|
||||||
"END_CALL": "End call"
|
"END_CALL": "End call",
|
||||||
|
"MUTE": "Mute mic",
|
||||||
|
"UNMUTE": "Unmute mic",
|
||||||
|
"VIEW_CHAT_HISTORY": "View chat history",
|
||||||
|
"GO_TO_CONVERSATION": "Go to conversation thread"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_TRANSCRIPT": {
|
"EMAIL_TRANSCRIPT": {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user