Skip to content

Activities (Microapps) โ€‹

Discord-style in-call activities โ€” widget apps that appear as extra tiles inside the voice call view, alongside real participants.

How it works โ€‹

When an activity is added to a room, it's stored as a Matrix im.vector.modular.widgets state event. Every client reads this event and renders the widget as a full-width tile in the call grid. The ๐Ÿš€ Activities button in the call control bar opens the app picker.

User clicks ๐Ÿš€ โ†’ picks YouTube โ†’ state event written to room
โ†’ all clients read state โ†’ YouTube tile appears in call grid
โ†’ host controls playback โ†’ sync commands sent as room events
โ†’ all clients seek to the same timestamp

Available Activities โ€‹

YouTube Together โ€‹

Watch YouTube videos in sync. One person controls playback; everyone follows.

FeatureDetail
Sync mechanismMatrix room state + command events
Drift compensationtimestamp + (Date.now() โˆ’ issuedAt) / 1000
Late-joinersCurrent position stored in room state; new clients seek on load

Supported URLs:

  • https://youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://youtube.com/shorts/VIDEO_ID

Spotify Together โ€‹

Share a Spotify track, album, or playlist. Everyone sees the same embed.

Note: True playback sync requires Spotify Premium + OAuth per user. This embeds the same URL for all members; each controls their own playback locally.

Polls (optional, requires Docker) โ€‹

Create and vote on polls directly in the room. Powered by nordeck/matrix-poll-widget.

Whiteboard (optional, requires Docker) โ€‹

Real-time collaborative whiteboard. Powered by nordeck/matrix-neoboard-widget.

Setting up Polls & Whiteboard โ€‹

YouTube and Spotify are built in โ€” no setup needed. Polls and Whiteboard require self-hosted Docker containers.

1. Configure environment variables โ€‹

env
# Public URL where users' browsers reach the polls container
MESH_POLLS_URL=https://polls.your-domain.com

# Public URL where users' browsers reach the whiteboard container
MESH_WHITEBOARD_URL=https://whiteboard.your-domain.com

2. Start the containers โ€‹

bash
# Start both:
docker compose --profile microapps up -d

# Then restart mesh so URLs are picked up:
docker compose restart mesh

3. Expose via reverse proxy โ€‹

nginx
# Polls
server {
    listen 443 ssl;
    server_name polls.your-domain.com;
    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_set_header Host $host;
        add_header Access-Control-Allow-Origin *;
    }
}

# Whiteboard
server {
    listen 443 ssl;
    server_name whiteboard.your-domain.com;
    location / {
        proxy_pass http://127.0.0.1:3003;
        proxy_set_header Host $host;
        add_header Access-Control-Allow-Origin *;
    }
}

No rebuild needed

At container startup, docker-entrypoint.sh generates /app/config-microapps.js with the URLs. Changing them only requires restarting the container โ€” no rebuild.

Released under the AGPL-3.0 License.