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

Серверный API

Обзор

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

info

Каждый вызов метода с ключом доступа API тарифицируется как 1 запрос. В том числе и методы администратора. Напрямую из панели администратора запросы не тарифицируются.

Мы используем язык GraphQL для обработки запросов. Так вы можете забирать только те данные, которые действительно вам нужны.

Удобные генераторы SDK для запросов к GraphQL:

API доступен по адресу

https://api.gamepush.com/gs/api/graphql

Все методы, схемы типов ввода и вывода доступны в интроспекции. Чтобы посмотреть схему или поработать в песочнице воспользуйтесь расширением для Chrome - Altair GraphQL Client.

Получить ключ API

  1. Перейдите в раздел Настройки аккаунта.
  2. В разделе Ключи API создайте ключ.
    • Выберите на какие проекты распространяется этот ключ или выберите все.
    • Выберите к каким методам API можно будет обращаться с этим ключом или выберите все.

Настройка запроса

GraphQL работает поверх https протокола.

Метод запроса: POST.

Формат ответа / Content-Type: JSON.

Для запроса требуется авторизация. Авторизация работает через заголовки, подробнее ниже.

Запрос от лица администратора

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

Список методов доступен в документации, кнопка Docs в Altair.

Методы администратора не содержат приписки Player (за исключением работы с модулем игрока):

  • FetchChannel
  • CreateChannel
  • FetchOnlineStats

Для авторизации нужно передать X-API-Secret заголовок:

# Ключ доступа
X-API-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Пример формирования заголовков в JS:

const headers = {
'Content-Type': 'application/json',
'X-API-Secret': 'mykey',
};

Запрос от лица игрока

Список методов доступен в документации, кнопка Docs в Altair.

Методы игрока начинаются с префикса Player или содержат его после глагола:

  • PlayerFetchAchievements
  • PlayerFetchLeaderboard
  • FetchPlayerProjectConfig
  • SyncPlayer
  • GetPlayer

Есть 2 варианта авторизации: по ID игрока или по авторизационным данным площадки.

По ID игрока

Нужно передать заголовки:

# Ключ доступа
X-API-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Номер проекта
X-Project-ID: 4

# ID игрока
X-Player-ID: 579134513

Пример формирования заголовков в JS:

const headers = {
'Content-Type': 'application/json',
'X-API-Secret': 'mykey', // НЕ используйте его на клиенте игры, только на сервере, храните в секрете
'X-Project-ID': '4',
'X-Player-ID': '579134513',
};

По авторизационным данным игрока

Авторизационные данные игрока - это данные, которые предоставляются площадками: токены, идентификаторы, подписи и прочая нагрузка. Она всегда разная от площадки к площадке, вы можете получить ее напрямую из нашего SDK уже готовую к отправке.

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

Нужно передать заголовки:

# Ключ доступа
X-API-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Номер проекта
X-Project-ID: 4

# Авторизационные данные игрока (gp.player._authInfo)
X-Player-Data: eyJzZWNyZXRDb2RlIjoiOXFwTnlna2gifQ==

# Тип площадки с которой делается запрос (gp.platform.type)
X-Platform: YANDEX

Заголовок X-Player-Data

Это JSON в base64 формате, содержащий аутентификационные данные игрока:

  • Секретный код
  • ID на площадке
  • Token авторизации игрока на площадке
  • Другие параметры авторизации

Параметры всегда отличаются от площадки к площадке и нужно получать авторизационные данные с игрока в клиентском SDK GamePush, gp.player._authInfo.

tip

При авторизации с данными площадки нужно указать площадку авторизации в заголовке X-Platform. Если запрос не привязан к площадке, заголовок можете опустить.

Пример формирования заголовков с использованием данных площадки, JS:

const headers = {
'Content-Type': 'application/json',
'X-API-Secret': 'mykey', // НЕ используйте его на клиенте игры, только на сервере, храните в секрете
'X-Project-ID': '4',
'X-Platform': gp.platform.type,
'X-Player-Data': btoa(JSON.stringify(gp.player._authInfo)),
};

Работа с API

Запрос к API состоит из 3 частей:

  • Передача авторизационных заголовков (выше)
  • Передача схемы запроса
  • Передача переменных запроса

Подробнее про работу с GraphQL: GraphQL Queries and Mutations.

Каждый запрос возвращает объединенный тип: либо ответ, либо ошибку. Ошибка приходит в свойстве message типа Problem.

... on Problem {
message
}

Проверка типа результата происходит через сравнение __typename результата:

query {
result: FetchPlayerProjectConfig {
__typename
... on Problem {
message
}
... on PlayerProjectConfig {
project {
names {
en
}
}
}
}
}

__typename будет один из предложенных:

  • "Problem"
  • "PlayerProjectConfig"

Пример запроса получения конфига проекта игроком

fragment translations on Translations {
en
fr
it
de
es
zh
pt
ko
ja
ru
tr
ar
id
hi
}

