Что умеет TextBack API

Через TextBack API доступна вся функциональность TextBack.

Это так, поскольку мы в TextBack исповедуем принцип - dogfooding. Мы сами используем тот же самый API для работы нашего веб-интерфейса и других внутренних сервисов, которые остаются за кадром.

Некоторые методы не описаны в спецификации и они не доступны в консоли API. Это не потому что, мы хотим что-то скрыть.

Просто не все методы имеют настолько хорошее описание, которое будет понятно сторонним разработчикам.

Не все методы важны, и мы часто не успеваем добавить описание в консоль.

Некоторые методы мы хотим переработать или убрать, поэтому намеренно не добавляем их в описание.

Мы можем гарантировать, что опубликованные методы будут работать так, как описано. Неописанные методы к сожалению не являются частью предоставляемого нами публичного контакта и могут быть изменены или удалены без предупреждения.

Но если вы нашли нужную вам функциональность путем исследования веб-интерфейса https://my.textback.io либо каким-то другим способом, и она не описана в консоли, дайте нам знать, мы подумаем, что с этим можно сделать.

Так же мы рады любой обратной связи от вас, особенно конструктивной критики, чтобы стать более удобными и функциональными. С группой развития API можно связаться по любому вопросу через Email devclub@textback.io или в Telegram https://telegram.me/TB_API_SupportBot

С чего начать?

Перед началом разработки необходимо получить доступ к API.

Мы предлагаем такой сценарий:

  • Прежде всего зарегистрируйте учетную запись TextBack на https://textback.ru/registration

  • Войдите в личный кабинет и перейдите на страницу интеграции https://my.textback.io/messaging.html#!/integration

  • Сгенерируйте токен и скопируйте в буфер

  • Сохраните API Token - он является секретом, поскольку предоставляет доступ ко всем функциям TextBack от лица вашей учетной записи

  • Исследуйте API через API Console

Время жизни токена равно году, но для пробного бесплатного тарифа токен генерируется до окончания бесплатного тарифа, затем вам придется сгенерировать новый токен после оплаты.

Токен выпускается с теми же правами доступа, как у пользователя, создавшего токен.

Наш API разделяется на две области применения:

  1. для обращения server to server. Вы выполняете те же действия, что и доступные из личного кабинета. Такие запросы должны содержать токен доступа и выполняются от лица пользователя, выпустившего токен. Используется для управления аккаунтом, общения с пользователями через мессенджеры, произведения рассылок, просмотра статистики.

  2. для обращения из браузера посетителя сайта Используется для замены стандартных виджетов чата и подписки. API не требует токена и вызывается от лица посетителя сайта. Доступна малая часть функциональности - получение настроек виджетов, создания подписки. Для некоторых методов (подписки, начала чата) требуется авторизация пользователя в социальной сети.

Никогда не выполняйте запросы из недоверенных сред вроде веб-браузера (кроме изучения API самостоятельно в своем браузере) или мобильного приложения и не передавайте API Token никуда кроме ваших серверов.

Варианты использования

Раздел содержит случаи, как API поможет для решения конкретных задач. Для быстрого старта рекомендуем найти подходящий вариант и следовать инструкциям в нем.

Полное справочное описание методов API приводится ниже в разделе Справочник по API

Отправить рассылку по номеру телефона в ВКонтакте

TextBack предоставляет возможность отправить сообщение пользователю ВКонтакте зная только его номер телефона.

Эта возможность имеет ограничения:

  1. сообщение может формироваться только по заранее утвержденному шаблону

  2. функциональностью не могут пользоваться некоторые виды организаций: коллекторские агенства, микрофинансовые организации, казино, производители лекарств, сигарет, алкогольной продукции, ювелирные магазины, букмекерские конторы

  3. сообщение должно быть реакцией пользователя на его активное действие, например подтверждение заказа

  4. сообщение не должно быть рекламного характера

Шаблон может иметь динамическую часть - так называемые подстановки. Например, "Вы сделали заказ #order_number\#, отправьте 1 для подтверждения.". Подстановки задаются через синтаксис #var_name\#, var_name должно состоять из набора символов [A-Za-z_]

Прежде всего требуется зарегистрировать шаблон. Регистрация шаблона производится сотрудниками технической поддержки TextBack, свяжитесь с нами любым удобным способом, указанным на сайте https://textback.io Регистрация шаблона занимает 2 рабочих дня. После успешной регистрации вы получите идентификатор шаблона - это строка, которую надо запомнить и слать в методе отправки сообщения. Кроме идентификатора шаблона вам надо знать идентификатор настроенной группы в TextBack, его можно получить воспользовавшись методом [Получение списка каналов]

Для отправки сообщения возпользуйтесь методом Отправка сообщения с передачей параметров:

  • remoteAddress - номер телефона в формате tel:+79…​, например +79210000000

  • channelId - идентификатор подключенного канала ВКонтакте в TextBack

  • templateId - идентификатор зарегистрированного шаблона

  • substitutions - JSON объект со значениями подстановок, поддерживается только один уровень вложенности параметров, например {"order_id": "Z123", "date": "12.01"}

  • параметр chatId передавать не требуется, поскольку данное сообщение не является ответом на существующую переписку

Пример запроса
curl -v ${base_url}/messages -H "${auth_header}" -X POST -d "{\"channel\":\"vk\",\"channelId\":2,\"remoteAddress\":\"tel:+79210000000\",\"templateId\":\"order_placed\",{\"order_id\": \"Z123\", \"date\": \"12.01\"}}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$value":{...},"$count":1}

Код ответа 200 сигнализирует, что метод выполнен успешно.

Код ответа 200 означает, что сообщение поставлено в очередь. Он не гарантирует, что сообщение доставлено, а тем более прочитано удаленным пользователем. Для получения статусов доставки необходимо быть подписанным на вебхуки и слушать события доставки.

Разберем пример ответа.

