Перейти к основному содержимому

Поддержка игроков

Все операции используют разрешённый documentId и требуют Authorization: Bearer <sessionId>. Внутренняя обработка и Omnidesk работают через один публичный контракт.

Портал поддержки​

QuerydocumentId: playerSupportPortalauth: Bearer session

playerSupportPortal​

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

Входные данные​

Операция не принимает переменные.

Результат: PlayerSupportPortal!

Запрос
documentId: playerSupportPortal
{
"documentId": "playerSupportPortal",
"variables": {}
}
Ответ
200 OK
{
"data": {
"playerSupportPortal": {
"enabled": true,
"provider": "INTERNAL",
"minimumTitleLength": 5,
"maximumTitleLength": 160,
"minimumMessageLength": 10,
"maximumMessageLength": 5000,
"attachmentsEnabled": true,
"maxFileSizeMb": 10,
"maxFiles": 5,
"maxTotalSizeMb": 25,
"allowedMimeTypes": [
"image/jpeg",
"image/png",
"image/webp"
],
"writeAccess": {
"allowed": true,
"reason": null,
"expiresAt": null
},
"categories": [
{
"id": "1",
"name": "Платежи",
"icon": "ti ti-credit-card"
},
{
"id": "2",
"name": "Игровой аккаунт",
"icon": "ti ti-user"
}
]
}
}
}

Список обращений​

QuerydocumentId: playerSupportTicketsauth: Bearer session

playerSupportTickets​

Возвращает обращения текущего игрока и независимую сводку. Для продолжения передайте курсор из pageInfo.

Входные данные​

ПолеТипОбязательныйОписание
cursorString-Курсор следующей или предыдущей выборки.
limitInt-Размер выборки; по умолчанию 20.

Результат: PlayerSupportTicketConnection! и PlayerSupportTicketSummary!

Запрос
documentId: playerSupportTickets
{
"documentId": "playerSupportTickets",
"variables": {
"cursor": null,
"limit": 20
}
}
Ответ
200 OK
{
"data": {
"playerSupportTickets": {
"items": [
{
"id": "1042",
"title": "Платёж успешно проведён, баланс не изменился",
"categoryId": 1,
"status": "WAITING_FOR_STAFF",
"messagesCount": 1,
"unreadCount": 0,
"lastMessage": "Приложил чек к обращению.",
"createdAt": "2026-08-08T10:24:15Z",
"updatedAt": "2026-08-08T10:24:15Z"
}
],
"pageInfo": {
"nextCursor": "eyJpZCI6MTA0Mn0",
"previousCursor": null,
"hasMore": true
}
},
"playerSupportTicketSummary": {
"all": 3,
"waitingForPlayer": 1,
"waitingForStaff": 1,
"closed": 1
}
}
}

Обращение и сообщения​

QuerydocumentId: playerSupportTicketauth: Bearer session

playerSupportTicket​

Возвращает одно обращение текущего игрока и курсорную историю сообщений.

Входные данные​

ПолеТипОбязательныйОписание
ticketIdID!✓ID обращения.
cursorString-Курсор истории сообщений.
limitInt-Размер выборки; по умолчанию 50.

Результат: PlayerSupportTicket или null

Запрос
documentId: playerSupportTicket
{
"documentId": "playerSupportTicket",
"variables": {
"ticketId": "1042",
"cursor": null,
"limit": 50
}
}
Ответ
200 OK
{
"data": {
"playerSupportTicket": {
"id": "1042",
"title": "Платёж успешно проведён, баланс не изменился",
"categoryId": 1,
"status": "WAITING_FOR_PLAYER",
"messages": {
"items": [
{
"id": "9101",
"content": "Проверили платёж. Баланс обновлён.",
"author": "STAFF",
"authorLabel": "Служба поддержки",
"redacted": false,
"deliveryState": "DELIVERED",
"feedback": null,
"feedbackAllowed": true,
"attachments": [
{
"url": "https://project.example/support/attachments/9101/original?token=short-lived",
"thumbnailUrl": "https://project.example/support/attachments/9101/thumbnail?token=short-lived"
}
],
"createdAt": "2026-08-08T11:02:41Z"
}
],
"pageInfo": {
"nextCursor": null,
"previousCursor": null,
"hasMore": false
}
},
"messagesCount": 2,
"unreadCount": 1,
"lastMessage": "Проверили платёж. Баланс обновлён.",
"createdAt": "2026-08-08T10:24:15Z",
"updatedAt": "2026-08-08T11:02:41Z"
}
}
}

Проверка доступа к обращению​

QuerydocumentId: playerSupportTicketAccessauth: Bearer session

playerSupportTicketAccess​

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

Входные данные​

ПолеТипОбязательныйОписание
ticketIdID!✓ID обращения.

Результат: Boolean!

Запрос
documentId: playerSupportTicketAccess
{
"documentId": "playerSupportTicketAccess",
"variables": {
"ticketId": "1042"
}
}
Ответ
200 OK
{
"data": {
"playerSupportTicketAccess": true
}
}

Проверка доступа к сообщению​

QuerydocumentId: playerSupportMessageAccessauth: Bearer session

playerSupportMessageAccess​

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

Входные данные​

ПолеТипОбязательныйОписание
messageIdID!✓ID сообщения.

Результат: Boolean!

Запрос
documentId: playerSupportMessageAccess
{
"documentId": "playerSupportMessageAccess",
"variables": {
"messageId": "9101"
}
}
Ответ
200 OK
{
"data": {
"playerSupportMessageAccess": true
}
}

