Instant Games

Messenger Groups

Updated: Mar 3, 2026
Copy for LLM
Messenger Groups integration allows your Instant Game
This guide covers how games integrate with Messenger group conversations, how to use the context APIs, how to enable group-based gameplay, how to detect and respond to different context types, and best practices for designing great group experiences.

How Games Work in Messenger Groups

When a player opens your Instant Game from within a Messenger group conversation, the game is launched in a GROUP context. This means:
  1. The game knows it was launched from a group conversation.
  2. The game has access to a context ID that is unique to that group.
  3. The game can retrieve information about other group members who have also played the game in that context.
  4. Any Custom Updates sent from the game appear in the group conversation thread.
  5. All group members who play the game in that conversation share the same context.
This creates a natural social experience: a group of friends chatting in Messenger can launch a game, compete with each other, and see each other’s activity -- all within the conversation they are already having.

Detecting the Group Context

When your game initializes, use the FBInstant.context APIs to detect whether the game is running in a group context.
async function initializeGame() {
  await FBInstant.initializeAsync();
  FBInstant.setLoadingProgress(100);
  await FBInstant.startGameAsync();

  const contextType = FBInstant.context.getType();
  const contextId = FBInstant.context.getID();

  switch (contextType) {
    case 'GROUP':
      console.log('Playing in a Messenger group! Context ID:', contextId);
      initializeGroupMode(contextId);
      break;
    case 'THREAD':
      console.log('Playing in a 1:1 conversation. Context ID:', contextId);
      initializeThreadMode(contextId);
      break;
    case 'ROOM':
      console.log('Playing in a Room. Context ID:', contextId);
      initializeRoomMode(contextId);
      break;
    case 'SOLO':
    default:
      console.log('Playing solo.');
      initializeSoloMode();
      break;
  }
}

Understanding Context Types

Context TypeDescription
SOLO
The player launched the game outside of any conversation. No shared context.
THREAD
The player launched the game from a 1:1 Messenger conversation with one other person.
GROUP
The player launched the game from a Messenger group conversation with multiple people.
ROOM
The player launched the game from a Messenger Room (video call). See Rooms Co-Play.

Getting the Context ID

The context ID is a unique identifier for the specific group conversation. All players who launch your game from the same group conversation share the same context ID. This is the key to creating shared experiences.
const contextId = FBInstant.context.getID();
// Use this ID to store and retrieve group-specific data (leaderboards, shared state, etc.)

Playing with Group Members

Getting Players in the Context

Use FBInstant.context.getPlayersAsync() to retrieve information about other group members who have played your game in this context.
async function getGroupPlayers() {
  try {
    const players = await FBInstant.context.getPlayersAsync();

    console.log(`${players.length} other player(s) in this group context.`);

    players.forEach(player => {
      console.log('Player ID:', player.getID());
      console.log('Player Name:', player.getName());
      console.log('Player Photo:', player.getPhoto());
    });

    return players;
  } catch (error) {
    console.error('Failed to get group players:', error);
    return [];
  }
}
Note:getPlayersAsync() returns only group members who have also played the game in this context. It does not return all group members. If no other group member has played the game yet, the array will be empty.

Building Group-Specific Leaderboards

Contextual leaderboards are a natural fit for group play. Create a leaderboard scoped to the group context so that group members compete only with each other.
async function showGroupLeaderboard() {
  const contextId = FBInstant.context.getID();

  if (!contextId) {
    console.log('No context -- cannot show group leaderboard');
    return;
  }

  try {
    // Use the context ID to create a contextual leaderboard
    const leaderboard = await FBInstant.getLeaderboardAsync(
      `group_score.${contextId}`
    );

    // Submit the player's score
    await leaderboard.setScoreAsync(currentScore);

    // Get all entries for this context
    const entries = await leaderboard.getEntriesAsync(20, 0);

    entries.forEach(entry => {
      const player = entry.getPlayer();
      console.log(
        `#${entry.getRank()} ${player.getName()}: ${entry.getScore()}`
      );
    });
  } catch (error) {
    console.error('Failed to load group leaderboard:', error);
  }
}

Sending Updates to the Group

When the game is in a group context, Custom Updates sent via FBInstant.updateAsync() appear in the group conversation thread, visible to all group members.
async function shareScoreWithGroup(score) {
  try {
    await FBInstant.updateAsync({
      action: 'CUSTOM',
      cta: 'Play Now',
      image: generateScoreImage(score),
      text: {
        default: `${FBInstant.player.getName()} just scored ${score.toLocaleString()} points! Who can beat it?`,
      },
      template: 'group_score',
      data: { score: score },
      strategy: 'IMMEDIATE',
      notification: 'PUSH',
    });

    console.log('Score shared with group!');
  } catch (error) {
    console.error('Failed to share with group:', error);
  }
}

Context Switching

Sometimes you want to let a player switch from one context to another -- for example, from solo play to a group context, or from one group to another. The SDK provides methods for context switching.

Choosing a Context