{
  "direction": "outbound",
  "channelId": 2,
  "channel": "vk",
  "templateId": "order_placed",
  "chatId": "103928298",
  "id": "2c12b7e7-cd40-4a9a-b828-5fd6ec6dcc72", (1)
  "sentTimestamp": 1459439095483,(2)
  "tbChatId": 10021(3)
}
1 Уникальный идентификатор сообщения. Обязательно запишите его в БД вашей информационной системы. По идентификатору доступен трекинг статусов доставки в дальнейшем.
2 Время отправки по часам сервера
3 Идентификатор диалога в TextBack. По идентификатору диалога можно отправлять ответы и получать полную историю переписки. Остальные поля имеют те же значения, которые мы передали, и не составляют интереса

Отправить рассылку по номеру телефона через Delivery Hero

TextBack позволяет отправить рассылку по номеру телефона сразу в несколько каналов. Доствка будет произведена каждому получателю только в один канал, в тот месенджер, который у него установлен. К примеру, у человека есть Viber, но нет VK - он получит сообщение в Viber. Если человек не пользуется Viber, ему будет доставлено на телефон через SMS.

На текущий момент наша платформа не поддерживает каналы SMS, поэтому вашим разработчикам будет необходимо слушать событие "недоставки" с нашей системы и отправлять СМС через свой механизм.
В случе отправки через VK к сообщению применимы ограничения накладываемые VK, описаанные в разделе рассылка по номеру телефона в ВКонтакте.

Данное API позволяет передать список телефонных номеров и переменных для постановок в шаблоны, а также отдельно указать шаблон по которому формировать сообщение для каждого канала (некоторые каналы не поддерживают вложения или имеют ограничения на кнопки).

Данное API в текущей версии поддерживает только массовую отправку по списку номеров, API для отправки индивидуальному получателю в разработке, но вы можете сделать рассылку на одного адресата.

Более детально смотрите в разделе описания API.

Написать свой виджет чата

В настоящий момент виджет чата поддерживает только ограниченную кастомизацию внешнего вида - можно изменять только те параметры стилей, которые предусмотрены в личном кабинете в настройках. SDK для виджета чата нет. Поэтому если вы хотите изменить внешний вид виджета, вам следует разработать полностью свой виджет, используя REST API виджета чата.

  1. Создать инстанс виджета через API endpoint создания виджета чата или в личном кабинете. Результатом будет уникальный идентификатор виджета, который понадобится при встраивании его на сайт

  2. Разработать javascript/html код виджета, который будет размещаться на сайте и заменять виджет TextBack

  3. Вызывать из кода виджета API endpoint получения настроек виджета. Для этого понадобится идентификатор, полученный на шаге 1

  4. Отрисовать виджет согласно полученным настройкам.

Отрисовка кнопок виджета зависит от особенностей канала и является частью спецификации канала. Виджет TextBack скрывает эти подробности в своем коде. В случае разработки своего виджета вам придется самостоятельно поддерживать соответствие актуальной спецификации мессенджера.

Написать свой виджет подписок

Воспользуйтесь SDK виджета подписок, который позволит выполнить полную кастомизацию внешнего вида. SDK поможет получить конфигурацию виджета, проинициализировать API мессенджеров, сформировать правильные действия на кнопки подписок.

Документация расположена по адресу https://www.npmjs.com/package/@textback%2Fnotification-widget раздел "TextBack Widget SDK"

Справочник по API

TextBack API представляет собой HTTP API построенный по принципам REST. Способ обращения клиент-серверный. Клиентом является ваш сервис, например CRM. Сервером является TextBack. Клиент выполняет HTTP-запрос, сервер возвращает ответ.

Формат запроса и ответа - JSON, тип содержимого application/json.

Сущности API и терминология

Канал

Настроенный способ общения с клиентами, например бот в Telegram или SMS-номер. Следует отличать тип канала (Telegram, ВКонтакте, SMS) и канал. Канал - это конкретный бот, конкретная группа в ВКонтакте, конкретный номер для SMS-переписки. Параметр channel - тип канала. channelId - числовой идентификатор канала. Идентификаторы уникальны только в пределах типа канала.

Диалог

это выделенный двунаправленный поток сообщений между аккаунтом в TextBack и пользователем на другой стророне - в мессенджере, в социальной сети. Во многих каналах диалог открывается только со стороны удаленного пользователя. Пока удаленный пользователь не написал боту, диалог не открыт, следовательно нельзя отправить сообщение этому пользователю. Исключение составляют каналы, поддерживающие рассылку по номеру телефона, например Viber, ВКонтакте, Whatsapp.

Взаимодействие

HTTP коды ответа

Table 1. Используются HTTP коды ответа:

Код

Описание

Почему такое произошло?

Что делать?

200

Метод отработал успешно

Все хорошо

Считать JSON-объект из тела ответа и интерпретировать согласно документации к методу

401

Аутентификация не удалась

Вы забыли передать API Token или токен не валиден (токен отозван, закончилось время жизни, аккаунт заблокирован)

Проверить, передан ли API Token, не заблокирован ли пользователь. Проверить время жизни токена на сайте https://jwt.io или другими средствами, читающими JWT (проверить поле exp). Если да, обратиться в техподдержку

402

Требуется оплата

Метод требует оплаты тарифа или дополнительного пакета услуг

Проверить, есть ли у вас оплата требуемой функциональности и не окончен ли пакет на странице https://my.textback.io/messaging.html#!/payment Если да, обратиться в техподдержку

403

Недостаточно прав для совершения вызова

Вы вызвали метод API, который требует больше прав, нежели в представленном API Token

Сгенерировать токен от лица пользователя, обладающего необходимыми правами

400

Ошибка клиента

Вероятнее всего вы запросили у сервера выполнить нечто, что не соответствует документации либо передали не совсем валидные данные

Проанализировать подкод ошибки из поля $error.sc, исправить запрос.

500

Ошибка сервера

