arRPC

repository·main·Indexed 20 days ago

https://github.com/openasar/arrpc

An open Discord RPC server for atypical setups, providing a library for implementing Remote Procedure Call (RPC) mechanisms. It supports Bridge WebSocket servers and Electron client integrations, allowing developers to bridge custom application states to Discord-like interfaces via the RPCServer class and various transport layers including IPC and WebSockets.

Tokens
1.6K
Snippets
9
Records
10
Agent score
73%

What's inside arrpc

  1. Implement SET_ACTIVITY logic via RPCServer

    main

    When a client sends the SET_ACTIVITY command, the RPCServer processes the activity payload and emits an activity event. This is used to bridge custom application states to a Discord-like interface.

    Supported Activity Fields:

    • buttons: An array of objects { url, label }. These are mapped to metadata.button_urls and extra.buttons.
    • timestamps: Objects containing start/end times. If provided as seconds, they are automatically converted to milliseconds.
    • instance: A boolean. If true, sets the flags bitmask to 1 (indicating an instance).
    • pid: The process ID associated with the activity.

    Clearing Activity: To clear the activity, send a SET_ACTIVITY command with a null activity argument. This will trigger an activity event with activity: null.

  2. Use the Bridge Mod for Web-based RPC

    main
    The bridge_mod.js example demonstrates how to implement a simple modification for using the arRPC Bridge WebSocket server. This is specifically intended for setting RPC status when working with a Web-based environment (using 'just Web').
    bridge_mod.js
  3. Configure the arRPC bridge port via environment variables

    main

    The arRPC bridge uses a WebSocket server to pass information to a web application. By default, it listens on port 1337. You can change this port by setting the ARRPC_BRIDGE_PORT environment variable. The value must be a valid integer.

    export ARRPC_BRIDGE_PORT=8080
  4. Initialize an arRPC Server and bridge activity

    main

    To use arRPC as a CLI/entrypoint tool, you can instantiate a Server and listen for the activity event. When an activity event is emitted, you can use Bridge.send(data) to forward that data through the bridge. This pattern is typically used to relay communication between a local server and a bridge module.

    import Server from './server.js';
    import * as Bridge from './bridge.js';
    
    (async () => {
      const server = await new Server();
    
      server.on('activity', data => Bridge.send(data));
    })();
  5. Handle DEEP_LINK commands

    main

    When a client sends the DEEP_LINK command, the RPCServer emits a link event. This event provides the arguments passed by the client and a deep_callback function.

    Calling deep_callback(true) sends a success response to the client. Calling deep_callback(false) sends an ERROR event.

    server.on('link', (args, deep_callback) => {
      // Attempt to open a deep link
      const success = openLink(args);
      deep_callback(success);
    });
  6. Use the send function to broadcast messages

    main

    The send function is used to broadcast messages to all connected WebSocket clients. When a message is sent, it is stored in a lastMsg cache keyed by socketId. This allows newly connected clients to 'catch up' by receiving the last known activity for their specific ID.

    import { send } from './bridge.js';
    
    send({
      socketId: 'unique-client-id',
      activity: 'some-activity-data'
    });
  7. Handle RPCServer events

    main

    The RPCServer emits several events that allow you to react to client connections, messages, and activity changes.

    Key events include:

    • connection: Emitted when a new socket connects. The socket object is provided.
    • message: Emitted when a client sends a command. The payload contains { socket, cmd, args, nonce }.
    • close: Emitted when a socket connection is closed.
    • activity: Emitted when the client's activity (e.g., Discord Rich Presence) is updated or cleared.
    • invite: Emitted when the INVITE_BROWSER command is received.
    • guild-template: Emitted when the GUILD_TEMPLATE_BROWSER command is received.
    • link: Emitted when the DEEP_LINK command is received.
    const server = await new RPCServer();
    
    server.on('connection', (socket) => {
      console.log('New client connected:', socket.socketId);
    });
    
    server.on('activity', ({ activity, pid, socketId }) => {
      console.log(`Activity updated for PID ${pid} on socket ${socketId}`);
    });
  8. Handle INVITE_BROWSER and GUILD_TEMPLATE_BROWSER commands

    main

    The RPCServer supports two commands for handling browser-based redirects for Discord-style invites and templates:

    1. INVITE_BROWSER: Emits the invite event with the code from args.
    2. GUILD_TEMPLATE_BROWSER: Emits the guild-template event with the code from args.

    Both commands provide a callback function that allows you to signal success or failure back to the client. If the validation fails, you should call the callback with false to return an error code to the client (4011 for invites, 4017 for templates).

    server.on('invite', (code, callback) => {
      const isValid = validateInvite(code);
      // callback(true) sends success; callback(false) sends error
      callback(isValid);
    });
  9. Initialize the RPCServer

    main

    The RPCServer class is the main entry point for the arRPC bridge. It extends EventEmitter and automatically initializes multiple transport layers: IPC, WebSocket, and optionally a Process Scanner.

    Because the constructor returns an async IIFE, you must await the instantiation to ensure all transport servers (IPC, WS, and Process) are fully started before use.

    By default, the server enables process scanning unless the --no-process-scanning CLI flag is present or the ARRPC_NO_PROCESS_SCANNING environment variable is set.

    import RPCServer from './src/server.js';
    
    const server = await new RPCServer();
    // The server is now running and listening on IPC and WebSocket transports