Reactions
Overview
The Reactions module lets players attach arbitrary reaction types (for example like, dislike, emoji-style ids such as heart, poop, lol, or service marks like view) to supported entities. For each entity the SDK exposes:
reactions— an object reaction type → total count across all players (aggregated counters).playerReactions— a list of reaction types the current player has left on this entity.
The server remembers whether the player has set a given reaction on a given entity, so you can build likes, voting, “seen” marks, and custom emoji bars.
Reactions are available for:
reactionType is a free-form string. Agree on a fixed set of keys in your game (like, dislike, heart, view, …) so the UI and analytics stay consistent.
Set reaction
+1 RequestAdds the current player’s reaction to the entity (if it is not already set for this player and this reactionType, depending on server rules).
- JavaScript
await gp.reactions.set({
// Entity kind: "CHANNEL" | "CHANNEL_MESSAGE" | "FILE" | "IMAGE"
entityType: 'FILE',
// Entity ID (string; use the same format as elsewhere in the API)
entityId: '12333',
// Any non-empty string identifier you use in the game
reactionType: 'like',
});
Examples: like / dislike on a channel message
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',
});
Examples: custom emoji-style keys
// “Heart”, “poop”, “lol” — only names; map them to icons in your UI
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',
});
Remove reaction
+1 RequestRemoves the current player’s reaction of the given type from the entity.
- JavaScript
await gp.reactions.unset({
entityType: 'FILE',
entityId: '12333',
reactionType: 'like',
});
Events
Subscribe to successful updates and errors.
- JavaScript
gp.reactions.on('set', ({ entityType, entityId, reactionType, counter }) => {
// counter — updated total count for this reaction type on the entity
});
gp.reactions.on('unset', ({ entityType, entityId, reactionType, counter }) => {});
gp.reactions.on('set:error', (error) => {});
gp.reactions.on('unset:error', (error) => {});
Real-time notifications
Real-time reaction notifications are also available. They let you see how other players add and remove reactions while you are in the channel.
At the moment, these events work only for the channel message entity.
gp.reactions.on('event:set', ({ entityType, entityId, reactionType, counter }) => {
// counter — updated total count for this reaction type on the entity
});
gp.reactions.on('event:unset', ({ entityType, entityId, reactionType, counter }) => {
// counter — updated total count for this reaction type on the entity
});
Reading counters and player reactions
After you load an entity with the usual methods (fetchChannel, fetchMessages, files.fetch, images.fetch, etc.), read:
- Totals:
entity.reactions[reactionType](number of reactions of that type from all players). - Current player:
entity.playerReactions— array of entries; checkreactionTypeto see if the player has reacted.
- JavaScript
const channel = await gp.channels.fetchChannel({ channelId: 123 });
const likesCount = channel.reactions.like ?? 0;
const hasLike = channel.playerReactions.some((r) => r.reactionType === 'like');
Channel
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');
Channel message
Use the message id from fetching messages (same id you pass as entityId for 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');
});
File
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');
}
Image
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');
}
Example: “viewed” mark on a file
Use a dedicated reaction type (for example view) as a lightweight “player has opened this file” flag: set it when the player views the file, then check playerReactions on later loads.
const fileId = '55501';
// When the player opens the document viewer
await gp.reactions.set({
entityType: 'FILE',
entityId: fileId,
reactionType: 'view',
});
// Later: after fetch, see if this player already “viewed” the file
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;
To clear the mark for the current player (if your design requires it):
await gp.reactions.unset({
entityType: 'FILE',
entityId: fileId,
reactionType: 'view',
});
Types
entityType values
| Value | Entity |
|---|---|
CHANNEL | Channel |
CHANNEL_MESSAGE | Channel message |
FILE | File |
IMAGE | Image |
Fields on entities
| Field | Type | Description |
|---|---|---|
reactions | Record<string, number> | Counts per reactionType for all players |
playerReactions | Array<{ reactionType: string, ... }> | Reactions the current player set on this entity |
Exact optional fields on playerReactions items may be extended by the SDK; always rely on reactionType for checks.
Stay in Touch
Other documents of this chapter available Here. To get started, welcome to the Tutorials chapter.
GamePush Community Telegram: @gs_community.
For your suggestions e-mail: official@gamepush.com
We Wish you Success!