Pandora is a multi-track Discord voice recorder written in Typescript. This project should actually be considered as a partial fork of Yahweasel's Craig, as the recording process is pretty much the same. Initially, I just needed to add some workflow changes to Craig, but plain Javascript wasn't that convenient to work with, and I ended up refactoring the whole thing, cherry-picking the functionalities I wanted.
Pandora can be regarded as a simplified version of Craig, intended to be used to record a single voice channel at a time.
This repository contains just the recording part, storing raw, unusable data. The cooking part, processing the data into an audio file (or zip file with multiple tracks) can be found here. The two projects are separated to allow for some sort of "horizontal scaling". One cooking server can be used with multiples bots (or multiple shards). The number of cooking servers can then be increased along with the workload.
There are three ways to use Pandora. Using text-based commands, interactions, or pub/sub messages component to begin/end the recording. See configuration section.
# You can configure the command prefix, see "configuration" section
# Start a recording session
<COMMAND_PREFIX>record
# End a recording session
<COMMAND_PREFIX>end
# Start a recording session
/record
# End a recording session
/end
The pub/sub communication is using the Request/Reply pattern. The pub/sub component itself can be any valid Dapr pub/sub component. See configuration section.
Message topics and payloads are as follow :
In order to begin a recording session, a message must be published to the topic startRecordingDiscord
.
This message must contain the ID of the voice channel to record.
pubsub.publish("startRecordingDiscord", {
voiceChannelId: "<ID of the voice channel to record>",
});
Once the recording started, an acknowledgment will be sent on the topic startedRecordingDiscord
, echoing the sent payload.
Likewise, to stop recording, a message must be published to the topic stopRecordingDiscord
. This message can be handled in two ways :
This allows for multiple bot instances recording multiple voices channels at the same time to be controlled by the same backing process.
The acknowledgment will be sent on the topic stoppedRecordingDiscord
.
Pandora uses 5 modules:
# Mandatory variables
# Discord bot token
PANDORA_TOKEN=
# Prefix for text-based command
COMMAND_PREFIX=
# Dapr component name for state storage
STORE_NAME=
# Optional variables
If defined: Slash commands aren't published
DISABLE_INTERACTIONS=
# Dapr callback port
DAPR_SERVER_PORT=
# Dapr Http port.
DAPR_HTTP_PORT=
# Variables for "complete" deployment
# Dapr component name for object storage
OBJECT_STORE_NAME=
# Dapr component name for pub/sub support
PUBSUB_NAME=
Dapr is used a decoupling solution. Dapr uses components to define the implementation of some part of the application at runtime using a sidecar architecture.
These components are YAML files mounted in the sidecar as a volume. You can find a sample deployment using these components in the sample implementation section.
This project is meant to be modular. The most basic setup offers the following features :
To achieve this, we need three components :
To deploy this setup, you can use the following commands :
# Copy the sample dotenv file, don't forget to replace all mandatory variables
cp .env.example samples/minimal/.env
cd samples/minimal
docker compose up
If you start a recording with either a slash command or a text command, you'll get the recording ID.
Recording started with id <ID>
Once you've finished recording, you can retrieve the audio files using the open port on the cooking server.
Open a browser and type :
localhost:3004/<ID>
to retrieve the recording in the default format (OGG, all users mixed as a single track)
This deployment is simple, but lacks two features:
Although not mandatory, these two features are somewhat the reason Pandora exists, as I use the bot as part of a larger system.
This deployment can be found in the samples/complete directory.