Use FBInstant.context.chooseAsync() to let the player select a conversation (group or 1:1) to play in.
async function chooseGroup() {
  try {
    await FBInstant.context.chooseAsync();

    const newContextType = FBInstant.context.getType();
    const newContextId = FBInstant.context.getID();

    console.log(`Switched to ${newContextType} context: ${newContextId}`);

    // Reinitialize the game for the new context
    if (newContextType === 'GROUP') {
      initializeGroupMode(newContextId);
    } else if (newContextType === 'THREAD') {
      initializeThreadMode(newContextId);
    }
  } catch (error) {
    if (error.code === 'SAME_CONTEXT') {
      console.log('Player selected the same context');
    } else if (error.code === 'USER_INPUT') {
      console.log('Player cancelled context selection');
    } else {
      console.error('Context switch failed:', error);
    }
  }
}

Switching to a Specific Player

Use FBInstant.context.createAsync() to create a 1:1 context with a specific player (e.g., to send them a direct challenge from within a group game).
async function challengePlayer(playerId) {
  try {
    await FBInstant.context.createAsync(playerId);

    // Now in a THREAD context with the selected player
    await FBInstant.updateAsync({
      action: 'CUSTOM',
      cta: 'Accept Challenge',
      image: challengeImage,
      text: {
        default: `${FBInstant.player.getName()} challenges you to a duel!`,
      },
      template: 'direct_challenge',
      data: { challengeType: 'duel' },
      strategy: 'IMMEDIATE',
      notification: 'PUSH',
    });
  } catch (error) {
    console.error('Failed to challenge player:', error);
  }
}

Switching Between Contexts

Use FBInstant.context.switchAsync() to switch to a specific existing context by its ID.
async function switchToContext(targetContextId) {
  try {
    await FBInstant.context.switchAsync(targetContextId);
    console.log('Switched to context:', FBInstant.context.getID());
    // Reinitialize game for the new context
  } catch (error) {
    console.error('Failed to switch context:', error);
  }
}

Designing for Group Play

Understand the Group Dynamic

When your game is launched from a Messenger group, the players have an existing relationship. They are friends, family, coworkers, or community members who are already in a conversation together. Your game should enhance this social dynamic, not replace it.

Keep Games Short and Shareable

In a group conversation, games are often played in quick bursts. A group member posts a score, others see it and try to beat it, and the conversation continues. Design your gameplay for short sessions (30 seconds to a few minutes) that produce shareable results.

Make Scores Visible Immediately

When a player finishes a round in a group context, immediately offer to share their score to the group. The faster the score appears in the conversation, the more likely other group members are to see it, react, and play.

Support Asynchronous Competition

Group members will not all be online at the same time. Your game should support asynchronous competition where players take turns at their own pace. Contextual leaderboards are perfect for this -- each player plays when they can, and the leaderboard tracks everyone’s best score.

Handle the Empty Group Gracefully

When the first player in a group launches your game, there are no other players in the context yet. Handle this case by:
  • Showing an engaging solo experience
  • Encouraging the player to share their score to attract other group members
  • Displaying a message like “Be the first to set a score! Share to challenge your group.”

Complete Code Example

async function startGame() {
  await FBInstant.initializeAsync();
  FBInstant.setLoadingProgress(100);
  await FBInstant.startGameAsync();

  const contextType = FBInstant.context.getType();
  const contextId = FBInstant.context.getID();

  if (contextType === 'GROUP' && contextId) {
    // Group mode
    const players = await FBInstant.context.getPlayersAsync();

    if (players.length > 0) {
      showMessage(`${players.length} friend(s) have played in this group!`);
      await showGroupLeaderboard();
    } else {
      showMessage('You are the first to play in this group! Set a score and share it.');
    }

    // Play a round
    const score = await playGameRound();

    // Submit score to contextual leaderboard
    const leaderboard = await FBInstant.getLeaderboardAsync(
      `group_score.${contextId}`
    );
    await leaderboard.setScoreAsync(score);

    // Share the score to the group
    try {
      await FBInstant.updateAsync({
        action: 'CUSTOM',
        cta: 'Beat My Score!',
        image: generateScoreImage(score),
        text: {
          default: `${FBInstant.player.getName()} scored ${score.toLocaleString()}! Can anyone beat it?`,
        },
        template: 'group_challenge',
        data: { score: score },
        strategy: 'IMMEDIATE',
        notification: 'PUSH',
      });
    } catch (error) {
      console.log('Score sharing skipped:', error.code);
    }

  } else {
    // Solo or other context
    const score = await playGameRound();
    showScoreScreen(score);

    // Offer to play in a group
    showButton('Challenge Friends', async () => {
      await FBInstant.context.chooseAsync();
      // Context has switched -- reinitialize
      startGame();
    });
  }
}

startGame();

Best Practices

Respect the Conversation

Your game is a guest in the group’s conversation. Do not flood the conversation with excessive updates. Send updates only at meaningful moments (score submissions, challenges, milestones), and give the player control over what is shared.

Design for Group Discovery

When a group member shares a score or update, it should be compelling enough to make other group members want to try the game. Include the player’s name, their score, and a clear call-to-action. Visual updates with images perform better than text-only updates.

Support Multiple Contexts

A single player may play your game in multiple group contexts (different friend groups, family, coworkers). Make sure each context has independent leaderboards, scores, and game state. A player’s score in one group should not affect their experience in another group.

Leverage Context for Persistence

Use the context ID to store group-specific data on your backend. This allows you to maintain persistent game state for each group -- ongoing tournaments, cumulative scores, group achievements, and more.

Test in Real Group Conversations

Test your game in actual Messenger group conversations with multiple participants. Solo testing will not reveal issues with context detection, player list retrieval, or update delivery.

Next Steps