Все плохо

К сожалению, что-то у нас сломалось. Мы записали ошибку в лог. Но если для вас ошибка является блокирующей, обратитесь в техподдержку и сообщите идентификатор запроса из заголовка X-Correlation-Id для ускорения работы по проблеме.

Если вы встретили другой код, не указанный здесь, обрабатывайте его по общему правилу:

  • 2XX коды - запрос был успешным

  • 301, 302 - проследуйте редиректу

  • остальные коды - запрос был не успешным. Проанализируйте код ответа самостоятельно или обратитесь в группу развития API

Формат успешного ответа

Мы отдаем ответ в обертке вида

{
    "$count": 1,
    "$items": [
        ...
    ],
    "$value": {
    }
}

Одни методы возвращают список, другие единственный элемент. Способ отдачи содержимого отличается.

count - количество элементов в ответе. Всегда 1 для методов, возвращающих единственный результат. $items - массив с элементами ответа, если метод вовращает список. $count содержит длину массива $value - ответ для методов, возвращающих единственный результат

Формат неуспешного ответа в случае ошибки 400

Мы отдаем ошибку в обертке вида

{
    "$error": [
        "sc": 1000,
        "scn": "BODY_HAS_INVALID_FORMAT",
        "violations": [{
            "propertyPath": "user.email",
            "name": "Email",
            "invalidValue": "bad_email@////\\\"
        },
        ...
        ]
    }
}

sc - числовой подкод ошибки scn - текстовый подкод ошибки violations - в случае валидационных ошибок содержит массив несработавших валидационных правил

propertyPath - имя поля в запросе, содержащего ошибочное значение name - имя валидационного правила invalidValue - значение поля

Подкоды ошибок в случае 400 ошибки

При написании клиента можно полагаться как на текстовое, так и на числовое представление подкода ошибки.

Table 2. Ниже перечислены все используемые подкоды
Числовой подкод Текстовый подкод Почему произошло? Что делать?

1000

BODY_HAS_INVALID_FORMAT

Тело запроса передано не в JSON либо содержит ошибки формата. Эту ошибку кидает JSON-парсер на сервере

Проверить тело запроса в любом JSON-валидаторе, исправить ошибки

1001

BODY_VALIDATION_ERROR

Тело запроса не прошло валидацию на правила

Проанализировать массив violations, исправить

1002

RESOURCE_ID_IS_ABSENT

Для REST-запросов, адресованных к ресурсу по ID, не передан идентификатор ресурса

Обратить внимание на URL запроса, свериться с документацией, исправить

1003

UNIQUE_CONSTRAINT_FAILED

Для POST-запросов обозначает, что ресурс не может быть создан поскольку нарушется ограничение уникальности. Такое бывает, когда например создается уже занятый аккаунт.

Выбрать другой идентификатор ресурса для создания

Могут встречаться и другие подкоды ошибок, анализировать их не требуется. Интерпретировать как неуспешный запрос.

Отладочный идентификатор запроса

Мы нумеруем каждый вызов API, чтобы потом было проще производить "разбор полетов". Настоятельно рекомендуем логировать возвращенный идентификатор запроса. Это действительно упрощает исследование проблем при интеграции, в том числе постфактум.

HTTP/1.1 400 Bad Request
Date: Thu, 31 Mar 2016 13:38:04 GMT
Content-Type: application/json
Content-Length: 5027
x-correlation-id: xwRmpAOk
cache-control: no-cache
expires: 0
pragma: no-cache

Заголовок x-correlation-id содержит идентификатор конкретного запроса. По этому идентификатору мы легко найдем логи и поймем, что произошло. Запишите идентификатор в свои логи тоже.

Идентификатор не является глобально уникальным, текущий формат идентификатора выбран как компромисс между читаемостью и повторяемостью. По опыту эксплуатации в течении недели идентификаторы не повторяются.

Авторизация

Каждый запрос, кроме перечисленных в разделе Методы API, предназначенные для использования из браузера посетителя сайта, должен содержать API Token, переданный в формате

Authorization: Bearer {INSERT_YOUR_API_TOKEN_HERE_WITHOUT_BRACES}

Пример

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

API Token живет ограниченное время, в настоящее время мы выдаем токены на 1 год. После окончания времени действия токен перестанет работать, а сервер будет отвечать с кодом 401. Не забывайте запрашивать новый токен заранее до истечения времени жизни.

API Token является JWT-токеном. В него можно заглянуть, декодировав содержимое любой библиотекой для работы с JWT либо на сайте http://jwt.io

Для удобства работы с curl, сохраним токен в переменную окружения.

export auth_header=Authorization: Bearer {INSERT_YOUR_API_TOKEN_HERE_WITHOUT_BRACES}

Подготовка инструмента

Можно использовать любой клиент, позволяющий выполнять HTTP запросы. Рассмотрим некоторые из них.

curl

В настоящей документации мы будем использовать широкораспространенную команду curl.

Для удобства пропишем переменную с базовым адресом API.

export base_url=http://api.textback.io/api

В разделе Авторизация мы установим еще одну переменную окружения - API Token.

Postman

Если curl вам не подходит, можете проходить примеры при помощи Postman.

Кстати Postman может удобно импортировать коллекцию на основе нашего машинного описания API. Импортируйте коллекцию по ссылке

API Console

Так же вы можете выполнять все примеры из браузера используя API Console.

Перед началом работы авторизуйтесь указав токен в верхнем правом углу страницы.

Токен необходимо указывать в формате Bearer {INSERT_YOUR_API_TOKEN_HERE_WITHOUT_BRACES}

Генерация клиентов для различных языков

Поскольку описание TextBack API доступно в машинном виде Swagger, вы можете воспользоваться генератором клиентов. Импортируйте описание API по ссылке и выберите меню Generate Client.

