Bots and Parties
A Bot exists only after its shard has logged it in. Read it from fnlb.bots.cache inside Events.Ready, or await fnlb.bots.fetch(id). Party, chat, and commands on that object talk to the local shard. They throw if the local FNLB client does not support the SDK bridge.
fnlb.on(Events.Ready, async (bot) => {
console.log(bot.id, bot.epicId, bot.displayName, bot.party.id);
});
const bot = await fnlb.bots.fetch('bot-id');
await bot.fetch();fetch() asks the shard for a fresh snapshot and replaces party members and presence on the same object.
| Field | Meaning |
|---|---|
id | FNLB bot id. Same id as fnlb.api.bots.list(). |
nickname | Name in FNLB. |
epicId / displayName | Epic account, after ready. |
parent | Category id, when the bot has one. |
flags | Bitfield from the API. 1 disabled, 2 public, 4 invalid auth, 8 prepared. |
ready | True after the Fortnite client has logged in. |
friendsCount / presenceStatus | Last friend count and presence string. |
party | The party the bot is in. |
fnlb.bots.cache is a Collection (a Map with find and filter). It does not include bots that this process is not running.
Party
bot.party is the Fortnite party.
| Member | Meaning |
|---|---|
id | Epic party id. |
playlistId | Island or playlist link id, lowercased. |
members | Collection of PartyMember, keyed by Epic account id. Includes the bot. |
me | The bot's own member, once bot.epicId is known. |
meta | Party schema (playlist, privacy, custom key). |
fetchMembers() | Reload members from the shard. |
Each PartyMember has id, displayName, isLeader, isReady, isSittingOut, isPlaying, outfit, emote, backpack, pickaxe, shoes, sidekick, and meta. kick() and promote() on a member call the same party methods with that member's id. members is a Collection: a Map plus find and filter.
const leader = bot.party.members.find((member) => member.isLeader);
const others = bot.party.members.filter((member) => member.id !== bot.epicId);Meta
Party meta and member meta are different schemas.
bot.party.metais the party (playlist, privacy, custom match key).bot.party.me.metais the bot's own member (cosmetics and loadout on that member).member.meta.get()can read another member.set()on anyone except the bot throws.
await bot.party.meta.set('Default:CustomMatchKey_s', 'my-key');
const playlist = await bot.party.meta.get('Default:PlaylistData_j');
const all = await bot.party.me.meta.get();get() with no key returns the parsed schema. get(key) returns one value. set(key, value) writes one key and sends that patch.
| Key suffix | Value |
|---|---|
j | Object |
b | Boolean |
U | Number |
s | String |
Events such as PartyMemberOutfitUpdated carry the cosmetic id, not this schema. Call get() when you need the full object.
Lobby controls
These run on the live Fortnite client inside the shard. Privacy, playlist, fill, size, and hiding members require party leader. Cosmetics change only this bot. The FNLB client has to be current; an older client rejects fortnite.action.
import { PartyPrivacy, Playlist } from 'fnlb';
await bot.party.setPrivacy(PartyPrivacy.PUBLIC);
await bot.party.setPlaylist(Playlist.SQUAD, 'NAE');
await bot.party.setCustomMatchmakingKey('my-key');
await bot.party.setSquadFill(false);
await bot.party.setMaxSize(4);
await bot.party.me?.setOutfit('CID_028_Athena_Commando_F', [{ variantIndex: 1 }]);
await bot.party.setEmote('EID_Wave');
await bot.party.clearEmote();
await bot.party.setReady(true);
await bot.party.setSittingOut(false);
await bot.party.setBanner('OtherBanner', 'DefaultColor');
await bot.party.setBattlePass(true, 100);
await bot.setStatus('Lobby bot', 'online');
await bot.join('party-id');
await bot.requestToJoin('friend-epic-id');setPlaylist takes a link id or island code. Playlist has the usual modes. Any other island code is a plain string, for example 1111-1111-1111. The second argument is a region such as NAE. Omit it to keep the current region.
Playlist | Link id |
|---|---|
SOLO | playlist_defaultsolo |
DUO | playlist_defaultduo |
TRIOS | playlist_trios |
SQUAD | playlist_defaultsquad |
CREATIVE | playlist_playgroundv2 |
LEGO | playlist_juno |
ROCKET_RACING | playlist_delmar |
FESTIVAL | playlist_sparksrhythm |
PartyPrivacy is a name, not the numeric dashboard enum in category config. PUBLIC is an open party. PRIVATE is invite-only. FRIENDS limits joins to the leader's friends. FRIENDS_ALLOW_FRIENDS_OF_FRIENDS and PRIVATE_ALLOW_FRIENDS_OF_FRIENDS loosen that. party.me.setOutfit is the same call as party.setOutfit. It throws on any member that is not this bot. variants is a list of SdkCosmeticVariant: { variantIndex } is the cosmetic style index, starting at 0.
| Method | What it sets | Reference |
|---|---|---|
setOutfit(id, variants?) | Outfit | Party.setOutfit |
setBackpack / setPickaxe / setShoes / setSidekick | That slot. Optional path is the game-file path. | Party |
clearBackpack / clearShoes / clearSidekick | Remove that slot | Party |
setEmote / setEmoji / setTrack | Emote, emoji, or jam track | Party.setEmote |
clearEmote() | Stop the current emote, emoji, or track | Party.clearEmote |
setReady(boolean) | Ready up | Party.setReady |
setSittingOut(boolean) | Sit out | Party.setSittingOut |
setBanner(bannerId, color) | Banner icon and color | Party.setBanner |
setBattlePass(purchased, level) | Pass ownership and level shown on the bot | Party.setBattlePass |
setLevel(level) | Account level shown on the bot | Party.setLevel |
setCosmeticStats(crowns, ranked) | Crown count and ranked progress | Party.setCosmeticStats |
hideMembers(hide?) / hideMember(id, hide?) | Hide other members in the squad list. Leader only. | Party.hideMembers |
bot.setStatus(text, onlineType) sets the presence friends see. onlineType is a PresenceOnlineType value: online, chat, away, xa, or dnd. Omit the text to keep the current status. bot.join(partyId) leaves the current party and joins another. bot.requestToJoin(friendId) asks to join a friend's party. They have to accept before this bot is invited. Invites you receive arrive as Events.PartyInvite. Dashboard outfits and privacy that should apply on every start belong in category config, not in a ready listener.
Party actions
The bot must already be friends with the target for an invite. Kick and promote require party leader.
await bot.party.invite('epic-account-id');
await bot.party.kick('epic-account-id');
await bot.party.promote('epic-account-id');
await bot.party.leave();
await bot.party.leave(false);leave() defaults to creating a new party afterwards. Pass false to stay without one. party.send(text) writes in party chat. See Chat and commands. After leave(), party.id and members stay as the last snapshot until the next fetch(), fetchMembers(), or party event.
Reference
| Topic | Symbol |
|---|---|
Bot fields and fetch | Bot |
| Party actions | Party |
| One member | PartyMember |
| Schema read and write | PartyMeta |
| Privacy names | PartyPrivacy |
| Playlist ids | Playlist |