npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@presenti/server

v1.2.6

Published

Lightweight REST API for retrieving the presence of a set list of Discord users.

Downloads

5

Readme

presenti

Service for tracking presences across various platforms.

Getting Started

Presenti is easy to deploy. My favorite method for maintaining an active process is pm2, though the process is unlikely to die, so you could run it in a detached screen if you watned.

Dependencies

  • PostgreSQL
  • Node >=12
  • TypeScript (only needed for development)
  • Discord (only needed if you want to have OAuth)
  1. Clone the latest version of presenti using git clone https://github.com/EricRabil/presenti.git
  2. Initialize the modules using npm i
  3. Initialize the service by running npm run run
  4. Presenti will ask you a few setup questions, like database credentials and other required details. It will then save the configuration file to config.json at the root of the project, and it will resemble this:
{
    "port": 8138,
    "registration": false,
    "discord": null,
    "crypto": {
        "jwtSecret": "<randomly generated secret>",
        "firstPartyKey": "<randomly generated secret>"
    },
    "web": {
        "host": "://localhost:8138"
    },
    "db": {
        "host": "localhost",
        "port": 5432,
        "name": "presenti",
        "username": "",
        "password": "",
        "cache": false
    },
    "modules": {}
}
  1. To generate a first-party API key for modules like presenti-additions, run the following in the Presenti shell and copy the results (I will be adding an admin panel for this eventually):
(Presenti) % await SecurityKit.firstPartyApiKey()

Modules

Presenti is built around modules, which can run in the server process or in their own process. If you'd like to load in modules, specify them and their configuration in the modules property of the config file.

Examples


Presenti Additions

Add the following entry to your modules file to add the @presenti/additions module, which includes Discord and Spotify integration.

{
  "modules": {
    "@presenti/additions": {
      "discord": {
          "token": "your token",
          "prefix": ">",
          "clientID": "your client ID",
          "clientSecret": "your client secret"
      },
      // It's important that you include this property, or spotifyInternal may not work correctly. Config generation for modules is coming soon.
      "spotifyInternal": {}
    }
  }
}

Streaming API

The Streaming API is for apps that are subscribing to presence data.

WebSocket

Currently, the Streaming API only exists on the WebSocket platform. If you have a use case for other platforms, please open an issue.

Subscribing to a presence is fairly straightforward. Simply open a connection to

ws://{host}/presence/{name}

Where host is the address to your server, and name is the name tied to the token.

Presence updates look like this, and are also sent upon connection:

{
  "activities": [
    {
      "presences": [
        {
          "title": "Listening to Spotify",
          "largeText": {
            "text": "Issues/Hold On",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "smallTexts": [
            {
              "text": "by Teyana Taylor",
              "link": "https://open.spotify.com/artist/4ULO7IGI3M2bo0Ap7B9h8a"
            },
            {
              "text": "on K.T.S.E.",
              "link": "https://open.spotify.com/album/0mwf6u9KVhZDCNVyIi6JuU"
            }
          ],
          "image": {
            "src": "https://i.scdn.co/image/ab67616d0000b273abca6b34e370af95f3b926bd",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "timestamps": {
            "start": 1589001619550,
            "stop": 1589002629550
          },
          "gradient": {
            "enabled": true
          },
          "isPaused": true
        }
      ]
    }
  ]
}

This is how that would be rendered

Rendered Presence

These are the only messages that will be sent by the server. If the connection closes, simply re-open the connection. There is no authentication necessary for this endpoint.

Presence API

The Presence API is for apps that are providing presence data to the service.

REST

The REST API is useful for platforms in which it is not feasible to maintain a WebSocket connection for updating your presence.

New Session

GET /session?token={your token}

Call this endpoint with a valid token to open a new presence session. The session will remain valid for as long as the value of expires, in milliseconds. This is server-configurable, and you can prevent the session from expiring by calling any of the below endpoints.

Example Response

{
  "sessionID": "34e7f94b-7fa3-4196-912a-88186b25299d",
  "expires": 10000
}

Update Presence

PUT /session?token={token}&id={sessionID}

Call this endpoint to update the presence state for the session. Calling this endpoint doubles as a session refresh, resetting the time until session expiration.

Example Request

{
  "presences": [
    {
      "presences": [
        {
          "title": "Listening to Spotify",
          "largeText": {
            "text": "Issues/Hold On",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "smallTexts": [
            {
              "text": "by Teyana Taylor",
              "link": "https://open.spotify.com/artist/4ULO7IGI3M2bo0Ap7B9h8a"
            },
            {
              "text": "on K.T.S.E.",
              "link": "https://open.spotify.com/album/0mwf6u9KVhZDCNVyIi6JuU"
            }
          ],
          "image": {
            "src": "https://i.scdn.co/image/ab67616d0000b273abca6b34e370af95f3b926bd",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "timestamps": {
            "start": 1589001619550,
            "stop": 1589002629550
          },
          "gradient": {
            "enabled": true
          },
          "isPaused": true
        }
      ]
    }
  ]
}

This is how that would be rendered

Rendered Presence

Example Response

{
  "ok": true
}

Refresh Session

PUT /session/refresh?token={token}&id={sessionID}

Call this endpoint to prevent the session from expiring, but don't have an updated payload to send.

Example Response

{
  "ok": true
}

WebSocket

The WebSocket API is useful for dedicated presence servers that will be sending a large or unknown amount of data.

An Overview

The WebSocket API follows the following general schema when exchanging data

{
  "type": 0,
  "data": []
}

Type Codes

These are the valid codes that may be sent or received over the WebSocket API. |Code|Name|Description|Sender|Response?| |-|-|-|-|-| |0|Ping|Pings the server|Client|✅| |1|Pong|Sent upon ping|Server|❎| |2|Presence|Updates presence, where the data property is an array of presence objects|Client|❎| |3|Identify|Authenticates session, where the data property is the user token|Client|✅| |4|Greetings|Sent by the server, upon successful authentication. Start sending pings after receiving greetings.|Server|❎|

Example messages

Identify

Sent upon connection open, this identifies the session for the server.

{
  "type": 3,
  "data": "{token}"
}
Ping

Though not required, these can help prevent a connection time-out and unnecessarily reconnecting.

{
  "type": 0
}
Presence Update
{
  "type":2,
  "data": [
    {
      "presences": [
        {
          "title": "Listening to Spotify",
          "largeText": {
            "text": "Issues/Hold On",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "smallTexts": [
            {
              "text": "by Teyana Taylor",
              "link": "https://open.spotify.com/artist/4ULO7IGI3M2bo0Ap7B9h8a"
            },
            {
              "text": "on K.T.S.E.",
              "link": "https://open.spotify.com/album/0mwf6u9KVhZDCNVyIi6JuU"
            }
          ],
          "image": {
            "src": "https://i.scdn.co/image/ab67616d0000b273abca6b34e370af95f3b926bd",
            "link": "https://open.spotify.com/track/0bxmVPKnEopTyuMMkaTvUb"
          },
          "timestamps": {
            "start": 1589001619550,
            "stop": 1589002629550
          },
          "gradient": {
            "enabled": true
          },
          "isPaused": true
        }
      ]
    }
  ]
}

This is how that would be rendered

Rendered Presence

Pre-requisites

  • Node 12
  • node-gyp capable device