TextBack не оказывает техподдержку клиентов, сгенерированных таким образом. Область нашей ответственности - REST API. Мы вынуждены ограничить область техподдержки, поскольку не имеем возможности покрыть тестированием все типы клиентов, которые генерирует Swagger Editor.

Требования к клиенту

  1. Клиент должен игнорировать поля в ответе, неизвестные ему

  2. Клиент должен игнорировать поля, установленные в null для необязательных полей

  3. Клиент должен игнорировать отсутствие необязательного поля. Отсутствие поля приравнивается к значению null либо к пустому массиву

  4. Даты передаются как число миллисекунд прошедших с полночи 1 января 1970 UTC (unixtime, но в миллисекундах)

  5. Клиент должен иметь включенную проверку валидности https-сертификата и соответствию домену

  6. Наши сервера настроены на максимальное время ожидания обработки - 10 секунд. Желательно настроить таймаут на клиенте немного больше.

Методы API, предназначенные для использования с сервера

Полный справочник методов доступен в API Console, используйте его в качестве reference documentation.

Работа с каналами

Получение списка каналов(version 1.0.0)

Метод нужен для получения идентификатов каналов, зарегистрированных для аккаунта TextBack, без знания которых невозможно отправить сообщение. В зависимости от версии api схема ответа может отличаться.

Выполним запрос

curl -v ${base_url}/channels?v=1.0.0 -H "${auth_header}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$error":null,"$items":[{"accountId":"1","channelId":1,"channel":"tg","id":"tg_1","botUsername":"TextBackSupportBot","botName":null,"botDescription":null,"botAboutText":null,"botUserPicUrl":null},{"accountId":"1","channelId":2,"channel":"tg","id":"tg_2","botUsername":"tb_prod_bot","botName":null,"botDescription":null,"botAboutText":null,"botUserPicUrl":null}],"$value":null,"$count":2}

Код ответа 200 сигнализирует, что метод выполнен успешно.

В теле ответа поле $count имеет значение 2, значит в $items массив длиной в 2 элемента. Элементы - типа Channel.

Рассмотрим тело ответа

{
  <1> "skype": [
                {
  <2>               "channel": {
                        "accountId": "1",
                        "channelId": 10,
                        "channel": "skype",
                        "id": "skype_10",
                        "tbUserId": null,
                        "botUserName": "tb_bot_2",
                        "botUsername": "tb_bot_2",
                        "webUrl": null,
                        "title": "tb_bot_2"
                    },
  <3>              "freeTextCapability": {
  <4>                   "textRestrictions": {
                           "maxSize": 600
                        },
                        "photoRestrictions": null,
                        "audioRestrictions": null,
                        "videoRestrictions": null,
                        "buttonsRestrictions": null,
                        "filesRestrictions": null,
                        "statusRestrictions": null,
                        "locationSupported": false,
                        "configurablePushBehavior": false,
                        "maxAttachmentsPerMessage": 0,
                        "messageSendIntervalMs": 1000,
                        "shouldWrapIntoCompositeIfButtonsPresent": false,
                        "channelTypeName": null,
                        "isTemplate": false,
                        "canCombineDifferentTypes": false,
                        "template": false
                    },
  <5>               "templateCapability": null
                }
            ],
  <6>  "capability": {
                   "textRestrictions": {
                       "maxSize": 600
                   },
                   "photoRestrictions": null,
                   "audioRestrictions": null,
                   "videoRestrictions": null,
                   "buttonsRestrictions": null,
                   "filesRestrictions": null,
                   "statusRestrictions": null,
                   "locationSupported": false,
                   "configurablePushBehavior": false,
                   "maxAttachmentsPerMessage": 0,
                   "messageSendIntervalMs": 40,
                   "shouldWrapIntoCompositeIfButtonsPresent": false,
                   "channelTypeName": null,
                   "isTemplate": false,
                   "canCombineDifferentTypes": false,
                   "template": false
               }
}
1 Название канала (tg, skype, vk, viber …​). В качестве значения - массив доступных каналов по данному названию
2 Объект содержащий представление конкретного канала
3 Объект содержаший ограничения по данному каналу. Эти данные могут быть использованы для определения совместимости канала, например, при решении орисовывать ли кнопку отправки файла.
4 Некое ограничение на текстовый ввод в канале. Например содержит maxSize для установки максимального вводимого числа знаков. Если равно null то текстовый ввод не поддерживается по данному каналу. По аналогии photoResrtictions, videoRestrictions …​
5 Поле подлежит описанию в будущем
6 Поле содержащую минимальную совместимость со всеми доступными каналами пользователя.
Некоторые поля, например, photoRestrictions содержат mimeMask поле обозначающее список поддерживаемых форматов каналом. Например, если это поле содержит "png;jpg" то канал поддерживает только изображения в формате .jpg и .png Если поле содержит "*;!exe" , то это значит канал поддерживает все форматы файлов кроме exe.
если вы сохраняете каналы в свою информационную систему, используйте или составной ключ на channelId и channel или простой ключ на id. Не следует разбирать формат id - его надо обрабатывать как прозрачную строку.

Получение списка каналов (версия 0.1.0)

Метод нужен для получения идентификатов каналов, зарегистрированных для аккаунта TextBack, без знания которых невозможно отправить сообщение. В зависимости от версии api схема ответа может отличаться.

Выполним запрос

curl -v ${base_url}/channels -H "${auth_header}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$error":null,"$items":[{"accountId":"1","channelId":1,"channel":"tg","id":"tg_1","botUsername":"TextBackSupportBot","botName":null,"botDescription":null,"botAboutText":null,"botUserPicUrl":null},{"accountId":"1","channelId":2,"channel":"tg","id":"tg_2","botUsername":"tb_prod_bot","botName":null,"botDescription":null,"botAboutText":null,"botUserPicUrl":null}],"$value":null,"$count":2}

Код ответа 200 сигнализирует, что метод выполнен успешно.

В теле ответа поле $count имеет значение 2, значит в $items массив длиной в 2 элемента. Элементы - типа Channel.

