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

Реакции

Обзор

Модуль «Реакции» позволяет игрокам оставлять на сущностях реакции с произвольным типом — например like / dislike, условные «эмодзи» в виде строк (heart, poop, lol) или служебные метки вроде view («просмотрено»). Для каждой сущности в данных доступны:

  • reactions — объект тип реакции → сколько всего таких реакций от всех игроков (агрегированные счётчики).
  • playerReactions — список реакций, которые текущий игрок поставил именно на эту сущность.

На стороне сервиса запоминается, ставил ли игрок данную реакцию на данную сущность — это можно использовать для лайков, голосований, отметок «просмотрено» и панелей с «эмодзи».

Реакции поддерживаются для:

tip

reactionTypeпроизвольная строка. Зафиксируйте набор ключей в игре (like, dislike, heart, view и т.д.), чтобы интерфейс и аналитика не расходились.

Поставить реакцию

+1 Request

Добавляет реакцию текущего игрока к сущности (поведение при повторной установке зависит от правил на сервере).

await gp.reactions.set({
// Тип сущности: "CHANNEL" | "CHANNEL_MESSAGE" | "FILE" | "IMAGE"
entityType: 'FILE',
// ID сущности (строка; тот же формат, что в остальном API)
entityId: '12333',
// Любой идентификатор реакции, который вы используете в игре
reactionType: 'like',
});

Примеры: like / dislike у сообщения в канале

const messageId = '884422';

await gp.reactions.set({
entityType: 'CHANNEL_MESSAGE',
entityId: messageId,
reactionType: 'like',
});

await gp.reactions.set({
entityType: 'CHANNEL_MESSAGE',
entityId: messageId,
reactionType: 'dislike',
});

Примеры: «эмодзи» как строки

// heart, poop, lol — только имена; иконки сопоставляйте на клиенте
await gp.reactions.set({
entityType: 'IMAGE',
entityId: '771209',
reactionType: 'heart',
});

await gp.reactions.set({
entityType: 'IMAGE',
entityId: '771209',
reactionType: 'poop',
});

await gp.reactions.set({
entityType: 'CHANNEL_MESSAGE',
entityId: '112233',
reactionType: 'lol',
});

Снять реакцию

+1 Request

Снимает у текущего игрока реакцию указанного типа с сущности.

await gp.reactions.unset({
entityType: 'FILE',
entityId: '12333',
reactionType: 'like',
});

События

Подписка на успешные операции и ошибки.

gp.reactions.on('set', ({ entityType, entityId, reactionType, counter }) => {
// counter — обновлённое суммарное количество этой реакции на сущности
});

gp.reactions.on('unset', ({ entityType, entityId, reactionType, counter }) => {});

gp.reactions.on('set:error', (error) => {});
gp.reactions.on('unset:error', (error) => {});

Нотификации в реальном времени

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

Сейчас эти события работают только для сущности сообщения канала.

gp.reactions.on('event:set', ({ entityType, entityId, reactionType, counter }) => {
// counter — обновлённое суммарное количество этой реакции на сущности
});

gp.reactions.on('event:unset', ({ entityType, entityId, reactionType, counter }) => {
// counter — обновлённое суммарное количество этой реакции на сущности
});

Счётчики и реакции игрока

После загрузки сущности обычными методами (fetchChannel, fetchMessages, files.fetch, images.fetch и т.д.) доступны:

  • Сумма по всем игрокам: entity.reactions[reactionType].
  • Текущий игрок: массив entity.playerReactions — проверяйте поле reactionType.
const channel = await gp.channels.fetchChannel({ channelId: 123 });

const likesCount = channel.reactions.like ?? 0;

const hasLike = channel.playerReactions.some((r) => r.reactionType === 'like');

Канал

const channel = await gp.channels.fetchChannel({ channelId: 123 });

const upvotes = channel.reactions.like ?? 0;
const downvotes = channel.reactions.dislike ?? 0;

const playerLiked = channel.playerReactions.some((r) => r.reactionType === 'like');

Сообщение канала

Используйте id сообщения из загрузки сообщений — тот же идентификатор передаётся в entityId для типа CHANNEL_MESSAGE.

const { items: messages } = await gp.channels.fetchMessages({ channelId: 123 });

messages.forEach((message) => {
const heartCount = message.reactions.heart ?? 0;
const playerSentHeart = message.playerReactions.some((r) => r.reactionType === 'heart');
});

Файл

const { items: files } = await gp.files.fetch();

const file = files.find((f) => String(f.id) === '12333');
if (file) {
const likes = file.reactions.like ?? 0;
const iLiked = file.playerReactions.some((r) => r.reactionType === 'like');
}

Картинка

const { items: images } = await gp.images.fetch();

const image = images.find((img) => String(img.id) === '771209');
if (image) {
const lolCount = image.reactions.lol ?? 0;
const playerLol = image.playerReactions.some((r) => r.reactionType === 'lol');
}

Пример: «просмотрено» для файла

Отдельный тип реакции (например view) можно использовать как флаг «игрок открывал этот файл»: поставьте реакцию при просмотре, затем при следующей загрузке списка проверяйте playerReactions.

const fileId = '55501';

// Когда игрок открыл просмотр документа
await gp.reactions.set({
entityType: 'FILE',
entityId: fileId,
reactionType: 'view',
});

// Позже: после fetch проверить, просматривал ли этот игрок файл
const { items } = await gp.files.fetch();
const file = items.find((f) => String(f.id) === fileId);

const totalViews = file?.reactions.view ?? 0;
const playerHasViewed = file?.playerReactions.some((r) => r.reactionType === 'view') ?? false;

Снять отметку у текущего игрока (если это нужно по геймдизайну):

await gp.reactions.unset({
entityType: 'FILE',
entityId: fileId,
reactionType: 'view',
});

Типы данных

Значения entityType

ЗначениеСущность
CHANNELКанал
CHANNEL_MESSAGEСообщение канала
FILEФайл
IMAGEКартинка

Поля на сущностях

ПолеТипОписание
reactionsRecord<string, number>Счётчики по reactionType по всем игрокам
playerReactionsArray<{ reactionType: string, ... }>Реакции текущего игрока на эту сущность

Дополнительные поля в элементах playerReactions могут появиться в SDK; для проверок опирайтесь на reactionType.

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

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

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

Для ваших обращений e-mail: official@gamepush.com

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