Создать обращение​

MutationdocumentId: createPlayerSupportTicketauth: Bearer session

createPlayerSupportTicket​

Идемпотентно создаёт тикет и первое сообщение. Новый пользовательский action получает новый requestId; безопасный повтор того же запроса использует прежнее значение.

Входные данные​

ПолеТипОбязательныйОписание
input.requestIdID!✓Уникальный ID попытки.
input.categoryIdInt!✓ID опубликованной категории.
input.titleString!✓Тема в пределах portal limits.
input.messageString!✓Первое сообщение.
input.accountString-Игровой аккаунт.
input.characterString-Персонаж.
input.attachmentClaimPlayerSupportAttachmentClaimInput-ID и credential предварительно загруженного набора файлов.

Результат: PlayerSupportMutationResult!

Запрос
documentId: createPlayerSupportTicket
{
"documentId": "createPlayerSupportTicket",
"variables": {
"input": {
"requestId": "3a124288-6ced-4a58-9956-7ed994c419a7",
"categoryId": 1,
"title": "Платёж успешно проведён, баланс не изменился",
"message": "Прикладываю чек и номер операции.",
"account": "demo_account",
"character": "Aster",
"attachmentClaim": {
"id": "01J4Q6N8WQ4G4Q5S8YQJ6R7M2D",
"credential": "claim-capability"
}
}
}
}
Ответ
200 OK
{
"data": {
"createPlayerSupportTicket": {
"message": "Обращение создано.",
"ticketId": "1042",
"messageId": "9100",
"deliveryPending": false
}
}
}

Ответить на обращение​

MutationdocumentId: replyPlayerSupportTicketauth: Bearer session

replyPlayerSupportTicket​

Идемпотентно добавляет сообщение игрока в доступное незакрытое обращение.

Входные данные​

ПолеТипОбязательныйОписание
input.requestIdID!✓Уникальный ID попытки.
input.ticketIdID!✓ID обращения текущего игрока.
input.messageString!✓Текст ответа.
input.attachmentClaimPlayerSupportAttachmentClaimInput-Необязательный набор загруженных файлов.

Результат: PlayerSupportMutationResult!

Запрос
documentId: replyPlayerSupportTicket
{
"documentId": "replyPlayerSupportTicket",
"variables": {
"input": {
"requestId": "e8c00d5d-f727-4b7c-96a4-413bd8d6207c",
"ticketId": "1042",
"message": "Баланс обновился, спасибо.",
"attachmentClaim": null
}
}
}
Ответ
200 OK
{
"data": {
"replyPlayerSupportTicket": {
"message": "Ответ отправлен.",
"ticketId": "1042",
"messageId": "9102",
"deliveryPending": false
}
}
}

Оценить ответ сотрудника​

MutationdocumentId: ratePlayerSupportMessageauth: Bearer session

ratePlayerSupportMessage​

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

Входные данные​

ПолеТипОбязательныйОписание
input.messageIdID!✓ID доступного ответа сотрудника.
input.feedbackPlayerSupportMessageFeedback!✓HELPFUL или NOT_HELPFUL.

Результат: PlayerSupportMessageFeedbackResult!

Запрос
documentId: ratePlayerSupportMessage
{
"documentId": "ratePlayerSupportMessage",
"variables": {
"input": {
"messageId": "9101",
"feedback": "HELPFUL"
}
}
}
Ответ
200 OK
{
"data": {
"ratePlayerSupportMessage": {
"messageId": "9101",
"feedback": "HELPFUL"
}
}
}

Публичные ошибки​

Ошибки имеют extensions.category = support и безопасный extensions.code.

КодЗначение
SUPPORT_DISABLEDРаздел выключен для проекта
BANNEDИгроку запрещены новые обращения и ответы
RATE_LIMITEDНе истекла настроенная пауза
INVALID_CATEGORYКатегория выключена или не существует
TITLE_LENGTH / MESSAGE_LENGTHНарушены опубликованные границы длины
TICKET_NOT_FOUNDОбращение не существует или недоступно игроку
TICKET_CLOSED / TICKET_BANNEDОтвет запрещён состоянием обращения
MESSAGE_NOT_FOUNDСообщение не существует или недоступно игроку
FEEDBACK_NOT_ALLOWEDЭто сообщение нельзя оценить
INVALID_ATTACHMENT_CLAIMНабор файлов недействителен или принадлежит другой сессии
ATTACHMENTS_DISABLED / TOO_MANY_ATTACHMENTSВложения не соответствуют правилам портала
ATTACHMENT_SERVICE_UNAVAILABLEХранилище временно недоступно
REQUEST_CONFLICTИдемпотентный ID повторён с другим содержимым
SENSITIVE_CONTENTСообщение отклонено политикой содержимого
Некорректный запрос
documentId: createPlayerSupportTicket
{
"documentId": "createPlayerSupportTicket",
"variables": {
"input": {
"requestId": "3a124288-6ced-4a58-9956-7ed994c419a7",
"categoryId": 1,
"title": "Нет",
"message": "Коротко"
}
}
}
Ошибка
200 OK
{
"errors": [
{
"message": "Длина темы должна быть от 5 до 160 символов.",
"extensions": {
"code": "TITLE_LENGTH",
"category": "support"
}
}
],
"data": {
"createPlayerSupportTicket": null
}
}