Рассмотрим тело ответа

[
  {
    "channelId": 1, (1)
    "channel": "tg", (2)
    "id": "tg_1", (3)
    "botUsername": "TextBackSupportBot", (4)
    "accountId": "1", (5)
  },
  {
    "accountId": "1",
    "channelId": 2,
    "channel": "sms",
    "id": "sms_2",
    "phone": "+79000000000", (6)
  }
]
1 Идентификатор канала
2 Тип канала, в данном случае Telegram.
3 Уникальный идентификатор ресурса (нужен только для модицифирующих REST-запросов)
4 Юзернейм бота
5 Идентификатор вашего аккаунта в TextBack
6 Номер телефона для отправки SMS
если вы сохраняете каналы в свою информационную систему, используйте или составной ключ на channelId и channel или простой ключ на id. Не следует разбирать формат id - его надо обрабатывать как прозрачную строку.

Работа с чатами и сообщениями

Получение списка диалогов

Метод нужен для получения идентификатов диалогов, без знания которых невозможно отправить сообщение в Telegram.

Выполним запрос

curl -v ${base_url}/chats?from=1519882045000 -H "${auth_header}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$items":[...],"$count":10}

Код ответа 200 сигнализирует, что метод выполнен успешно.

В теле ответа поле $count имеет значение 10, значит в $items массив длиной в 10 элемента. Элементы - типа Chat.

Разберем пример информации о диалоге.

{
  "chatId": "103928298", (1)
  "channel": "tg", (2)
  "channelId": 2, (3)
  "id": "tg_2_103928298", (4)
  "accountId": "1", (5)
  "remoteUsername": "ivan2", (6)
  "remoteAddress": "1001001", (7)
  "remoteFirstName": "Ivan", (8)
  "remoteLastName": "Ivanov", (9)
  "lastMessage": { (10)

  },
  "userPicUrl": null, (11)
  "unreadCount": 0 (12)
}
1 Идентификатор диалога. Уникален в пределах канала
2 Тип канала
3 Идентификатор канала
4 Уникальный идентификатор ресурса (нужен только для модицифирующих REST-запросов)
5 Идентификатор вашего аккаунта в TextBack
6 Идентификатор учетной записи удаленного пользователя (с кем происходит диалог). Формат и содержание зависит от типа канала.
7 Адрес удаленного пользователя (с кем происходит диалог). Формат и содержание зависит от типа канала. Часто является идентификатором анкеты пользователя в удаленной системе.
8 Имя удаленного пользователя
9 Фамилия удаленного пользователя
10 Последнее сообщение в диалоге. Тип TbUniMessage. Рассмотрено подробно далее.
11 Ссылка на аватар удаленного пользователя
12 Количество непрочитанных сообщений оператором
если вы сохраняете диалоги в свою информационную систему, используйте или составной ключ на chatId, channelId и channel или простой ключ на id. Не следует разбирать формат id - его надо обрабатывать как прозрачную строку.
В январе 2018г введен новый обязательный параметр - from, это unixtime в мс. Метод вернет чаты, обновленные не ранее этого времени. Следует использовать глубину не более 3 месяцев.
Отправка сообщения

Для отправки сообщения нам понадобится идентификатор канала и идентификатор диалога. Чтобы их получить используйте методы их предыдущих разделов.

Для отправки текстового сообщения сформируйте POST запрос с полем text.

curl -v ${base_url}/messages -H "${auth_header}" -X POST -d "{\"channel\":\"tg\",\"channelId\":2,\"chatId\":\"103928298\",\"text\":\"Привет!\"}

В полях channel, channelId и chatId значения аналогичных полей, полученных ранее из списка диалогов.

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$value":{...},"$count":1}

Код ответа 200 сигнализирует, что метод выполнен успешно.

Код ответа 200 означает, что сообщение поставлено в очередь. Он в настоящий момент не гарантирует, что сообщение доставлено, а тем более прочитано удаленным пользователем.

В теле ответа поле $count имеет значение 1, значит в $value ответ. Метод возвращает отправленное сообщение, но с заполненными некоторыми полями. Главное поле, которое может быть интересным - уникальный идентификатор сообщения.

Разберем пример ответа.

{
  "accountId": "1",
  "direction": "outbound",
  "channelId": 2,
  "channel": "tg",
  "text": "hi",
  "chatId": "103928298",
  "id": "2c12b7e7-cd40-4a9a-b828-5fd6ec6dcc72", (1)
  "sentTimestamp": 1459439095483 (2)
}
1 Уникальный идентификатор сообщения. Обязательно запишите его в БД вашей информационной системы. По идентификатору доступен трекинг статусов в дальнейшем
2 Время отправки по часам сервера Остальные поля имеют те же значения, которые мы передали, и не составляют интереса
Прием сообщений

Для передедачи входящих сообщений (от конечного пользователя в TextBack) мы используем механизм вебхуков.

Прежде всего необходимо зарегистрировать вебхук через техничесую поддержку support@textback.io. При регистрации необходимо передать URL вашей системы, которая будет принимать запроы с вебхуками. URL должен быть доступен через интернет.

Затем вы должны разработать скрипт, принимающий запросы от TextBack. Мы делаем POST запросы с JSON-содержимым. Формат тела зависит от типа события. Доступны события

  • новый чат

  • входящее сообщение в существующем чате

  • исходящее сообщение в существующем чате

  • отчет о доставке/недоставке исходящего сообщения

  • отчет о прочтении (если канал поддерживает)

  • пользователь подписался на рассылки

  • назначен тег

  • снят тег

  • изменены заметки к чату

  • канал изменил состояние (whatsapp ушел в оффлайн или вернулся в онлайн)

  • TextBack активировал или деактивировал услугу на вашем аккаунте

Управление виджетом чата

Получить список виджетов

Метод нужен для получения списка настроенных виджетов. Этот метод предназначен для управления виджетами, а не для отображения на страницах сайта.

