--- name: socialbridge description: Integrate existing apps with SocialBridge custom connections over MessagePack WebSocket. Use when connecting chat, game, community, or app events to Discord via SocialBridge. --- # SocialBridge Skill Use this skill when integrating existing projects with SocialBridge custom connections. SocialBridge bridges custom app chat/events to Discord over WebSocket. ## Connection - Base URL: https://socialbridge.cc - Endpoint: /custom/api/v1/ws - Full URL: wss://socialbridge.cc/custom/api/v1/ws - Protocol: WebSocket - Serialization: msgpack binary WebSocket messages - Packet version: 1 - Auth: send API key via x-api-key header from server-side clients, or ?key=API_KEY query param when client cannot set headers ## Setup flow 1. In SocialBridge dashboard, create custom connection. 2. Copy API key. 3. Connect WebSocket to wss://socialbridge.cc/custom/api/v1/ws. 4. Encode every outbound packet as MessagePack map/object. 5. Include Version=1 and PacketID matching packet table. 6. Read binary WebSocket messages, MessagePack-decode, route by PacketID. 7. Auto-reconnect on close/error. SocialBridge deploys may briefly drop connections. 8. Send PING periodically if app needs health checks. ## Security - Keep API key server-side when possible. - Do not commit API key. - If browser/WebSocket lib cannot set headers, use ?key=API_KEY only when exposure is acceptable for your app. - Rotate key in SocialBridge if leaked. ## Minimal JavaScript example ```js import WebSocket from "ws"; import { encode, decode } from "@msgpack/msgpack"; const apiKey = process.env.SOCIALBRIDGE_API_KEY; const wsUrl = "wss://socialbridge.cc/custom/api/v1/ws"; let ws; function connect() { ws = new WebSocket(wsUrl, { headers: { "x-api-key": apiKey } }); ws.binaryType = "arraybuffer"; ws.onmessage = (event) => { const packet = decode(new Uint8Array(event.data)); switch (packet.PacketID) { case 21: // MESSAGE_CREATE console.log("Discord message", packet.Username, packet.Content); break; case 69: // ERROR console.error("SocialBridge error", packet.Error); break; } }; ws.onclose = () => setTimeout(connect, 2000); ws.onerror = () => ws.close(); } connect(); function sendMessage(content, username = "App") { ws.send(encode({ Version: 1, PacketID: 21, ID: crypto.randomUUID(), Username: username, Content: content, Timestamp: Math.floor(Date.now() / 1000), AvatarURL: "", })); } ``` ## Client -> SocialBridge packets ### PING (2) Ping the server to check connection health | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | ### MESSAGE_CREATE (21) Send a chat message to Discord | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | ID | string | yes | Unique message ID (use timestamp or UUID) (optional) | | Username | string | yes | Display name of the sender (cannot contain 'discord' - will be replaced with 'dscrd') | | Content | string | yes | Message text content | | Timestamp | int64 | yes | Unix timestamp when message was sent | | AvatarURL | string | yes | URL to sender's avatar image | | ReferenceID | string | no | ID of the message being replied to (optional) | | ReferenceUsername | string | no | Username of the referenced message author (optional) | | ReferenceUserID | string | no | User ID of the referenced message author (optional) | | ReferenceContent | string | no | Content preview of the referenced message (optional) | | DiscordGuildID | string | no | Discord guild/server ID (set when receiving from Discord) | | DiscordChannelID | string | no | Discord channel ID (set when receiving from Discord) | | DiscordUserID | string | no | Discord user ID (set when receiving from Discord) | | FallbackNameFormat | string | no | Format string for name in fallback bot message (must contain %s, default: **__%s__**: ) | | FallbackContentFormat | string | no | Format string for content in fallback bot message (must contain %s, default uses code blocks) | | SkipAI | bool | no | If true, skip this message in AI analysis (optional). Recommended for non-user-generated messages like system notifications. | ### MESSAGE_EDIT (22) Edit an existing Discord message | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message to edit | | ChannelID | string | yes | ID of the Discord channel containing the message | | Content | string | yes | New message content | | GuildID | string | no | Discord guild ID (optional, uses first connected guild if not provided) | ### MESSAGE_DELETE (23) Delete a Discord message | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message to delete | | ChannelID | string | yes | ID of the Discord channel containing the message | | GuildID | string | no | Discord guild ID (optional) | ### MESSAGE_REACTION_CREATE (25) Add a reaction to a Discord message | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message to react to | | ChannelID | string | yes | ID of the Discord channel containing the message | | Emoji | string | yes | Emoji to add (unicode emoji or custom emoji format) | | GuildID | string | no | Discord guild ID (optional) | ### MESSAGE_REACTION_DELETE (26) Remove a reaction from a Discord message | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message | | ChannelID | string | yes | ID of the Discord channel containing the message | | Emoji | string | yes | Emoji to remove | | UserID | string | yes | Discord user ID whose reaction to remove (use @me for bot's own reaction) | | GuildID | string | no | Discord guild ID (optional) | ### DISCORD_USER_DM (31) Send a direct message to a Discord user | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | DiscordUserID | string | yes | Discord user ID to send the DM to | | Content | string | yes | Message content | ### DISCORD_USER_ROLE_ASSIGN (32) Assign a role to a Discord user | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | UserID | string | yes | Discord user ID | | RoleID | string | yes | Discord role ID to assign | | GuildID | string | no | Discord guild ID (optional) | ### DISCORD_USER_ROLE_REMOVE (33) Remove a role from a Discord user | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | UserID | string | yes | Discord user ID | | RoleID | string | yes | Discord role ID to remove | | GuildID | string | no | Discord guild ID (optional) | ### DISCORD_IMAGE_UPLOAD (34) Upload an image to a Discord channel | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | ChannelID | string | yes | Discord channel ID to upload the image to | | ImageData | []uint8 | yes | Raw image bytes | | Filename | string | yes | Filename with extension (e.g., screenshot.png) | | GuildID | string | no | Discord guild ID (optional) | ### DISCORD_GUILD_ROLES (28) Request all roles for a Discord guild | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | GuildID | string | no | Discord guild ID (optional, uses first connected guild if not provided) | ## SocialBridge -> Client packets ### PING (2) Response to a ping request (server echoes the ping back) | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | ### ERROR (0) Error response from the server | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | Error | string | yes | Error message describing what went wrong | ### MESSAGE_CREATE (21) Receive a chat message from Discord | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | ID | string | yes | Unique message ID (use timestamp or UUID) (optional) | | Username | string | yes | Display name of the sender (cannot contain 'discord' - will be replaced with 'dscrd') | | Content | string | yes | Message text content | | Timestamp | int64 | yes | Unix timestamp when message was sent | | AvatarURL | string | yes | URL to sender's avatar image | | ReferenceID | string | no | ID of the message being replied to (optional) | | ReferenceUsername | string | no | Username of the referenced message author (optional) | | ReferenceUserID | string | no | User ID of the referenced message author (optional) | | ReferenceContent | string | no | Content preview of the referenced message (optional) | | DiscordGuildID | string | no | Discord guild/server ID (set when receiving from Discord) | | DiscordChannelID | string | no | Discord channel ID (set when receiving from Discord) | | DiscordUserID | string | no | Discord user ID (set when receiving from Discord) | | FallbackNameFormat | string | no | Format string for name in fallback bot message (must contain %s, default: **__%s__**: ) | | FallbackContentFormat | string | no | Format string for content in fallback bot message (must contain %s, default uses code blocks) | | SkipAI | bool | no | If true, skip this message in AI analysis (optional). Recommended for non-user-generated messages like system notifications. | ### DISCORD_GUILD_ROLES (28) Response containing guild roles | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | GuildID | string | yes | Discord guild ID | | Roles | []CustomRole | yes | List of roles in the guild | ### MESSAGE_REACTION_CREATE (25) Receive a reaction add event from Discord | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message that was reacted to | | ChannelID | string | yes | ID of the Discord channel containing the message | | Emoji | string | yes | Emoji that was added | | GuildID | string | yes | Discord guild ID | | UserID | string | yes | Discord user ID of the user who added the reaction | | Username | string | yes | Display name of the user who added the reaction | | AvatarURL | string | yes | URL to the user's avatar image | | ReferenceUserID | string | yes | ID of the user who authored the reacted message | | ReferenceUsername | string | yes | Display name of the user who authored the reacted message | ### MESSAGE_REACTION_DELETE (26) Receive a reaction remove event from Discord | Field | Type | Required | Notes | | --- | --- | --- | --- | | Version | uint8 | yes | Protocol version, always 1 | | PacketID | uint8 | yes | Packet type identifier | | MessageID | string | yes | ID of the Discord message that had a reaction removed | | ChannelID | string | yes | ID of the Discord channel containing the message | | Emoji | string | yes | Emoji that was removed | | GuildID | string | yes | Discord guild ID | | UserID | string | yes | Discord user ID of the user who removed the reaction | | Username | string | yes | Display name of the user who removed the reaction | | AvatarURL | string | yes | URL to the user's avatar image | | ReferenceUserID | string | yes | ID of the user who authored the reacted message | | ReferenceUsername | string | yes | Display name of the user who authored the reacted message | ## Referenced types ### CustomRole CustomRole | Field | Type | Required | Notes | | --- | --- | --- | --- | | ID | string | yes | Discord role ID | | Name | string | yes | Role name | | Color | int | yes | Role color as integer |