XPost documentation#
Installation#
The recommended approach is to use the official container image from ghcr.io/zenfyrdev/xpost:latest
Podman Quadlets#
Example Rootful Quadlet. Make sure the data dir exists on the host and is owned by 1000:1000!
[Unit]
Description=XPost
[Container]
Image=ghcr.io/zenfyrdev/xpost:latest
EnvironmentFile=/etc/containers/systemd/xpost/.env
Volume=/var/containers/xpost/data:/app/data:Z
[Service]
Restart=always
RestartSec=10s
[Install]
WantedBy=default.target
Docker Compose#
Make sure the data dir exists on the host and is owned by 1000:1000!
services:
xpost:
image: ghcr.io/zenfyrdev/xpost:latest
restart: unless-stopped
env_file: ./.env
volumes:
- ./data:/app/data
Native Install#
The project uses uv, so a native install using a .venv is pretty simple.
- Make sure that
ffmpegandlibmagicare installed. - Download and install uv
- Clone the project
https://tangled.org/zenfyr.dev/xpost - Run
uv sync --locked
Quickstart#
Upon first launch, XPost will create a folder ./data with an example settings.json
Edit the file, and then start XPost again.
Features#
- Based on streaming APIs to instantly crosspost new posts.
- Splitting large posts into multiple smaller ones to fit into character limits.
- Supports quotes and reposts.
Configuration#
XPost config accepts an array of input -> outputs pairs. find all services and example configs in services.md.
All "key": "value" options can be set to env:VARIABLE to read envvars instead of storing things directly in the settings file.
Additionally XPost accepts some envvars.
| Key | Description |
|---|---|
DATA_DIR |
Base data directory. |
SETTINGS_DIR |
settings.json file location. |
DATABASE_DIR |
data.db file location. |
SLINGSHOT_URL |
URL of the microcosm slingshot service for resolving identities. |
JETSTREAM_URL |
URL of the Jetstream service for listening for incoming posts. |
Advanced Features#
bi-directional crossposting#
This is experimental and unstable.
XPost supports pointing to services directly at each other, posts crossposted from other services are marked as so, and are skipped to avoid creating infinite loops.
While this works for most things, cross-service replies can end up being duplicated multiple times over or cause an infinite loop, this usually happens when a post from one service is split into multiple other on the other.
e.g. Post A from Mastodon ends up as Post A1 and Post A2 on bsky, replying from bsky to either may result in Reply B being posted twice, or getting stuck in a loop.