Аттрибуты пользователей

API атрибутов пользователя бота

Кастомные поля пользователя: город, источник, отказ от рассылки, UTM и любые свои ключи.

Два слоя:

  1. Справочник ключей бота — какие атрибуты есть у бота и как они называются.
  2. Значения пользователя — что записано конкретному пользователю.

Авторизация

Все методы — POST с телом JSON.

ПараметрГдеОбязательностьОписание
bot_idтелодаID бота в BOT-T
token или botTokenquery или телода*Токен бота
secretKeyqueryда*Секретный ключ бота (альтернатива токену)

* Достаточно либо token/botToken, либо secretKey.

Заголовки:

Content-Type: application/json

Базовый URL:

https://api.bot-t.com

Формат ответа:

{ "result": true, "data": ... }
{ "result": false, "message": "текст ошибки" }

Всегда проверяйте result === true перед использованием data.

Лимит запросов: 120 запросов в минуту с одного IP.


Как устроены атрибуты

Атрибут — пара key → value (строки). Это отдельные поля, не статус и не баланс пользователя.

ТипПримеры ключей
Кастомныеcity, source, любой свой ключ
Системныеmailing_opt_out, utm, utm_first, language

Правила ключа:

  • после записи ключ приводится к нижнему регистру (City → city);
  • начинается с латинской буквы, дальше буквы, цифры или _, длина 1–32;
  • значение — строка до 1024 символов; null или пустая строка удаляет значение.

Запрещены: balance, status, expectation, referral.

Системные:

КлючМожно писать из APIОписание
mailing_opt_outдаотказ от рассылки; любое непустое значение сохраняется как "1"
utmдатекущая UTM-метка (код ссылки трафика)
utm_firstдапервая UTM-метка; из трафика ставится один раз, из API можно перезаписать
languageнетязык пользователя (код вроде ru, en); ставит мультиязычность бота

Если записать кастомный ключ, которого ещё нет в справочнике, он создастся сам (название = ключ). Чтобы сразу задать своё название — сначала создайте ключ в справочнике.

Системные ключи в справочник не входят. Пишутся тем же attribute/upsert, что и кастомные.


Кто такой user_id

В методах значений нужен системный ID пользователя — поле user.id из ответа просмотра пользователя:

  • POST /v1/bot/user/view-by-telegram-id
  • POST /v1/bot/user/view-by-user-id
  • POST /v1/bot/user/view — берите user.id, не верхний id

Либо передайте telegram_id вместо user_id — достаточно одного из двух.

Верхний id из ответа пользователя (ID записи в боте) сюда не подходит.


Справочник ключей бота

МетодURLНазначение
indexPOST /v1/bot/user/attribute-def/indexсписок ключей бота
createPOST /v1/bot/user/attribute-def/createдобавить ключ
updatePOST /v1/bot/user/attribute-def/updateпереименовать (только title)
deletePOST /v1/bot/user/attribute-def/deleteудалить ключ из справочника

POST /v1/bot/user/attribute-def/index

Тело: только bot_id.

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute-def/index?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1
  }'
{
  "result": true,
  "data": [
    { "id": 15, "bot_id": 1, "key": "city", "title": "Город" }
  ]
}

POST /v1/bot/user/attribute-def/create — добавить атрибут

ПолеТипОписание
bot_idintegerID бота
keystringключ (city)
titlestringназвание; если пусто — равно key
curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute-def/create?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "key": "city",
    "title": "Город"
  }'

Ответ — созданный элемент справочника (id, bot_id, key, title).

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

POST /v1/bot/user/attribute-def/update — переименовать

Ключ (key) менять нельзя, только название.

ПолеТипОписание
bot_idintegerID бота
idintegerID записи справочника
titlestringновое название
curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute-def/update?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "id": 15,
    "title": "Город проживания"
  }'

POST /v1/bot/user/attribute-def/delete — удалить атрибут из справочника

ПолеТипОписание
bot_idintegerID бота
idintegerID записи справочника
curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute-def/delete?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "id": 15
  }'
{ "result": true, "data": { "ok": true } }

Удаляется только справочник. Значения у пользователей остаются. Чтобы стереть значение — вызовите удаление значения.


Значения у пользователя

МетодURLНазначение
indexPOST /v1/bot/user/attribute/indexпрочитать все значения
upsertPOST /v1/bot/user/attribute/upsertдобавить или изменить (кастомные и системные)
deletePOST /v1/bot/user/attribute/deleteудалить значение