Сейчас виджеты привязаны к пользователю, который их создал. Так исторически сложилось. В настоящий момент почти все пользователи TextBack используют одну административную учетную запись в своем аккаунте, так что это не должно быть проблемой. Если для вас это важное ограничение - напишите нам.

Выполним запрос

curl -v ${base_url}/widgets/by_user/@me -H "${auth_header}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$items":[...],"$count":1}

Код ответа 200 сигнализирует, что метод выполнен успешно.

В теле ответа поле $count имеет значение 1, значит в $items массив длиной в 1 элемент. Элементы - типа Widget.

Разберем пример информации о виджете.

{
      "id":"b65372f0-bbd5-443b-bc83-8f4545dc35f2", (1)
      "userId":"fdadfd3f-7d5b-44c4-b71c-c3624d154a2e",
      "accountId":"99bffda5-5bd1-49b1-b4f2-658854797c01",
      "channels":[(2)
         {
            "channel":"facebook",(3)
            "id":"323049074708312",(4)
            "slug":"TextBack",(5)
            "enabled":true(6)
         },
         {
            "channel":"instagram",
            "id":"tbdevinsta",
            "slug":null,
            "enabled":false
         },
         {
            "channel":"skype",
            "id":"3e3fb011-d023-4d7f-8a85-8cb9439b0148",
            "slug":"tb_test_bot_4",
            "enabled":false
         }
      ],
      "welcome-avatar-url":"https://www.city-n.ru/upload/2013/01/31/319497.jpg",(7)
      "welcome-name":"Вася",(8)
      "welcome-seconds":1,(9)
      "welcome-tooltip":"Приветствую!\n<br>\n<br>Дайте нам знать, если у вас возникнут вопросы.\n<br>\n<br>Просто задайте вопрос через удобный вам мессенджер.",(10)
      "disable-welcome-cursor":false,(11)
      "show-welcome":true,(12)
      "welcome-avatar":"image",(13)
      "widget-size":45,(14)
      "bg-color":"2cbd96",(15)
      "show-waterdrop":true,(16)
      "show-lightbox":true,(17)
      "widget-desktop-icon":"desktopCarousel",(18)
      "widget-mobile-icon":"mobileAngle",(19)
      "disable-desktop-tooltip-en":true,(20)
      "disable-mobile-tooltip-en":true,(21)
      "desktop-tooltiptext-en":"",(23)
      "mobile-tooltiptext-en":"Hey, guys",(24)
      "disable-desktop-tooltip-ru":false,
      "disable-mobile-tooltip-ru":false,
      "desktop-tooltiptext-ru":"Интересует?",
      "mobile-tooltiptext-ru":"Интересует?",
      "show-mobile-version":true,(25)
      "show-mobile":true,(26)
      "widget-alignment":"widget-alignment-right",(27)
      "widget-alignment-left":"",(28)
      "widget-alignment-right":"0",
      "widget-alignment-bottom":"0",
      "custom-channel-tab-number":1,
      "custom-channel-id":0,
      "custom-channel-tooltip":"Онлайн-чат",(29)
      "custom-channel-icon":"default",(30)
      "custom-channel-action":"link",(31)
      "custom-channel-icon-url":"",(32)
      "custom-channel-link":"link",(33)
      "custom-channel-callback":"",(34)
      "is-custom-wide":false,(35)
      "disable-custom-channel-mo":false,(36)
      "disable-custom-channel-tu":false,
      "disable-custom-channel-we":false,
      "disable-custom-channel-th":false,
      "disable-custom-channel-fr":false,
      "disable-custom-channel-sb":false,
      "disable-custom-channel-su":false,
      "custom-channel-from-hours":0,(37)
      "custom-channel-from-minutes":0,
      "custom-channel-to-hours":23,(38)
      "custom-channel-to-minutes":0,
      "custom-channel-tab-number1":2,(39)
      "custom-channel-id1":1,
      "custom-channel-tooltip1":"Онлайн-чат",
      "custom-channel-icon1":"default",
      "custom-channel-action1":"link",
      "custom-channel-icon-url1":"",
      "custom-channel-link1":"link",
      "custom-channel-callback1":"",
      "is-custom-wide1":false,
      "disable-custom-channel-mo1":false,
      "disable-custom-channel-tu1":false,
      "disable-custom-channel-we1":false,
      "disable-custom-channel-th1":false,
      "disable-custom-channel-fr1":false,
      "disable-custom-channel-sb1":false,
      "disable-custom-channel-su1":false,
      "custom-channel-from-hours1":0,
      "custom-channel-from-minutes1":0,
      "custom-channel-to-hours1":23,
      "custom-channel-to-minutes1":0,
      "custom-channels-total":2,(40)
      "widget-open":"open-click-mouseover",(41)
      "hide-tb-logo":""(42)
}
1 уникальный идентификатор виджета. Требуется для отрисовки (или получения настроек) в коде встраивания виджета на сайт.
2 массив из кнопок-каналов (не считая кастомных кнопок)
3 тип канала (vk|facebook|whatsapp|skype|tg|viber). Требуется для определения способа и деталей отрисовки кнопки и реакции на клик
4 идентификатор канала в мессенджере. Требуется для создания ссылки начала чата. Это не TextBack идентификатор, а именно мессенджерский.
5 надпись на кнопке, как правило имя паблик аккаунта. Может отсутствовать, тогда нужно использовать идентификатор
6 флаг, включен ли канал в настройках
7 ссылка на аватар "оператора"
8 имя "оператора"
9 через сколько секунл отображать виджет в режиме приветствия
10 текст в приветствии, HTML
11 N/A
12 отображать ли виджет в режиме приветствия
13 если имеет значение image, то отображать аватар, а не иконку по умолчанию
14 размер (ширина и высота) виджета в пикселях
15 цвет виджета
16 включить Waterdrop анимацию
17 затемнять фон
18 стиль иконки на десктопе (desktopMessaging|desktopTelegram|desktopPhone|desktopBubble|desktopCarousel)
19 стиль иконки на мобильном устройстве (mobileAngle|mobileMessaging|mobileTelegram|mobilePhone|mobileBubble|mobileCarousel)

