TypeScript SDK
@trucklinemp/sdk это официальный набор инструментов TypeScript и JavaScript для интеграций с TrucklineMP. Он включает в себя:
- Клиент Публичного API (
Truckline) с типизированными моделями, повторными попытками и помощниками для пагинации - Помощники OAuth (
TrucklineOAuth, PKCE) для авторизации пользователей - Проверка подписей вебхуков и обработчики доставки (Node.js)
Спецификация OpenAPI остаётся главным источником истины для каждого поля. SDK отслеживает общие ресурсы и намеренно остаётся легковесным.
| Пакет | @trucklinemp/sdk |
| Версия | 0.2.x |
| Реестр | npmjs.com |
| Репозиторий | github.com/trucklinemp/sdk |
| Лицензия | MIT |
| Среда выполнения | Node.js 18+ (глобальный fetch); поддерживается работа HTTP-клиента в браузере |
Установка
Заголовок раздела «Установка»npm install @trucklinemp/sdkТочки входа
Заголовок раздела «Точки входа»| Импорт | Содержимое |
|---|---|
@trucklinemp/sdk |
Полный клиент, модели, ошибки; OAuth и вебхуки реэкспортируются |
@trucklinemp/sdk/oauth |
Только OAuth / PKCE |
@trucklinemp/sdk/webhooks |
Только проверка / обработчик вебхуков (использует встроенный модуль Node crypto) |
Отдавайте предпочтение импорту по конкретным путям, если вам нужна меньшая площадь пакета (например, для OAuth в отдельном микросервисе).
Быстрый старт (Публичный API)
Заголовок раздела «Быстрый старт (Публичный API)»- Включите режим разработчика и создайте проект в Консоли разработчика.
- Создайте API-ключ (
tlmp_api_...) и сохраните его в безопасном месте. - Вызовите API:
import { Truckline, TrucklineError } from "@trucklinemp/sdk";
const tl = new Truckline({ apiKey: process.env.TRUCKLINE_API_KEY,});
console.log(tl.version); // строка версии SDK
const { user } = await tl.users.get("some-handle");console.log(user.webId, user.steamId, user.name);
const bySteam = await tl.users.getBySteam("76561198000000000");
try { await tl.vtcs.get("missing-vtc");} catch (err) { if (err instanceof TrucklineError) { console.error(err.status, err.code, err.requestId, err.message); if (err.isRateLimited) console.error("retry after", err.retryAfter); }}Анонимные запросы работают для многих публичных маршрутов, но имеют более строгие лимиты. В продакшене всегда отправляйте ключ.
Конфигурация
Заголовок раздела «Конфигурация»new Truckline({ apiKey: "tlmp_api_...", baseUrl: undefined, // по умолчанию https://api.trucklinemp.com timeoutMs: 30_000, maxRetries: 1, // повторные попытки при 429 и 5xx retryOnServerError: true, headers: { "X-App": "my-bot" }, userAgent: "my-bot/1.0", // только для Node; по умолчанию включает версию SDK debug: false, onRequest: ({ method, url, attempt }) => {}, onResponse: ({ status, requestId, durationMs }) => {}, fetch: customFetch, // необязательно});Базовый URL
Заголовок раздела «Базовый URL»| Опция | Базовый URL |
|---|---|
| По умолчанию | https://api.trucklinemp.com |
Не добавляйте дополнительный /v1 к api.trucklinemp.com. См. Базовые URL публичного API.
Информация о лимитах запросов
Заголовок раздела «Информация о лимитах запросов»После выполнения запроса вы можете проверить последние разобранные заголовки лимитов:
await tl.meta.version();console.log(tl.lastRateLimit);// { retryAfter, limit, remaining, reset }Типизированные модели
Заголовок раздела «Типизированные модели»Пакет экспортирует типы TypeScript для публичных данных (структуры могут расширяться по мере развития API; необязательные поля остаются необязательными):
- Пользователи:
PublicUser,PublicUserSearchResult,PublicUserBans, … - VTC / участники:
VtcListItem,VtcMember,VtcNewsItem,VtcRole - Мероприятия:
PublicEvent,PublicEventAttendee,PublicEventSlot - Новости, баны, партнёры, значки, игровые серверы, OAuth userinfo, доставка вебхуков
Даты, получаемые от API, типизированы как ISO-строки (IsoDateString).
Пример:
import type { PublicUser } from "@trucklinemp/sdk";
const { user } = await tl.users.get("driver");const profile: PublicUser = user;Ресурсы
Заголовок раздела «Ресурсы»Мета / платформа
Заголовок раздела «Мета / платформа»await tl.meta.version();await tl.meta.status();await tl.meta.stats();await tl.meta.partners();await tl.meta.rules();await tl.meta.session();await tl.meta.recruitmentOpen();Пользователи
Заголовок раздела «Пользователи»await tl.users.search({ q: "alex", page: 1, limit: 20 });await tl.users.get("handle-or-id-or-steamId64");await tl.users.getBySteam("7656119…");await tl.users.resolve("handle"); // возвращает PublicUserawait tl.users.batch(["id1", "id2"]); // автоматически разбивает на чанки по 50await tl.users.bans(userId);await tl.users.events(userId, { tab: "upcoming" });
for await (const page of tl.users.iterateSearch({ q: "a", limit: 20 })) { console.log(page.length);}
const allMatches = await tl.users.searchAll({ q: "a", maxItems: 100 });Публичные объекты пользователя включают steamId, если аккаунт привязан.
await tl.vtcs.list({ limit: 20, q: "logistics" });await tl.vtcs.get("handle-or-id");await tl.vtcs.batch([1, 2, 3]);await tl.vtcs.members("handle");await tl.vtcs.news(vtcId);await tl.vtcs.events(vtcId);await tl.vtcs.roles(vtcId);await tl.vtcs.gallery(vtcId);await tl.vtcs.tier(vtcId);await tl.vtcs.liveEvents(vtcId);await tl.vtcs.upcomingEvents(vtcId);
for await (const members of tl.vtcs.iterateMembers("my-vtc", { limit: 50 })) { for (const m of members) console.log(m.name, m.steamId);}
const everyVtc = await tl.vtcs.listAll({ maxPages: 10 });Мероприятия, новости, баны, программы, игра
Заголовок раздела «Мероприятия, новости, баны, программы, игра»await tl.events.list();await tl.events.get(eventId);await tl.events.attendees(eventId);await tl.events.slots(eventId);
await tl.news.list();await tl.news.get(newsId);
await tl.bans.list({ page: 1, pageSize: 25, q: "cheat" });await tl.bans.get(banId);for await (const page of tl.bans.iterate({ pageSize: 50 })) { /* … */ }
await tl.programs.badge("bug-hunter");await tl.programs.recognition();await tl.game.servers();Запасной выход
Заголовок раздела «Запасной выход»await tl.get("/version");await tl.request("GET", "/vtcs", { query: { limit: 5 } });await tl.post("/path", { body: { … } }); // если в будущем будет задокументирован маршрут для записиОшибки и повторные попытки
Заголовок раздела «Ошибки и повторные попытки»При неудачных HTTP-ответах выбрасывается ошибка TrucklineError:
| Поле / флаг | Значение |
|---|---|
status |
HTTP-статус (0 при сетевой ошибке / таймауте / прерывании) |
code |
Код API или клиента (NOT_FOUND, TIMEOUT, ABORTED, …) |
requestId |
Идентификатор корреляции для службы поддержки |
retryAfter |
Секунды из заголовка Retry-After, если он присутствует |
details |
Дополнительные данные от API |
isRateLimited / isNotFound / isUnauthorized / isForbidden |
Хелперы |
isTimeout / isNetworkError / isServerError / isValidationError |
Хелперы |
Повторные попытки по умолчанию: до maxRetries (по умолчанию 1) при ошибках 429 и 5xx, с использованием джиттера. Установите maxRetries: 0, чтобы отключить. При сбоях сети запросы также повторяются, если maxRetries > 0.
Таблицы лимитов платформы: Лимиты запросов.
Используйте OAuth, когда вам нужны данные от лица авторизованного пользователя (а не только с помощью API-ключа). Полное описание процесса: Приложения OAuth.
import { TrucklineOAuth, generatePkce } from "@trucklinemp/sdk/oauth";
const oauth = new TrucklineOAuth({ clientId: process.env.CLIENT_ID!, clientSecret: process.env.CLIENT_SECRET, // опустите для публичных клиентов + PKCE redirectUri: "https://myapp.com/callback", // siteUrl: "https://trucklinemp.com",});
const pkce = generatePkce();const url = oauth.getAuthorizeUrl({ scope: ["profile", "vtc:read", "presence:read"], state: "csrf-token", codeChallenge: pkce.codeChallenge,});
// После редиректа:const tokens = await oauth.exchangeCode(code, { codeVerifier: pkce.codeVerifier,});const me = await oauth.userinfo(tokens.access_token);console.log(me.sub, me.steam_id, me.handle);
const refreshed = await oauth.refresh(tokens.refresh_token!);await oauth.revoke(tokens.access_token, "access_token");Правила Redirect URI (localhost / приватная LAN / https): Приложения OAuth — redirect URIs.
userinfo с областью видимости profile включает steam_id, если аккаунт привязан.
Вебхуки (Node.js)
Заголовок раздела «Вебхуки (Node.js)»Доставка вебхуков подписывается с помощью HMAC-SHA256 на основе сырого тела запроса:
X-TrucklineMP-Signature: sha256=<hex>X-TrucklineMP-Event: user.bannedX-TrucklineMP-Delivery: <id>import { createWebhookHandler, verifyWebhookSignature, WEBHOOK_SIGNATURE_HEADER,} from "@trucklinemp/sdk/webhooks";
const handle = createWebhookHandler({ secret: process.env.WEBHOOK_SECRET!, onEvent: async (event, meta) => { console.log(meta.type, meta.deliveryId, event); },});
// Express: используйте express.raw(), чтобы тело не парсилось заново перед этимapp.post("/hooks/truckline", express.raw({ type: "*/*" }), async (req, res) => { const result = await handle({ rawBody: req.body, headers: req.headers }); res.status(result.ok ? 200 : 401).json(result);});Низкоуровневый вариант:
verifyWebhookSignature(rawBody, req.headers[WEBHOOK_SIGNATURE_HEADER], secret);Каталог событий и повторные попытки: Вебхуки.
Примеры
Заголовок раздела «Примеры»В репозитории SDK (после npm run build):
| Файл | Назначение |
|---|---|
examples/basic.mjs |
Версия + поиск пользователя |
examples/oauth-pkce.mjs |
Вывод URL авторизации + верификатор |
examples/webhook-express.mjs |
Минимальный обработчик на Express |
Версионирование
Заголовок раздела «Версионирование»- Методы SDK, параметры и класс ошибок следуют семантическому версионированию (
Truckline.VERSION/ версия пакета). - Поля JSON на Сервере могут развиваться; относитесь к новым необязательным полям как к необязательным.
- Критические изменения в клиенте выпускаются как мажорные версии. Смотрите CHANGELOG пакета.
Конфиденциальность
Заголовок раздела «Конфиденциальность»API-трафик с использованием вашего ключа подлежит такому же логированию и ограничению скорости, как и обычные HTTP-запросы. Ознакомьтесь с Политикой конфиденциальности и примечаниями к телеметрии Публичный API.
Участие в разработке
Заголовок раздела «Участие в разработке»Структура пакета, пулл-реквесты PR и добавление новых методов: Участие в разработке TypeScript SDK.
Связанные руководства
Заголовок раздела «Связанные руководства»| Руководство | Темы |
|---|---|
| Обзор платформы | Режим разработчика, типы интеграций |
| Публичный API | Авторизация, базовые URL, лимиты, карта эндпоинтов |
| Приложения OAuth | Авторизация, токены, права доступа, redirect URIs |
| Вебхуки | События, подписи, повторные попытки |
| Консоль разработчика | Проекты, ключи, рабочая среда |
| Участие в разработке SDK | Локальная настройка и PR |
| Утечка API-ключей и секретов | Смена ключей после компрометации |