Ответ этих трёх методов одинаковый:

{
  "result": true,
  "data": {
    "attributes": {
      "city": "Москва",
      "source": "ads"
    },
    "system_attributes": {
      "mailing_opt_out": "1",
      "utm": "promo_may",
      "utm_first": "promo_may",
      "language": "ru"
    }
  }
}
ПолеОписание
attributesкастомные ключи
system_attributesmailing_opt_out, utm, utm_first, language (если заданы)

Пустых ключей в ответе нет. Те же поля приходят при просмотре одного пользователя (view, view-by-telegram-id, view-by-user-id). В списке пользователей их нет.

POST /v1/bot/user/attribute/index — прочитать

ПолеТипОписание
bot_idintegerID бота
user_idintegerсистемный ID пользователя или
telegram_idintegerTelegram ID
curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/index?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552
  }'

POST /v1/bot/user/attribute/upsert — добавить или изменить

Один метод: нет ключа — создаст, есть — перезапишет. Работает и для кастомных, и для системных ключей (mailing_opt_out, utm, utm_first).

ПолеТипОписание
bot_idintegerID бота
user_id или telegram_idintegerкто
keystringключ
valuestring или nullзначение; null или "" удаляет ключ

Кастомный атрибут

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/upsert?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "city",
    "value": "Москва"
  }'

Системный: отказ от рассылки

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/upsert?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "mailing_opt_out",
    "value": "1"
  }'

Вернуть в рассылку — удалите ключ через attribute/delete или передайте пустой value.

Системный: текущая UTM (utm)

Значение — код метки трафика (как в аналитике UTM), не полный URL.

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/upsert?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "utm",
    "value": "promo_may"
  }'

Системный: первая UTM (utm_first)

Из автоматического трафика ставится один раз. Из API можно задать или перезаписать вручную.

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/upsert?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "utm_first",
    "value": "promo_may"
  }'

POST /v1/bot/user/attribute/delete — удалить значение

ПолеТипОписание
bot_idintegerID бота
user_id или telegram_idintegerкто
keystringкакой ключ (кастомный или системный)

Удалить город:

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/delete?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "city"
  }'

Сбросить текущую UTM:

curl --request POST \
  --url 'https://api.bot-t.com/v1/bot/user/attribute/delete?token=BOT_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "bot_id": 1,
    "telegram_id": 182352323552,
    "key": "utm"
  }'

Если ключа у пользователя нет — запрос всё равно успешен, в ответе текущие значения без этого ключа.


Типичный сценарий

  1. Создать ключ city с названием «Город» (можно пропустить).
  2. Записать город пользователю.
  3. При необходимости задать utm / utm_first или mailing_opt_out.
  4. Прочитать значения.
  5. Записать новое значение — изменить.
  6. Удалить значение.
  7. Удалить ключ из справочника бота (значения у пользователей не трогает).

Примеры кода

API_BASE   = https://api.bot-t.com
BOT_ID     = 1
BOT_TOKEN  = 123456789:ABCdefGHI...

PHP

<?php

const API_BASE = 'https://api.bot-t.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';

function botAttrRequest(string $path, array $body): array
{
    $url = API_BASE . '/v1/bot/user/' . $path . '?token=' . urlencode(BOT_TOKEN);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode(array_merge(['bot_id' => BOT_ID], $body)),
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);
    if (!is_array($data) || ($data['result'] ?? false) !== true) {
        throw new RuntimeException($data['message'] ?? 'API error');
    }

    return $data['data'];
}

// Справочник: добавить ключ
$def = botAttrRequest('attribute-def/create', [
    'key' => 'city',
    'title' => 'Город',
]);

// Кастомный атрибут
$maps = botAttrRequest('attribute/upsert', [
    'telegram_id' => 182352323552,
    'key' => 'city',
    'value' => 'Москва',
]);

// Системные: UTM и отказ от рассылки
botAttrRequest('attribute/upsert', [
    'telegram_id' => 182352323552,
    'key' => 'utm',
    'value' => 'promo_may',
]);
botAttrRequest('attribute/upsert', [
    'telegram_id' => 182352323552,
    'key' => 'utm_first',
    'value' => 'promo_may',
]);
botAttrRequest('attribute/upsert', [
    'telegram_id' => 182352323552,
    'key' => 'mailing_opt_out',
    'value' => '1',
]);

// Прочитать
$maps = botAttrRequest('attribute/index', [
    'telegram_id' => 182352323552,
]);

