Что умеет TextBack API

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

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

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

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

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

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

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

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

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

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

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

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

  • Прежде всего зарегистрируйте учетную запись TextBack на http://textback.io#download

  • Проверьте Email, вы должны получить приветственное письмо от TextBack

  • Ответом на Email сообщите о том, что вы планируете использовать TextBack API

  • Расскажите нам немного о том, как планируете примененять API. Возможно, у нас есть чем поделиться на этот счет.

  • В ответ мы пришлем API Token

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

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

В настоящий момент мы выпускаем токены с полным доступом. В будущем, токены будут наделяться теми или иными правами.

Наш API предназначен для обращения server to server.

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

Общее техническое описание API

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

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

HTTP коды ответа

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

Код

Описание

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

Что делать?

200

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

Все хорошо:)

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

401

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

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

Проверить, передан ли API Token. Если да, обратиться в техподдержку

403

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

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

Использовать токен с достаточными правами. Запросить токен можно обратившись в техподдержку

400

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

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

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

500

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

Все плохо:(

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

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

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

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

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

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

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

{
    "$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

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

Можно использовать любой клиент, позволяющий выполнять 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 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}

Популярные методы

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

Текущая страница описывает наиболее часто используемые методы и подходы.

Чтобы отправить сообщение пользователю требуется знать идентификатор канала, идентификатор диалога и идентификатор пользователя.

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

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

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

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

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

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 -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 - его надо обрабатывать как прозрачную строку.

Отправка сообщения

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

Для отправки текстового сообщения сформируйте 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 Время отправки по часам сервера Остальные поля имеют те же значения, которые мы передали, и не составляют интереса

Прием сообщений

В настоящий момент прием сообщений возможен только через WebSocket API, которое не документировано. Именно его использует веб-интерфейс https://my.textback.io

Мы разрабатываем новый API, работающий по принципу Webhooks (мы вызываем вас при поступлении входящего сообщения), но пока что нечем поделиться.

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

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