/lanyard

🏷️   Expose your Discord presence and activities to a RESTful API and WebSocket in less than 10 seconds

Primary LanguageElixirMIT LicenseMIT

Lanyard Logo

🏷️ Expose your Discord presence and activities to a RESTful API and WebSocket in less than 10 seconds

Lanyard is a service that makes it super easy to export your live Discord presence to an API endpoint (api.lanyard.rest/v1/users/:your_id) and to a WebSocket (see below) for you to use wherever you want - for example, I use this to display what I'm listening to on Spotify on my personal website.

You can use Lanyard's API without deploying anything yourself - but if you want to self host it, you have the option to, though it'll require a tiny bit of configuration.

Get started in < 10 seconds

Just join this Discord server and your presence will start showing up when you GET api.lanyard.rest/v1/users/:your_id. It's that easy.

API Docs

Getting a user's presence data

GET https://api.lanyard.rest/v1/users/:user_id

Example response:

{
  "success": true,
  "data": {
    "active_on_discord_mobile": false,
    "active_on_discord_desktop": true,
    "listening_to_spotify": true,
    // Below is a custom crafted "spotify" object, which will be null if listening_to_spotify is false
    "spotify": {
      "timestamps": {
        "start": 1615529820677,
        "end": 1615530068733
      },
      "song": "Let Go",
      "artist": "Ark Patrol; Veronika Redd",
      "album_art_url": "https://i.scdn.co/image/ab67616d0000b27364840995fe43bb2ec73a241d",
      "album": "Let Go"
    },
    "discord_user": {
      "username": "Phineas",
      "public_flags": 131584,
      "id": "94490510688792576",
      "discriminator": "0001",
      "avatar": "a_7484f82375f47a487f41650f36d30318"
    },
    "discord_status": "online",
    // activities contains the plain Discord activities array that gets sent down with presences
    "activities": [
      {
        "type": 2,
        "timestamps": {
          "start": 1615529820677,
          "end": 1615530068733
        },
        "sync_id": "3kdlVcMVsSkbsUy8eQcBjI",
        "state": "Ark Patrol; Veronika Redd",
        "session_id": "140ecdfb976bdbf29d4452d492e551c7",
        "party": {
          "id": "spotify:94490510688792576"
        },
        "name": "Spotify",
        "id": "spotify:1",
        "flags": 48,
        "details": "Let Go",
        "created_at": 1615529838051,
        "assets": {
          "large_text": "Let Go",
          "large_image": "spotify:ab67616d0000b27364840995fe43bb2ec73a241d"
        }
      },
      {
        "type": 0,
        "timestamps": {
          "start": 1615438153941
        },
        "state": "Workspace: lanyard",
        "name": "Visual Studio Code",
        "id": "66b84f5317e9de6c",
        "details": "Editing README.md",
        "created_at": 1615529838050,
        "assets": {
          "small_text": "Visual Studio Code",
          "small_image": "565945770067623946",
          "large_text": "Editing a MARKDOWN file",
          "large_image": "565945077491433494"
        },
        "application_id": 383226320970055681
      }
    ]
  }
}

Socket Docs

The websocket is available at wss://api.lanyard.rest/socket. If you would like to use compression, please specify ?compression=zlib at the end of the URL.

Once connected, you will receive Opcode 1: Hello which will contain heartbeat_interval in the data field. You should set a repeating interval for the time specified in heartbeat_interval which should send Opcode 3: Heartbeat on the interval. You should also be sending Opcode 2: Initialize immediately once connected.

Example of Opcode 2: Initialize:

{
  op: 2,
  d: {
    // subscribe_to_ids should be an array of user IDs you want to subscribe to presences from
    // if Lanyard doesn't monitor an ID specified, it won't be included in INIT_STATE
    subscribe_to_ids: ["94490510688792576"]
  }
}

If you just want to subscribe to one user, you can send subscribe_to_id instead with a string of a single user ID to subscribe to. Then, the INIT_STATE's data will just contain the presence object for the user you've subscribed to instead of a user_id->presence map.

Once sent, you should immediately receive a INIT_STATE event payload if connected successfully. If not, you will be disconnected with an error (see below).

List of Opcodes

Opcode Name Description Client Send/Recv
0 Event This is the default opcode when receiving core events from Lanyard, like INIT_STATE Receive
1 Hello Lanyard sends this when clients initially connect, and it includes the heartbeat interval Receive Only
2 Initialize This is what the client sends when receiving Opcode 1 from Lanyard - it should contain an array of user IDs to subscribe to Send only
3 Heartbeat Clients should send Opcode 3 every 30 seconds (or whatever the Hello Opcode says to heartbeat at) Send only

Events

Events are received on Opcode 0: Event - the event type will be part of the root message object under the t key.

Example Event Message Objects

INIT_STATE

{
  op: 0,
  seq: 1,
  t: "INIT_STATE",
  d: {
    "94490510688792576": {
      // Full Lanyard presence (see API docs above for example)
    }
  }
}

PRESENCE_UPDATE

{
  op: 0,
  seq: 2,
  t: "PRESENCE_UPDATE",
  d: {
    // Full Lanyard presence and an extra "user_id" field
  }
}

Error Codes

Lanyard can disconnect clients for multiple reasons, usually to do with messages being badly formatted. Please refer to your WebSocket client to see how you should handle errors - they do not get received as regular messages.

Types of Errors

Name Code Data
Invalid/Unknown Opcode 4004 unknown_opcode

Used By

Below is a list of sites using Lanyard right now, check them out! A lot of them will only show an activity when they're active. Create a PR to add your site below!

Todo

  • Landing page?