Языки и переводы
Какие языки есть у ассистента, как посетителю выбирается язык и как перевести приветствие, агентов и пейволл одним запросом.
У ассистента два независимых списка языков, язык по умолчанию и переводы, разложенные по разделам. Эта страница — про списки языков (/locales) и про единый метод перевода всех строк ассистента (/i18n).
BASE=https://framesuite.app/api/v1
KEY=user_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ASSISTANT=53
Как устроены языки
Языки сайта и бандлы пейволла
| Список | Поле | На что влияет |
|---|---|---|
| Языки сайта | locales | Переключатель языка в шапке чата (виден, когда языков больше одного) и язык интерфейса и контента: приветствие, имя ассистента, агенты, онбординг. Язык вне списка посетителю недоступен. |
| Бандлы пейволла | paywall_locales | Цены, валюта и тексты пейволла по языкам. По ним же ищется долларовый бандл для оплаты иностранной картой. |
Списки не обязаны совпадать. Бандл пейволла может существовать для языка, которого нет на сайте: так у одноязычного русского ассистента включают оплату иностранной картой — бандл en в долларах есть, английского интерфейса нет. Язык по умолчанию (default_locale) обязан быть среди языков сайта.
Как выбирается язык посетителя
Сервер берёт первый подходящий источник:
- Язык страницы сайта, если чат встроен в неё.
interface_localeассистента (ruилиen), если владелец зафиксировал язык, см. Настройки бота.- Параметр адреса
?locale=(или старый?lang=). - Язык, который человек выбрал переключателем раньше.
- Язык браузера, если он есть среди языков сайта.
- Язык ассистента по умолчанию.
Результат всегда ограничен языками сайта: язык не из списка заменяется языком по умолчанию. Для контента одного языка действует откат: перевод на язык посетителя, иначе английский, иначе базовый текст.
Методы языков
Получить языки
GET /assistants/{assistantId}/locales
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
curl -s "$BASE/assistants/$ASSISTANT/locales" \
-H "Authorization: Bearer $KEY"
{
"success": true,
"locales": ["ru", "en", "kk", "id", "…", "de", "cs"],
"default_locale": "ru",
"paywall_locales": ["bg", "bn", "cs", "…", "pt-br", "zh-tw"]
}
| Свойство | Тип | Описание |
|---|---|---|
locales | array строк | Языки сайта. Если не заданы — ["ru"]. |
default_locale | string | Язык по умолчанию. Если не задан — ru. |
paywall_locales | array строк | Языки, для которых есть бандл пейволла. Сами бандлы — GET /paywall?locale=…, см. Пейволл и тарифы. |
| HTTP | Когда |
|---|---|
| 200 | Отдано. |
| 404 | Ассистента нет или к нему нет доступа: {"success":false,"error":"Project not found or access denied"}. |
Добавить язык
Добавляет язык в языки сайта и, по желанию, копирует на него переводы с другого языка.
POST /assistants/{assistantId}/locales
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locale | string | да | Тело. Код xx или xx-yy (en, pt-br), приводится к нижнему регистру. |
copy_from | string | нет | Тело. Язык-источник. Копируются бандл пейволла (без привязки цен к Paddle — цены создадутся заново при сохранении пейволла), переводы приветствия, языковая версия бота (bot_locales) и онбординг. Только если у нового языка своих данных ещё нет. |
site_language | boolean | нет | Тело. По умолчанию true. false — не добавлять язык на сайт, а завести только бандл пейволла; приветствие, бот и онбординг тогда не копируются. |
currency | string | нет | Тело. RUB, USD или EUR — валюта заводимого бандла. По умолчанию RUB для ru, USD для остальных. |
curl -s -X POST "$BASE/assistants/$ASSISTANT/locales" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"locale":"it","copy_from":"en"}'
{
"success": true,
"locales": ["ru", "en", "…", "it"],
"default_locale": "ru",
"paywall_locales": ["ru", "en", "…", "it"],
"site_language": true
}
Повторное добавление существующего языка не ошибка: список не меняется. Если у ассистента ещё нет языка по умолчанию, им становится добавленный.
| HTTP | Когда |
|---|---|
| 200 | Добавлено. |
| 404 | Ассистента нет или к нему нет доступа. |
| 422 | Неверный код языка или валюта. Кроме errors в ответе общее message: {"success":false,"message":"The locale field format is invalid.","errors":{"locale":["The locale field format is invalid."]}}. |
Задать языки сайта списком
Заменяет список языков сайта целиком. Бандлы пейволла и переводы не трогает: убранный с сайта язык продолжает обслуживать оплату. Чтобы стереть данные языка, нужен DELETE /locales/{locale}.
PUT /assistants/{assistantId}/site-locales
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locales | array строк | да | Тело. Не пустой. Коды xx или xx-yy, приводятся к нижнему регистру, повторы убираются. |
default_locale | string | нет | Тело. Сменить язык по умолчанию тем же запросом. Должен быть в locales. |
curl -s -X PUT "$BASE/assistants/$ASSISTANT/site-locales" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"locales":["ru","en"],"default_locale":"ru"}'
{
"success": true,
"locales": ["ru", "en"],
"default_locale": "ru",
"paywall_locales": ["ru", "en", "es"]
}
| HTTP | Когда |
|---|---|
| 200 | Записано. |
| 404 | Ассистента нет или к нему нет доступа. |
| 422 | Пустой список или неверный код: {"success":false,"errors":{"locales":["The locales field is required."]}}. |
| 422 | Язык по умолчанию не попал в список: {"success":false,"error":"default_locale_not_in_list","message":"Default locale 'ru' must stay in the site languages list. Change it via PATCH /default-locale first, or pass default_locale in this request."}. |
Сменить язык по умолчанию
Язык по умолчанию получают посетители, чей язык не определился, и на нём хранятся исходные тексты: базовые поля приветствия, агентов и пейволла — это тексты на этом языке.
PATCH /assistants/{assistantId}/default-locale
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locale | string | да | Тело. Код языка, уже входящего в языки сайта. |
curl -s -X PATCH "$BASE/assistants/$ASSISTANT/default-locale" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"locale":"en"}'
{
"success": true,
"locales": ["ru", "en"],
"default_locale": "en"
}
Смена языка по умолчанию не переносит тексты: базовые поля остаются как были и начинают считаться текстами нового языка.
| HTTP | Когда |
|---|---|
| 200 | Записано. |
| 404 | Ассистента нет или к нему нет доступа. |
| 422 | Языка нет среди языков сайта: {"success":false,"error":"locale_not_active"}. |
Удалить язык
Убирает язык с сайта и стирает все его данные: бандл пейволла, переводы приветствия, языковую версию бота (bot_locales) и онбординг. Цены Paddle этого бандла архивируются. Переводы агентов, подвала и задержки не трогаются.
DELETE /assistants/{assistantId}/locales/{locale}
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locale | string | да | Путь. Код языка. |
curl -s -X DELETE "$BASE/assistants/$ASSISTANT/locales/it" \
-H "Authorization: Bearer $KEY"
{
"success": true,
"locales": ["ru", "en"],
"default_locale": "ru",
"paywall_locales": ["ru", "en"]
}
Язык, у которого есть только бандл пейволла, удаляется тем же методом: стирается бандл, проверки ниже к нему не относятся.
| HTTP | Когда |
|---|---|
| 200 | Удалено. |
| 404 | Языка нет ни на сайте, ни среди бандлов: {"success":false,"error":"locale_not_found"}. |
| 422 | Последний язык сайта: {"success":false,"error":"cannot_remove_last_locale"}. |
| 422 | Язык по умолчанию: {"success":false,"error":"cannot_remove_default_locale","message":"Change default_locale via PATCH /default-locale first."}. |
DELETE /locales/{locale} стирает бандл пейволла и переводы без возможности вернуть их. Если язык нужно только убрать с сайта, используйте PUT /site-locales.
Перевод ассистента одним запросом
/i18n отдаёт все переводимые строки ассистента плоской картой «ключ → текст» и принимает перевод одного языка одной транзакцией. Туда входят приветствие, агенты и пейволл. Системный промпт, промпты агентов, иконки, категории и адреса картинок не входят — это не текст для читателя.
Ключи
Индексы — позиции в исходной структуре. Структура (сколько секций, вариантов ответа, тарифов) переводом не меняется.
| Ключ | До символов | Что это |
|---|---|---|
welcome.welcome_message | 500 | Заголовок приветствия. |
welcome.welcome_subtitle | 500 | Подзаголовок. |
welcome.header_note | 300 | Дисклеймер в шапке. |
welcome.input_placeholder | 255 | Подсказка в поле ввода. |
welcome.welcome_start_message | 2000 | Стартовое сообщение приветствия. |
welcome.sections.<i>.title | 100 | Заголовок секции. |
welcome.sections.<i>.link_label | 100 | Подпись карточки-ссылки секции шаблонов. |
welcome.sections.<i>.categories.<j>.label | 100 | Подпись вкладки-категории. |
welcome.sections.<i>.categories.<j>.subcategories.<k>.label | 100 | Подпись подкатегории. |
agents.<id>.label | 255 | Название агента. |
agents.<id>.subtitle | 255 | Подзаголовок агента. |
agents.<id>.badge | 64 | Бейдж на карточке. |
agents.<id>.prepared_response | 20000 | Заготовленный первый ответ. |
agents.<id>.suggestions.<k>.text | 200 | Текст варианта ответа. |
agents.<id>.suggestions.<k>.response | 8000 | Заготовленный ответ на вариант. |
paywall.plans.<i>.name, .label, .description, .button_text | 50, 30, 200, 50 | Тексты тарифа. |
paywall.plans.<i>.features.<k> | 120 | Пункт тарифа. |
paywall.features.<i>.title, .description | 100, 200 | Преимущества на пейволле. |
paywall.texts.title, .subtitle_anonymous, .subtitle_authorized, .button_text, .footer | 100, 200, 200, 50, 500 | Общие тексты пейволла. |
Получить строки для перевода
GET /assistants/{assistantId}/i18n
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locale | string | нет | Строка запроса. Язык, по умолчанию язык ассистента по умолчанию. |
Отдаются тексты, которые посетитель увидит на этом языке, с учётом отката: где перевода нет, придёт английский или исходный текст. Пустые поля в карту не попадают.
curl -s "$BASE/assistants/$ASSISTANT/i18n?locale=en" \
-H "Authorization: Bearer $KEY"
{
"success": true,
"locale": "en",
"default_locale": "ru",
"locales": ["ru", "en", "kk", "…"],
"fields": {
"welcome.welcome_message": { "value": "Чем могу помочь?", "max": 500 },
"welcome.sections.1.title": { "value": "Создайте изображения", "max": 100 },
"agents.797.label": { "value": "Upload your resume for review", "max": 255 },
"agents.936.suggestions.0.text": { "value": "Resume from scratch", "max": 200 },
"paywall.texts.title": { "value": "Full access", "max": 100 },
"paywall.texts.button_text": { "value": "Continue", "max": 50 }
}
}
Чтобы понять, что ещё не переведено, сравните карту языка с картой языка по умолчанию: совпадающие значения — кандидаты на перевод.
| HTTP | Когда |
|---|---|
| 200 | Отдано. |
| 404 | Ассистента нет или к нему нет доступа. |
Записать перевод
Записывает переведённые строки одного языка. Все проверки идут до записи: любая ошибка — 422, и в базе ничего не меняется. Другие языки и не присланные ключи не трогаются.
PUT /assistants/{assistantId}/i18n
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
locale | string | да | Строка запроса. Язык перевода: входит в языки сайта и не равен языку по умолчанию. |
fields | object | да | Тело. Непустая карта {"ключ": "текст"}. Можно прислать и объекты из GET как есть — берётся value. |
Правила для значений:
| Правило | Что проверяется |
|---|---|
| Ключ | Поле структуры ассистента на языке по умолчанию — в том числе пустое там (агент переведён на en, а на ru текста нет), либо поле, которое уже есть на этом языке. Незнакомый ключ — ошибка. |
| Текст | Непустая строка не длиннее предела ключа. |
| Ссылки | Все адреса http(s)://… и /storage/… из исходного текста должны остаться в переводе — картинки и ссылки в заготовленных ответах не теряются. |
curl -s -X PUT "$BASE/assistants/$ASSISTANT/i18n?locale=en" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"welcome.welcome_message": "How can I help?",
"welcome.header_note": "Independent AI assistant, not affiliated with model providers.",
"agents.797.label": "Upload your resume for review"
}
}'
{
"success": true,
"locale": "en",
"applied": 2,
"unchanged": 1
}
applied — сколько значений отличалось от текущих на этом языке, unchanged — сколько совпало.
Куда пишется: приветствие — в переводы ассистента и сразу на приветственный экран по умолчанию; агенты — в языковые версии агентов; пейволл — в бандл этого языка (если бандла не было, он создаётся из текущего отображаемого, без привязки цен к Paddle).
| HTTP | Когда |
|---|---|
| 200 | Записано. |
| 404 | Ассистента нет или к нему нет доступа. |
| 422 | Язык не из языков сайта: {"success":false,"error":"locale_not_active","message":"Locale 'it' is not a project language. Add it via POST /assistants/53/locales first."}. В подсказке стоит id вашего ассистента. |
| 422 | Язык по умолчанию: {"success":false,"error":"default_locale","message":"Default locale holds source texts; edit them via the regular endpoints."}. |
| 422 | Нет fields или это массив: {"success":false,"error":"fields_required","message":"Body must be {\"fields\": {\"<key>\": \"<text>\", ...}}."}. |
| 422 | Ошибки по ключам: {"success":false,"error":"invalid_fields","errors":{"welcome.welcome_message":["The welcome.welcome_message field must not be greater than 500 characters."],"welcome.bogus":["Неизвестное поле: у ассистента на языке по умолчанию такого нет."]}}. Поле в тексте ошибки называется своим ключом. |
На язык по умолчанию /i18n не пишет: исходники меняются через PUT /welcome, методы агентов и PUT /paywall. Добавили агента или секцию — их ключи появятся в карте сразу, переводить можно тем же запросом.
Где остальные переводы
/i18n покрывает главное, но часть текстов переводится в своих разделах.
| Что | Как переводится | Страница |
|---|---|---|
| Приветствие, включая секции | welcome_locales в PUT /welcome или PUT /bot: карта сливается с сохранённой по языкам и полям, "<язык>": null удаляет перевод; у дополнительных экранов — свои переводы | Первые экраны |
| Агенты | Поле locales агента | Агенты |
| Пейволл и тарифы | GET и PUT /paywall?locale=<язык> — у каждого языка свой бандл; в PUT язык можно передать и полем locale в теле, ?locale= главнее | Пейволл и тарифы |
| Онбординг | GET и PUT /onboarding?locale=<язык>; в PUT язык можно передать и полем locale в теле, ?locale= главнее | Онбординг |
| Подвал и пустые состояния | templates.footer.locales, templates.posts_empty | Шаблоны и подвал |
| Тексты и категории каталога «Помощники» | templates.agents_catalog — «поле → язык → строка» | Каталог «Помощники» |
| Окно поддержки | support_locales: сливается по языкам и полям, "<язык>": null удаляет язык | Поддержка и обращения |
| Панель окна входа | auth_locales в PUT /bot | Настройки бота |
| Имя, аватар, логотип ассистента и пункты боковой панели | bot_locales в PUT /bot: сливается по языкам и полям, "<язык>": null удаляет язык | Настройки бота |
| Задержка перед ответом | delay_text_locales, delay_note_text_locales | Возможности и задержка |
Дальше
- Первые экраны (welcome) — исходные тексты приветствия.
- Пейволл и тарифы — бандлы по языкам и оплата иностранной картой.
- Сценарии — готовые последовательности запросов.