Skip to content

How to add license keys to a JDA bot ​

Short answer: add the SunLicense Java SDK, read the buyer's key from an environment variable or config.properties, check it before JDABuilder...build(), and exit when SunLicense says no. A network error is not a no: start anyway and check again later.

java
// build.gradle.kts: implementation("com.sunlicense:sunlicense:0.0.1") next to JDA, in one shadow jar
public static void main(String[] args) {
    SunLicense client = new SunLicense.Builder()
            .baseUrl("https://api.sunlicense.com").token(API_KEY).build();   // API key from your build, never git
    try {
        SunLicense.Result r = client.validate(System.getenv("LICENSE_KEY"), Map.of("host", machineId()));
        if (r.getStatus() == 400) {   // EXPIRED, REVOKED, TOO_MANY_MACHINES…
            System.err.println("License rejected: " + r.getBody());
            System.exit(1);
        }
    } catch (SunLicense.SunLicenseException e) {
        System.err.println("SunLicense unreachable, starting anyway: " + e.getMessage());
    }
    JDA jda = JDABuilder.createLight(System.getenv("DISCORD_TOKEN")).build();
}

Start from the template instead: example-discord-bot-jda (Java 21, JDA 6) has this plus a stable machine id, masked keys, re-checks every 6 hours, a signed offline license fallback, a sealed core package, a /license command, tests and CI.

Or let your AI agent do it: paste the setup prompt into your coding agent.

Free plan: 3 products, 100 licenses, no credit card. Create a free account.

Step by step ​

  1. In the dashboard: a product, a policy (1 machine = one running copy per license) and an API key, which can only validate licenses.
  2. One runnable jar. Add the SDK with implementation and build with Shadow; relocating it isn't needed in a bot that runs alone, but does no harm.
  3. Keep the API key out of git: put it in ~/.gradle/gradle.properties and expand it into a resource at build time. The buyer's DISCORD_TOKEN and LICENSE_KEY come from their environment or config.properties.
  4. Machine id as host: a hash of OS, architecture and host name (snippet in the Paper guide). In Docker, set a fixed hostname: or the container id changes on every restart.
  5. Results: 200 builds JDA, 400 exits with the reason (keys masked in logs), anything else starts and retries in about 10 minutes, or uses an offline license.
  6. Re-check every few hours on a ScheduledExecutorService; on a 400 call jda.shutdown() and exit.

Selling it ​

Tebex, Gumroad, Lemon Squeezy, Stripe, BuiltByBit and the other stores issue a key per purchase and revoke it on a refund. A jar downloaded from BuiltByBit or Voxel Shop can carry the key through a %%__SUNLICENSE__%% placeholder.

Going further ​

Send feedback

Found something broken, or have an idea? It goes straight to our board.

The first line becomes the title.
Images (optional, up to 5: paste, drop or capture)
Check each image before sending, and remove any that show something private.

We also receive this page's address and your browser version.

Ctrl Enter to send