// Удалить значение
$maps = botAttrRequest('attribute/delete', [
    'telegram_id' => 182352323552,
    'key' => 'city',
]);

// Удалить ключ из справочника
botAttrRequest('attribute-def/delete', ['id' => $def['id']]);

JavaScript (Node.js, fetch)

const API_BASE = 'https://api.bot-t.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';

async function botAttrRequest(path, body = {}) {
  const url = `${API_BASE}/v1/bot/user/${path}?token=${encodeURIComponent(BOT_TOKEN)}`;
  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ bot_id: BOT_ID, ...body }),
  });
  const json = await response.json();
  if (!json.result) {
    throw new Error(json.message || 'API error');
  }
  return json.data;
}

(async () => {
  const def = await botAttrRequest('attribute-def/create', {
    key: 'city',
    title: 'Город',
  });

  await botAttrRequest('attribute/upsert', {
    telegram_id: 182352323552,
    key: 'city',
    value: 'Москва',
  });

  await botAttrRequest('attribute/upsert', {
    telegram_id: 182352323552,
    key: 'utm',
    value: 'promo_may',
  });

  const maps = await botAttrRequest('attribute/index', {
    telegram_id: 182352323552,
  });
  console.log(maps.attributes.city, maps.system_attributes?.utm);

  await botAttrRequest('attribute/delete', {
    telegram_id: 182352323552,
    key: 'city',
  });

  await botAttrRequest('attribute-def/delete', { id: def.id });
})();

Токен бота не храните в браузерном JavaScript — вызывайте API с сервера.

Python 3

import requests

API_BASE = 'https://api.bot-t.com'
BOT_ID = 1
BOT_TOKEN = '123456789:ABCdefGHI...'


def bot_attr_request(path: str, body: dict = None) -> dict:
    url = f'{API_BASE}/v1/bot/user/{path}'
    payload = {'bot_id': BOT_ID, **(body or {})}
    response = requests.post(
        url,
        params={'token': BOT_TOKEN},
        json=payload,
        headers={'Content-Type': 'application/json'},
        timeout=30,
    )
    response.raise_for_status()
    data = response.json()
    if not data.get('result'):
        raise RuntimeError(data.get('message', 'API error'))
    return data['data']


# Справочник
def_ = bot_attr_request('attribute-def/create', {'key': 'city', 'title': 'Город'})

# Кастомный
bot_attr_request('attribute/upsert', {
    'telegram_id': 182352323552,
    'key': 'city',
    'value': 'Москва',
})

# Системные
bot_attr_request('attribute/upsert', {
    'telegram_id': 182352323552,
    'key': 'utm',
    'value': 'promo_may',
})
bot_attr_request('attribute/upsert', {
    'telegram_id': 182352323552,
    'key': 'utm_first',
    'value': 'promo_may',
})

# Прочитать
maps = bot_attr_request('attribute/index', {'telegram_id': 182352323552})
print(maps['attributes'].get('city'), maps.get('system_attributes', {}).get('utm'))

# Удалить значение
bot_attr_request('attribute/delete', {
    'telegram_id': 182352323552,
    'key': 'city',
})

# Удалить ключ справочника
bot_attr_request('attribute-def/delete', {'id': def_['id']})

Типичные ошибки

СообщениеПричина
bot_id not foundНет bot_id в теле
token not found / token is not validНет или неверный токен
secretKey is not validНеверный secretKey
user_id not foundНет ни user_id, ни telegram_id
user not foundПользователь не найден в этом боте
key not foundНе передан key
id not foundНет id при изменении или удалении ключа справочника
Некорректный ключ атрибутаКлюч не подходит под формат
Этот ключ зарезервированbalance, status, expectation, referral
Значение атрибута слишком длинноеБольше 1024 символов
Название атрибута не может быть пустымПустой title при создании или переименовании
Нет доступа к атрибутуКлюч справочника принадлежит другому боту

Важные замечания

  1. В этих методах user_id — системный ID (user.id из просмотра пользователя), не верхний id записи в боте. Проще передать telegram_id.
  2. Добавить и изменить значение — один метод upsert, в том числе для utm, utm_first, mailing_opt_out.
  3. Пустой value в upsert удаляет значение, как отдельное удаление.
  4. Удаление ключа из справочника не чистит значения пользователей.
  5. Значение utm / utm_first — код метки трафика, не URL.
  6. Авторизация через секретный ключ: POST /v1/bot/user/attribute/upsert?secretKey=YOUR_SECRET_KEY.