SpigotSalesWebhook is a lightweight Java worker that watches SpigotMC premium resource buyer lists and sends Discord webhook notifications when new buyers appear.
It is designed for straightforward self-hosting: configure your Spigot cookie, Discord webhook URL, and resource buyer-list URLs once, then leave the worker running wherever you prefer. The first scan records the current buyers without sending old purchases; later scans only notify for new buyers.
- Hourly buyer scans: Polls configured Spigot resource buyer pages on a configurable interval.
- Discord embeds: Sends clean webhook embeds with buyer, plugin, price, currency, and purchase time.
- First-run baseline: Records existing buyers on the first run without spamming Discord.
- Single config file: Uses
src/main/resources/config.yml; no.envfile is required. - Self-hostable: Runs as a standalone Java process or Docker container.
- Java 25
- A Discord webhook URL
- A valid SpigotMC cookie with access to your premium resource buyer pages
Copy the example config and fill in your private values:
cp src/main/resources/config.example.yml src/main/resources/config.ymlWindows PowerShell:
Copy-Item src/main/resources/config.example.yml src/main/resources/config.ymlsrc/main/resources/config.yml is ignored by git. Do not commit your webhook URL or Spigot cookie.
Example:
discord:
webhook-url: "https://discord.com/api/webhooks/..."
username: "Spigot Sales"
spigot:
cookie: "xf_session=...; xf_user=...; xf_tfa_trust=..."
request-delay-ms: 800
plugins:
- name: "Plugin Name"
buyer-list-url: "https://www.spigotmc.org/resources/plugin-name.plugin-id/buyers"
scan:
interval-minutes: 60
notify-existing-on-first-run: false
state-file: "data/seen-sales.json"Windows:
gradlew.bat clean jarLinux / macOS:
./gradlew clean jarRun continuously:
java -jar build/libs/spigot-sales-webhook-1.0.1.jarRun one scan and exit:
java -jar build/libs/spigot-sales-webhook-1.0.1.jar --onceRun one scan and notify existing buyers too:
java -jar build/libs/spigot-sales-webhook-1.0.1.jar --once --notify-existingDocker is the recommended way to keep the worker running on a server.
- Create
src/main/resources/config.ymlfromsrc/main/resources/config.example.ymland fill in your Discord webhook URL and Spigot cookie. - Start the container:
docker compose up -d --build- Check logs:
docker compose logs -f spigot-sales-webhook- Stop the worker:
docker compose downThe compose file mounts src/main/resources/config.yml into /opt/spigot-sales-webhook/config.yml as read-only and mounts ./data into /opt/spigot-sales-webhook/data, so seen buyer state survives rebuilds and restarts. The container prepares the mounted data directory automatically before starting the worker.
The Docker image does not copy your real src/main/resources/config.yml into the image. Keep private webhook and cookie values only in your local config file.
Seen buyers are stored per plugin:
{
"initialized": true,
"seenSalesByPlugin": {
"Plugin Name": [
"examplebuyer"
]
}
}Delete the configured state file if you want the worker to rebuild its baseline from scratch.
We prioritize user privacy and application integrity. Please do not open public issues for discovered vulnerabilities.
Read our SECURITY.md for responsible disclosure reporting.
We welcome Pull Requests from the community. To help us maintain clean project history and formatting, please follow these guidelines:
- No tabs: Use spaces exclusively for indentation.
- Style consistency: Respect the established code architecture and style templates.
- Version control cleanliness: Do not increment project version numbers in example configurations within your PR.
- Minimal diffs: Disable automated reformat-on-save settings that affect untouched files.
Learn more via our formal Contribution Guidelines.
This project is licensed under the GPL-3.0 License.
See the LICENSE file for comprehensive copyright notices and third-party attributions.