query {
result: FetchPlayerProjectConfig {
__typename
... on Problem {
message
}
... on PlayerProjectConfig {
isDev
isAllowedOrigin
config {
lang
avatarGenerator
avatarGeneratorTemplate
ymCounterId
gtagCounterId
showLoader
showReqCounter
orientation
showOrientationOverlay
targetOS
showUnsupportedOSOverlay
communityLinks {
...translations
}
}
project {
names {
...translations
}
descriptions {
...translations
}
icon(w: 256, h: 256, crop: false)
mainChatId
enableMainChat
achievements {
isLockedVisible
isLockedDescriptionVisible
enableUnlockToast
}
ads {
showCountdownOverlay
showRewardedFailedOverlay
}
}
platformConfig {
appId
gameLink
communityLinks {
...translations
}
banners {
type
enabled
bannerId
desktopBannerId
frequency
refreshInterval
maxWidth
maxHeight
maxWidthDimension
maxHeightDimension
desktopMaxWidth
desktopMaxHeight
desktopMaxWidthDimension
desktopMaxHeightDimension
fitCanvas
position
limits {
hour
day
session
}
useNative
}
}
playerFields {
names {
...translations
}
key
type
default
important
variants {
value
names {
...translations
}
}
}
serverTime
gameVariables {
key
values {
en
}
type
}
rewards {
id
iconSmall: icon(w: 48, h: 48, crop: false)
icon(w: 256, h: 256, crop: false)
tag
isAutoAccept
mutations {
type
key
action
value
}

names {
...translations
}
descriptions {
...translations
}
}
triggers {
id
tag
isAutoClaim
descriptions {
...translations
}
conditions {
type
key
operator
value
}
bonuses {
id
type
}
}
achievements {
id
iconSmall: icon(w: 48, h: 48, crop: false)
icon(w: 256, h: 256, crop: false)
tag
rare
progress
maxProgress
unlocked
lockedIcon(w: 256, h: 256, crop: false)
lockedIconSmall: lockedIcon(w: 48, h: 48, crop: false)
progressStep
isPublished
isLockedVisible
isLockedDescriptionVisible

names {
...translations
}
descriptions {
...translations
}
}
achievementsGroups {
id
tag
achievements
names {
...translations
}
descriptions {
...translations
}
}
products {
id
icon(w: 256, h: 256, crop: false)
iconSmall: icon(w: 48, h: 48, crop: false)
tag
price
isSubscription
period
trialPeriod
yandexId

names {
...translations
}
descriptions {
...translations
}
}
products {
id
icon(w: 256, h: 256, crop: false)
iconSmall: icon(w: 48, h: 48, crop: false)
tag
price
isSubscription
period
trialPeriod
yandexId

names {
...translations
}
descriptions {
...translations
}
}
schedulers {
id
tag
type
days
isRepeat
daysBonuses {
day
bonuses {
id
type
}
}
triggers {
id
tag
isAutoClaim
descriptions {
...translations
}
conditions {
type
key
operator
value
}
bonuses {
id
type
}

day
}
isAutoRegister
}
events {
id
tag
icon(w: 256, h: 256, crop: false)
iconSmall: icon(w: 48, h: 48, crop: false)
dateStart
dateEnd
isAutoJoin
triggers {
id
tag
isAutoClaim
descriptions {
...translations
}
conditions {
type
key
operator
value
}
bonuses {
id
type
}
}

names {
...translations
}
descriptions {
...translations
}
}
acl {
canUploadImages
canUploadFiles
canConnectOnline
canCollectStats
}
}
}
}

Пример получения прогресса игрока

query ($input: GetPlayerInput!) {
result: GetPlayer(input: $input) {
__typename
... on Player {
state
stats {
playtimeAll
playtimeToday
activeDays
activeDaysConsecutive
}
achievementsList {
achievementId
createdAt
progress
unlocked
}
purchasesListV2 {
productId
payload
gift
subscribed
createdAt
expiredAt
}
rewards {
rewardId
countTotal
countAccepted
}
triggers {
triggerId
claimed
}
segments
leftSegments
newSegments
playerSchedulers {
schedulerId
daysClaimed
stats {
activeDays
activeDaysConsecutive
}
}
playerEvents {
eventId
stats {
activeDays
activeDaysConsecutive
}
}
experiments {
experiment
cohort
}
rewardsData {
activatedTriggersNow
claimedTriggersNow
claimedSchedulersDaysNow {
schedulerId
day
}
givenAchievements
givenRewards
givenProducts
}
sessionStart
}
... on Problem {
message
}
}
}

И его переменные с параметром "первый ли это запрос за сессию", это нужно для статистики и формирования уникального токена на сессию, можно опустить в рамках сервера.

{
"input": {
"isFirstRequest": false
}
}

Полный пример запроса полчения игрока на JS

const GET_PLAYER_QUERY = `query ($input: GetPlayerInput!) {
result: GetPlayer(input: $input) {
__typename
... on Player {
id
state
stats {
playtimeToday
}
}
... on Problem {
message
}
}
}`;

const input = {
isFirstRequest: true,
};

// Ответ придет в переменной result, так она названа в запросе выше
// result: GetPlayer()
const result = await fetch('https://api.gamepush.com/gs/api/graphql', {
headers: {
'Content-Type': 'application/json',
'X-API-Secret': 'mykey',
'X-Project-ID': '4',
'X-Player-ID': '579134513',
},
body: JSON.stringify({
query: GET_PLAYER_QUERY,
variables: { input },
}),
})
.then((r) => r.json())
.then((r) => r.data.result);

if (result.__typename === 'Problem') {
// запрос не удался
throw result.message;
}

const player = result;
console.log(player.state.score);

Смотрите так же:

Оставайтесь на связи

С другими разделами документации вы можете ознакомиться здесь. Для начала работы вы можете ознакомиться с нашими туториалами.

Сообщество GamePush в Telegram: @gs_community.

Для ваших обращений e-mail: [email protected]

Желаем вам успехов!