Помимо параметров отображения указанных выше вы можете хранить собственные параметры. TextBack будет их сохранять и возвращать виджету во время отображения на страницах сайта. Рекомендуется задавать префикс для пользовательских настроек, чтобы они пересекались с настройками TextBack. Разрешено хранить не более 50 пользовательских настроек, размер данных каждой настройки - 1кб.

Создать виджет

Метод нужен для создания нового инстанса виджета. Новый виджет нужен если вы хотите отображать на разных станицах сайта виджеты с разными настройками или кнопками каналов.

Разрешено создавать не более 2 виджетов на тарифе Start и 10 виджетов на тарифе PRO.

При создании виджета необходимо задать хотя бы одну кнопку канала.

При создании виджета вы можете передать собственные параметры. TextBack будет их сохранять и возвращать виджету во время отображения на страницах сайта. Рекомендуется задавать префикс для пользовательских настроек, чтобы они пересекались с настройками TextBack. Разрешено хранить не более 50 пользовательских настроек, размер данных каждой настройки - 1кб.

Если вы предполагаете использовать виджет TextBack, то необходимо передать все настройки, которые возвращаются в любом примере ответа уже созданного виджета.

Создать виджет с кнопкой канала ВКонтакте и без дополнительных настроек

Выполним запрос

curl -v ${base_url}/widgets -H "${auth_header}" -X POST --data "{\"channels\":[{\"channel\":\"vk\",\"id\":\"123\"}]}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$value":
    {
        "id":"df2002ba-c78e-4a65-aa5a-7553bdc061a5",(1)
        "channels":[(2)
            {
                "channel":"vk",(3)
                "id":"123",(4)
                "slug":null,(5)
                "enabled":true(6)
            }
        ]
    }
}
1 уникальный идентификатор созданного виджета. Требуется для отрисовки (или получения настроек) в коде встраивания виджета на сайт.
2 массив из кнопок-каналов (не считая кастомных кнопок)
3 тип канала (vk|facebook|whatsapp|skype|tg|viber). Требуется для определения способа и деталей отрисовки кнопки и реакции на клик
4 идентификатор канала в мессенджере. Требуется для создания ссылки начала чата. Это не TextBack идентификатор, а именно мессенджерский.
5 надпись на кнопке, как правило имя паблик аккаунта. Может отсутствовать, тогда нужно использовать идентификатор
6 флаг, включен ли канал в настройках

Код ответа 200 сигнализирует, что метод выполнен успешно. В $value объект типа Widget.

Создать виджет с кнопкой канала Facebook и дополнительными настройками

Выполним запрос

curl -v ${base_url}/widgets -H "${auth_header}" -X POST --data "{\"channels\":[{\"channel\":\"facebook\",\"id\":\"123\"}],\"x-my-color\":\"#112233\"}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$value":
    {
        "id":"c6d15f3a-d354-46cc-a4bd-757f477afc12",(1)
        "channels":[(2)
            {
                "channel":"facebook",(3)
                "id":"123",(4)
                "slug":null,(5)
                "enabled":true(6)
            }
        ],
        "x-my-color":"#112233"(7)
    }
}
1 уникальный идентификатор созданного виджета. Требуется для отрисовки (или получения настроек) в коде встраивания виджета на сайт.
2 массив из кнопок-каналов (не считая кастомных кнопок)
3 тип канала (vk|facebook|whatsapp|skype|tg|viber). Требуется для определения способа и деталей отрисовки кнопки и реакции на клик
4 идентификатор канала в мессенджере. Требуется для создания ссылки начала чата. Это не TextBack идентификатор, а именно мессенджерский.
5 надпись на кнопке, как правило имя паблик аккаунта. Может отсутствовать, тогда нужно использовать идентификатор
6 флаг, включен ли канал в настройках
7 пользовательская настройка с именем x-my-color. Имя выбрано произвольно. TextBack сохранил настройку и вернул в ответе.

Код ответа 200 сигнализирует, что метод выполнен успешно. В $value объект типа Widget.

Сохранить настройки виджета

Метод сохранения настроек работает так же, как и создания, но метод - PUT, а в URL задается идентификатор изменяемого виджета.

Метод производит полную замену настроек, то есть это не частичное изменение только переданных полей. Если какие-то поля не будут переданы в метод сохранения настроек - они удалятся.

При помощи этого метода изменяются как пользовательские настройки, так и каналы: добавляются новые, удаляются старые. Просто передайте нужный список каналов в массиве channels и он будет полностью заменен.

Выполним запрос

curl -v ${base_url}/widgets/c6d15f3a-d354-46cc-a4bd-757f477afc12 -H "${auth_header}" -X PUT --data "{\"channels\":[{\"channel\":\"facebook\",\"id\":\"123\"}],\"x-my-color\":\"#332211\"}"

Пример ответа

< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 384
< x-correlation-id: 2J972JPQ
< cache-control: no-cache
< expires: 0
< pragma: no-cache
<
{"$value":
    {
        "id":"c6d15f3a-d354-46cc-a4bd-757f477afc12",(1)
        "channels":[(2)
            {
                "channel":"facebook",(3)
                "id":"123",(4)
                "slug":null,(5)
                "enabled":true(6)
            }
        ],
        "x-my-color":"#112233"(7)
    }
}
1 уникальный идентификатор измененного виджета. Требуется для отрисовки (или получения настроек) в коде встраивания виджета на сайт.
2 массив из кнопок-каналов (не считая кастомных кнопок)
3 тип канала (vk|facebook|whatsapp|skype|tg|viber). Требуется для определения способа и деталей отрисовки кнопки и реакции на клик
4 идентификатор канала в мессенджере. Требуется для создания ссылки начала чата. Это не TextBack идентификатор, а именно мессенджерский.
5 надпись на кнопке, как правило имя паблик аккаунта. Может отсутствовать, тогда нужно использовать идентификатор
6 флаг, включен ли канал в настройках
7 пользовательская настройка с именем x-my-color. Видим, что возвращено измененное значение свойства.

