Skip to main content
Version: Latest

3rd party tools

Cross-seed with autobrr

Heads up

This is meant for advanced users. If you're not familiar with cross-seed already, we suggest you read their documentation before you continue.

Don't expect any support for setting this up. If you need help setting up cross-seed, you need to reach out to them directly.

With this setup you can utilize autobrr with cross-seed to automatically cross-seed newly announced torrents from indexer Y that matches existing torrents in your torrent client from indexer X.

Install cross-seed and its dependencies

You can install cross-seed in several ways. Docker is recommended, but installing via npm or yarn (requires node 16 or greater) is also fine.

In this guide we will install it with npm. This method requires node 16 or greater. https://github.com/nodesource/distributions/blob/master/README.md#using-debian-as-root-3

# Elevate to root and install Node.js LTS (v18.x)
sudo su -
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - &&\
apt-get install -y nodejs

# Install cross-seed
npm install -g cross-seed

Generate config and make sure the port isn't exposed to the internet

# Generate a cross-seed config file
cross-seed gen-config

# Open the file
nano /home/$USER/.cross-seed/config.js

# Make sure the following parameters are set within the config

# You need to add at least one torznab URL from Prowlarr to the config for it to be valid
# They will not be used by autobrr

# outputDir needs to exist, but will not be used

torznab: [
"http://127.0.0.1:9696/1/api?apikey=APIKEY&tracker=Tracker1",
"http://127.0.0.1:9696/2/api?apikey=APIKEY&tracker=Tracker2"
],
torrentDir: "/home/$USER/.local/share/qBittorrent/BT_backup",
outputDir: "/home/$USER/torrentfiles",
action: "inject",
qbittorrentUrl: "http://user:pass@localhost:port",
apiAuth: true,
Make sure the port is not exposed to the internet

Even with API auth enabled, cross-seed still recommends that you do not expose its port to untrusted networks (such as the Internet). You can use iptables or UFW to solve this.
The cross-seed daemon uses port 2468 by default. If you want to expose cross-seed to another server on the internet substitute 127.0.0.1 with the IP of the corresponding server.

sudo apt-get install iptables

iptables -A INPUT -p tcp --dport 2468 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 2468 -j DROP

Start the cross-seed daemon

To make autobrr communicate with cross-seed, you need to run cross-seed in daemon mode. In this guide we will set up a systemd service. You can also set it up with screen or docker.

Systemd

touch /etc/systemd/system/cross-seed.service

You'll want to customize the following variables:

  • {user}: your user, or another user if you want to create a separate user for cross-seed
  • {group}: your group, or another group if you want to create a separate group for cross-seed
  • /path/to/node: run the command which node in your terminal, then paste the output here.
/etc/systemd/system/cross-seed.service
[Unit]
Description=cross-seed daemon
[Service]
User={user}
Group={group}
Restart=always
Type=simple
ExecStart=/path/to/node cross-seed daemon
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload # tell systemd to discover the unit file you just created
sudo systemctl enable cross-seed # enable it to run on restart
sudo systemctl start cross-seed # start the service
sudo journalctl -u cross-seed # view the logs

Create the cross-seed filter in autobrr

The way this works is you create a filter with a higher priority set than any other filter to make sure every cross-seed match is forwarded to the cross-seed daemon instead of being run through other filters.

  1. Get your API key with the following command:

    cross-seed api-key

    Keep this key at hand since we will need it at step 5 later on.
    In the rest of this tutorial, we will refer to this as YOUR_API_KEY.

  2. Create a filter and name it eg. cross-seed.

  3. Select all the indexers you want to use, preferably all of them.

  4. Set a really high priority to make sure it's always higher than your other filters.

  5. Go to the External tab, and add a new External filter.

    • Type: Webhook
    • Host: http://localhost:2468/api/announce
    • Headers: x-api-key=YOUR_API_KEY
    • HTTP Method: POST
    • Expected http status: 200
    • Data (JSON):
    {
    "name": "{{ .TorrentName }}",
    "guid": "{{ .TorrentUrl }}",
    "link": "{{ .TorrentUrl }}",
    "tracker": "{{ .Indexer | js}}"
    }
  6. Go to the Actions tab and create a Test action. This is required for the webhook to work.

  7. Finally, make sure the filter is enabled and you're all set.

Cross-seed notifications

You can set up a Notifiarr or Apprise webhook for cross-seed notifications within the cross-seed config.

Upgraderr - Arr, deduplication, and cross-seed functionality

Heads up

This is meant for any kind of user. There is no configuration, and it's nearly impossible to make a mistake so long as the guide is followed with the modest amount of care.

What is this

Upgraderr is a title parser that matches existing titles present in your qBittorrent client with the title submitted and returns a HTTP return code. The return codes indicate an action to perform next, if applicable.

Arr functionality

On any filter, you may utilize the external tab as a pre-filter. Using this with a return code of 200 permits any unique titles to be added, or if they're a quality upgrade. This also acts as a deduplicator should you wish.

Coupling this with the extensive filtering built-in to autobrr allows you to specify qualities to stop accepting upgrades at, should you wish. This allows you to replace applications such as Sonarr / Radarr.

On the external Webhook action, utilize the following payload, replacing the host(s), user and password with your configuration. The expected return code is 200.

  • Host:
http://upgraderr:6940/api/upgrade
  • Payload:
{
"host": "http://qbittorrent:8080",
"user": "username",
"password": "password",
"name": "{{ .TorrentName | js }}"
}

Cross-Seed functionality

At the time of this writing, Upgraderr has excellent cross-seed functionality that runs in milliseconds. Presently there's a partial matcher implemented, where if 80% of the data matches the existing torrent, the new torrent will have the conflicting files (should they exist) renamed, to not corrupt the existing torrent.

On the external Webhook action, utilize the following payload, replacing the host(s), user and password with your configuration. The expected return code is 250.

  • Host:
http://upgraderr:6940/api/upgrade
  • Payload:
{
"host": "http://qbittorrent:8080",
"user": "username",
"password": "password",
"name": "{{ .TorrentName | js }}"
}

Once the pre-hook succeeds, create a Webhook action, replacing the same variables as before.

  • Host:
http://upgraderr:6940/api/cross
  • Payload:
{
"host": "http://qbittorrent:8080",
"user": "username",
"password": "password",
"name": "{{ .TorrentName | js }}",
"hash": "{{ .TorrentHash }}",
"torrent": "{{ .TorrentDataRawBytes | js }}"
}

Finally

This is a toolchest, other functionality can be achieved by using other return codes, and attaching other tools to actions taken by the application.

More Information: github.com/kylesanderson/upgraderr