Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1e0b8ce
refactor: incorporate changes from #17 and #19
null8626 Apr 18, 2025
baf0c6c
feat: remove anything shards related
null8626 Apr 18, 2025
0f92f19
feat: remove discriminators and default avatars
null8626 Apr 18, 2025
651991b
feat: deprecate certified-related things
null8626 Apr 18, 2025
ff29709
feat: remove user fetching
null8626 Apr 18, 2025
34dea32
feat: adapt more properties to v0
null8626 Apr 18, 2025
a56c3d5
feat: remove Social.java
null8626 Apr 18, 2025
370e9e8
fix: enforce int/long consistency (fixes #7)
null8626 Apr 18, 2025
4e93b6d
feat: add page feature for getVoters
null8626 Apr 18, 2025
1e67e6a
feat: add several bounds checking countermeasures
null8626 Apr 18, 2025
0885dde
fix: add error checking for the sort parameter
null8626 Apr 18, 2025
a9322bb
fix: several bug-fixes, gradle build should work now
null8626 Apr 21, 2025
533281e
doc: reword error message
null8626 Apr 21, 2025
2951870
feat: add github and owners property
null8626 Apr 21, 2025
9c7409d
feat: fully adapt to v0
null8626 Jun 16, 2025
e4282a6
feat: add widgets
null8626 Jun 17, 2025
fb681b2
feat: add small widgets
null8626 Jun 18, 2025
bf09f9b
docs: readme overhaul
null8626 Jun 23, 2025
0255cb1
feat: add webhooks
null8626 Jun 27, 2025
aec9368
feat: migrate entity to project
null8626 Sep 17, 2025
0b6dd2e
revert: revert renaming project to entity
null8626 Oct 9, 2025
cb06ec6
revert: revert various breaking changes
null8626 Oct 9, 2025
dbf6ac4
revert: revert more breaking changes
null8626 Oct 9, 2025
d4f9c98
revert: revert getUser
null8626 Oct 9, 2025
0d34e63
revert: revert postServerCount back to setStats
null8626 Oct 9, 2025
faf8b19
revert: revert forms of getBots()
null8626 Oct 9, 2025
f6284e7
feat: use long instead of int for autoposter server count
null8626 Oct 9, 2025
83ff3f1
meta: update gradle
null8626 Oct 9, 2025
fe4f856
refactor: remove unused import
null8626 Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.gradle/
build/
320 changes: 258 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,302 @@
# DBL Java Library
A Java wrapper for the [top.gg API](https://top.gg/api/docs)
# Top.gg Java SDK

The community-maintained Java library for Top.gg.

## Installation

[![Release](https://jitpack.io/v/top-gg/java-sdk.svg)](https://jitpack.io/#top-gg/java-sdk)

Replace `VERSION` here with the latest version or commit hash. The latest version can be found [under GitHub releases](https://github.com/top-gg-community/java-sdk/releases).

### Maven

```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>com.github.top-gg</groupId>
<artifactId>java-sdk</artifactId>
<version>VERSION</version>
</dependency>
</dependencies>
```

### Gradle

```gradle
repositories {
maven { url 'https://jitpack.io' }
}

dependencies {
compile 'com.github.top-gg:java-sdk:VERSION'
}
```

## Setting up

```java
final DiscordBotListAPI client = new DiscordBotListAPI
.Builder()
.token(System.getEnv("TOPGG_TOKEN"))
.botId("BOT_ID")
.build();
```

## Usage

First, build a DiscordBotListAPI object.
### Getting a bot

```java
DiscordBotListAPI api = new DiscordBotListAPI.Builder()
.token("token")
.botId("botId")
.build();
final Bot bot = client.getBot("264811613708746752").toCompletableFuture().get();
```

#### Posting stats
### Getting several bots

DBL provides three ways to post your bots stats.
#### With defaults

**#1**
Posts the server count for the whole bot.
```java
int serverCount = ...; // the total amount of servers across all shards
final BotResult result = client.getBots().toCompletableFuture().get();
final List<Bot> bots = result.getResults();
```

#### With explicit arguments

api.setStats(serverCount);
```java
// Limit Offset Sort by
final BotResult result = client.getBots(50, 0, "date").toCompletableFuture().get();
final List<Bot> bots = result.getResults();
```

**#2**
Posts the server count for an individual shard.
### Getting your bot's voters

#### First page

```java
int shardId = ...; // the id of this shard
int shardCount = ...; // the amount of shards
int serverCount = ...; // the server count of this shard
final List<SimpleUser> voters = client.getVoters().toCompletableFuture().get();
```

#### Subsequent pages

api.setStats(shardId, shardCount, serverCount);
```java
final List<SimpleUser> voters = client.getVoters(2).toCompletableFuture().get();
```

### Check if a user has voted for your bot

```java
final boolean hasVoted = client.hasVoted("661200758510977084").toCompletableFuture().get();
```

**#3**
Posts the server counts for every shard in one request.
### Getting your bot's server count

```java
List<Integer> shardServerCounts = ...; // a list of all the shards' server counts
final long serverCount = client.getServerCount().toCompletableFuture().get();
```

### Posting your bot's server count

api.setStats(shardServerCounts);
```java
client.postServerCount(bot.getServerCount()).toCompletableFuture().get();
```

#### Checking votes
### Automatically posting your bot's server count every few minutes

#### With defaults

```java
String userId = ...; // ID of the user you're checking
api.hasVoted(userId).whenComplete((hasVoted, e) -> {
if(hasVoted)
System.out.println("This person has voted!");
else
System.out.println("This person has not voted!");
client.startAutoposter(() -> {
return bot.getServerCount();
});
```

#### Getting voting multiplier
#### With a callback

```java
api.getVotingMultiplier().whenComplete((multiplier, e) -> {
if(multiplier.isWeekend())
System.out.println("It's the weekend, so votes are worth 2x!");
else
System.out.println("It's not the weekend :pensive:");
client.startAutoposter(() -> {
return bot.getServerCount();
}, new BiConsumer<>() {
@Override
public void accept(Integer serverCount, Throwable error) {
if (serverCount != null) {
System.out.println("Successfully posted " + serverCount + " servers to Top.gg!");
} else {
System.err.println("Post error: " + error.getMessage());

client.stopAutoposter();
}
}
});
```

## Download
#### With a custom delay

[![Release](https://jitpack.io/v/top-gg/java-sdk.svg)](https://jitpack.io/#top-gg/java-sdk)
```java
// Posts once every 30 minutes
client.startAutoposter(1800, () -> {
return bot.getServerCount();
}, new BiConsumer<>() {
@Override
public void accept(Integer serverCount, Throwable error) {
if (serverCount != null) {
System.out.println("Successfully posted " + serverCount + " servers to Top.gg!");
} else {
System.err.println("Post error: " + error.getMessage());

Replace `VERSION` with the latest version or commit hash. The latest version can be found under releases.
client.stopAutoposter();
}
}
});
```

#### Maven
### Checking if the weekend vote multiplier is active

```xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
```java
final boolean multiplierActive = client.getVotingMultiplier().toCompletableFuture().get().isWeekend();
```
```xml
<dependencies>
<dependency>
<groupId>com.github.top-gg</groupId>
<artifactId>java-sdk</artifactId>
<version>VERSION</version>
</dependency>
</dependencies>

### Generating widget URLs

#### Large

```java
final String widgetUrl = Widget.large(Widget.Type.DISCORD_BOT, "574652751745777665");
```

#### Gradle
```gradle
repositories {
maven { url 'https://jitpack.io' }
#### Votes

```java
final String widgetUrl = Widget.votes(Widget.Type.DISCORD_BOT, "574652751745777665");
```

#### Owner

```java
final String widgetUrl = Widget.owner(Widget.Type.DISCORD_BOT, "574652751745777665");
```

#### Social

```java
final String widgetUrl = Widget.social(Widget.Type.DISCORD_BOT, "574652751745777665");
```

### Webhooks

#### Being notified whenever someone voted for your bot

##### Spring Boot

In your `TopggWebhookFilterConfig.java`:

```java
import org.discordbots.api.client.entity.Vote;
import org.discordbots.api.client.webhooks.SpringBoot;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TopggWebhookFilterConfig {
@Bean
public FilterRegistrationBean<SpringBoot<Vote>> registerVoteWebhook() {
final FilterRegistrationBean<SpringBoot<Vote>> registrationBean = new FilterRegistrationBean<>();

registrationBean.setFilter(new SpringBoot<>(Vote.class, System.getenv("MY_TOPGG_WEBHOOK_SECRET")) {
@Override
public void callback(final Vote vote) {
System.out.println("A user with the ID of " + vote.getVoterId() + " has voted us on Top.gg!");
}
});

registrationBean.addUrlPatterns("/votes");
registrationBean.setOrder(1);

return registrationBean;
}
}
```
```gradle
dependencies {
compile 'com.github.top-gg:java-sdk:VERSION'

##### Dropwizard

In your `MyVoteListener.java`:

```java
import org.discordbots.api.client.entity.Vote;
import org.discordbots.api.client.webhooks.Dropwizard;

import jakarta.ws.rs.Path;

@Path("/votes")
public class MyVoteListener extends Dropwizard<Vote> {
public MyVoteListener() {
super(Vote.class, System.getenv("MY_TOPGG_WEBHOOK_SECRET"));
}

@Override
public void callback(final Vote vote) {
System.out.println("A user with the ID of " + vote.getVoterId() + " has voted us on Top.gg!");
}
}
```

In your `MyServer.java`:

```java
import io.dropwizard.core.Application;
import io.dropwizard.core.Configuration;
import io.dropwizard.core.setup.Environment;
import io.dropwizard.jersey.setup.JerseyEnvironment;

public class MyServer extends Application<Configuration> {
public static void main(String[] args) throws Exception {
new MyServer().run(args);
}

@Override
public void run(Configuration config, Environment env) {
final JerseyEnvironment jersey = env.jersey();

jersey.register(new MyVoteListener());
}
}
```

##### Eclipse Jetty

In your `MyServer.java`:

```java
import org.discordbots.api.client.entity.Vote;
import org.discordbots.api.client.webhooks.EclipseJetty;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class MyServer {
public static void main(String[] args) throws Exception {
final Server server = new Server(8080);
final ServletContextHandler handler = new ServletContextHandler();

handler.setContextPath("/");
handler.addServlet(new ServletHolder(new EclipseJetty<>(Vote.class, System.getenv("MY_TOPGG_WEBHOOK_SECRET")) {
@Override
public void callback(final Vote vote) {
System.out.println("A user with the ID of " + vote.getVoterId() + " has voted us on Top.gg!");
}
}), "/votes");

server.setHandler(handler);
server.start();
server.join();
}
}
```
Loading