Код ответа 200 сигнализирует, что метод выполнен успешно. В $value объект типа Widget с измененными данными.

Методы API для рассылок по номеру с доставкой в один из мессенджеров (Delivery Hero)

Отправка рассылок и просмотр отправленных рассылок

Доступные опреации:

GET https://api.textback.io/api/deliveryHero/notifications/  — получить все разосланные рассылки

GET https://api.textback.io/api/deliveryHero/notifications/:id  — получить информацию по конкретной рассылке

POST https://api.textback.io/api/deliveryHero/notifications  — отправить рассылку

Сущность данных, используемая в рассылках:

{
  "id":"9E21B919-8ED0-4F25-AD02-793767CB19B5",
  "audience": [ (1)
    {
      "remoteAddress": "tel:+7XXXXXXXXX", (2)
      "substitutions": { (3)
        "sub": "Тестовая подстановка"
      }
    }
  ],
  "deliveryConfig": {(4)
    "attempts": [
      {
        "channel": "vk",(5)
        "channelId": 11111,(6)
        "timeout": "PT10M",(7)
        "message": { (8)
          "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",(9)
          "registeredTemplateId": "template_name", (10)
          "attachments": [], (11)
          "buttons": [] (12)
        }
      },
      {
        "channel": "whatsapp", (5)
        "channelId": 11111,(6)
        "timeout": "PT10M",(7)
        "message": {
          "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",(9)
          "attachments": [],
          "buttons": []
        }
      },
      {
        "channel": "vibersm",
        "channelId": 11111,
        "timeout": "PT10M",
        "message": {
          "text": "Привет {{sub}}",
          "attachments": [],
          "buttons": []
        }
      }
    ]
  }
}
1 указывает список получателей
2 номер телефона получателя
3 возможные подстановки для шаблона (см. <9> )
4 настройки доставки для каждого канала (должен быть подключен к вашему аккаунту)
5 тип канала
6 id канала
7 указание максимального времени, сколько наша система будет пытаться доставить в данный канал, в формате ISO 8601 Duration
8 шаблон сообщения для конкретного мессенджера
9 шаблон текста сообщения (рекомендем для ВК также указывать в нашем формате {{ xx }}, а не в формате их шаблонизатора, так как в таком случае исходящее сообщение в нашем ЛК будет отображатся корректно, с подстановками, и вашим операторам будет проще разобраться.
10 имя зарегистрированного шаблона, актуально только для VK (см. рассылка по номеру телефона в ВКонтакте)
11 прикрепленные файлы, такойже формат, как при отправке обычного сообщения. Для VK недопустим.
12 копки, для VK необходимо согласовние с нашей поддержкой, полноценно работает только с WhatsApp. Формат такой же, как при обычной рассылке.
Пример отправки рассылки

Пример запроса:

curl -X POST \
  https://my.textback.io/api/deliveryHero/notifications/ \
  -H 'authorization: Bearer eyXXXXXXXXXXXXXXXXX' \
  -H 'content-type: application/json' \
  -d '{
  "audience": [
    {
      "remoteAddress": "tel:+700000000000",
      "substitutions": {
        "sub": "Подстановка"
      }
    }
  ],
  "deliveryConfig": {
    "attempts": [
      {
        "channel": "vibersm",
        "channelId": 1,
        "timeout": "PT10M",
        "message": {
          "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",
          "registeredTemplateId": "textback_test1",
          "attachments": [],
          "buttons": []
        }
      },
      {
        "channel": "vibersm",
        "channelId": 4,
        "timeout": "PT10M",
        "message": {
          "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",
          "registeredTemplateId": "textback_test1",
          "attachments": [],
          "buttons": []
        }
      }
    ]
  }
}'

Пример ответа:

{
    "$error": null, (1)
    "$items": null,
    "$value": { (2)
        "id": "275d5c03-c3ec-1dc0-1afd-0162b5f04b73",
        "accountId": "5425b21f-4456-4365-a972-d1ce860f7090",
        "audience": [
            {
                "remoteAddress": "tel:+700000000000",
                "substitutions": {
                    "sub": "Подстановка"
                }
            }
        ],
        "audienceSize": 1,
        "deliveryConfig": {
            "attempts": [
                {
                    "channel": "vibersm",
                    "channelId": 1,
                    "timeout": "PT10M",
                    "message": {
                        "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",
                        "registeredTemplateId": "textback_test1",
                        "attachments": [],
                        "buttons": []
                    }
                },
                {
                    "channel": "vibersm",
                    "channelId": 4,
                    "timeout": "PT10M",
                    "message": {
                        "text": "Это сообщение тестовое. Мы проверяем как работает доставка в ВК по номеру, а это подстановка {{sub}}",
                        "registeredTemplateId": "textback_test1",
                        "attachments": [],
                        "buttons": []
                    }
                }
            ]
        },
        "sentTs": "2018-04-11T18:20:46.835Z", (4)
        "createdTs": "2018-04-11T18:20:46.835Z"
    },
    "$count": 1
}

В случае успешной отправки HTTP статус ответа будет 200 OK и в ответе поле $error <1> будет пустым, а поле $value будет содержать обьект рассылки с заполненным (сгенерированным id) и временем отправки <4>.

Методы API, предназначенные для использования из браузера посетителя сайта

Документация доступна по данному адресу: https://www.npmjs.com/package/@textback/notification-widget

Остальные методы

Документация по остальным методам (а так же и по перечисленным здесь) доступна в API Console