Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
26a58c2
fix: fix GET /bots/votes not working
null8626 May 25, 2025
d2cb2ce
feat: add widgets
null8626 Jun 17, 2025
2327b15
feat: add small widgets
null8626 Jun 18, 2025
13982a5
style: remove trailing comma
null8626 Jun 23, 2025
46ef8d1
docs: readme overhaul
null8626 Jun 23, 2025
db99c59
feat: make webhooks more specific
null8626 Jun 24, 2025
327e15b
feat: remove features deprecated by v0
null8626 Jun 24, 2025
1a03b27
feat: remove BotStats
null8626 Jul 4, 2025
ed43118
deps: remove the dependence on @top-gg/eslint-config
null8626 Jul 16, 2025
b27d294
feat: adapt to v1
null8626 Sep 10, 2025
1b2027c
*: minor tweaks
null8626 Sep 12, 2025
157a44c
[doc,revert]: rename WebhookVotePayload to WebhookPayload, TopggAPIEr…
null8626 Sep 13, 2025
4192bd3
refactor: remove redundant checks
null8626 Sep 13, 2025
8f986e1
feat: separate v1 from v0
null8626 Sep 13, 2025
6d866f5
refactor: use Bearer prefix for legacy and new tokens
null8626 Sep 15, 2025
66adfe3
doc: add @see Webhook#voteListener
null8626 Sep 15, 2025
3a234ad
doc: update documentation and readme
null8626 Sep 15, 2025
b2652b2
meta: make SDK description clearer
null8626 Sep 15, 2025
89be620
revert: revert breaking changes to webhooks
null8626 Sep 16, 2025
6fe8cf4
revert: revert breaking changes
null8626 Sep 18, 2025
840abb8
doc: update readme
null8626 Oct 3, 2025
15fb73a
ci: bump github workflow dependency versions
null8626 Oct 7, 2025
1ddf708
doc: fix less accurate naming
null8626 Oct 10, 2025
59c5257
doc: objects, not dicts
null8626 Oct 10, 2025
aa408ac
doc: documentation tweaks
null8626 Oct 10, 2025
9f88be3
feat: rename postBotCommands to postCommands
null8626 Oct 10, 2025
eb64cb1
doc: readme tweak
null8626 Oct 10, 2025
2c159e0
doc: fix API version links in README.md
null8626 Oct 20, 2025
40cae1c
doc: remove for more information link from README
null8626 Oct 21, 2025
7d342ca
revert: revert changes to the GitHub Workflows and eslint rules
null8626 Feb 1, 2026
4572c80
revert: revert Authorization header change
null8626 Feb 1, 2026
6768ba1
revert: revert back to TopGGAPIError
null8626 Feb 1, 2026
3059297
revert: revert dependency version bumps
null8626 Feb 1, 2026
e1226fd
revert: revert script updates
null8626 Feb 1, 2026
0871797
fix: add discord-api-types to dev dependencies
null8626 Feb 1, 2026
5f70047
revert: revert changes to the error class
null8626 Feb 1, 2026
bc9011f
fix: remove unused import
null8626 Feb 1, 2026
ecd1dc1
doc: minor readme tweaks
null8626 Feb 1, 2026
2aef3eb
doc: fix mismatched jsdoc argument name
null8626 Feb 1, 2026
bb84644
feat: delete v0 APIs
null8626 Feb 2, 2026
9bf3d96
deps: bump npm dependencies
null8626 Feb 2, 2026
d29d991
fix: fix eslint errors
null8626 Feb 2, 2026
bc29672
ci: update deprecated portion of pre-commit script
null8626 Feb 2, 2026
78302b9
meta: update npm scripts
null8626 Feb 2, 2026
d822d27
deps: bump CI dependencies
null8626 Feb 2, 2026
4d442bf
ci: also test for node 22 and 24
null8626 Feb 2, 2026
5608437
ci: drop support for node 18 as it does not work with undici 7 or later
null8626 Feb 2, 2026
7f4cd94
feat: add support for GET /v1/projects/@me
null8626 Feb 3, 2026
bb1a39e
style: fix eslint errors and warnings
null8626 Feb 3, 2026
cd651e2
feat: implement new webhook authorization approach
null8626 Feb 3, 2026
cd679c6
doc: add widgets example to readme
null8626 Feb 3, 2026
80e77e0
doc: add documentation for getSelf()
null8626 Feb 3, 2026
31712b6
refactor: use parsedSignature.t
null8626 Feb 3, 2026
0c1b82b
fix: forgot digest('hex')
null8626 Feb 3, 2026
12e2569
fix: add Bearer prefix to Authorization header
null8626 Feb 4, 2026
930f89b
[style,feat,meta]: prettier; update webhook typings and tsconfig
null8626 Feb 17, 2026
6cf58c1
feat: add trace property to webhook payload
null8626 Feb 17, 2026
55d920a
doc: fix typing documentation for WebhookTestPayload
null8626 Feb 17, 2026
6e29493
feat: make votedAt and expiresAt a Date type for consistency
null8626 Feb 17, 2026
19e319f
meta: update project metadata to make jest work
null8626 Feb 17, 2026
52968df
feat: add integration.create and integration.delete support
null8626 Feb 17, 2026
6635d9a
feat: more consistent naming
null8626 Feb 17, 2026
0c9b1b0
doc: update webhook documentation
null8626 Feb 18, 2026
c79e357
feat: remove deprecated webhook via middleware method
null8626 Feb 18, 2026
c8990db
fix: remove overridden 204 response in webhooks
null8626 Feb 18, 2026
8eb621b
feat: add two more missing properties to Vote
null8626 Feb 18, 2026
6e71450
feat: rename avatarURL to avatar for consistency
null8626 Feb 18, 2026
9975bcb
doc: add missing documentation for WebhookPayload
null8626 Feb 19, 2026
8dffd4c
feat: add getVotes
null8626 Feb 20, 2026
b6de1e5
fix: return 403 instead of 401 in case of invalid signature
null8626 Feb 20, 2026
8c791c6
doc: fix NameError in documentation examples
null8626 Feb 20, 2026
37e6f0e
doc: log payload directly
null8626 Feb 20, 2026
3c956d6
doc: use an, not a
null8626 Feb 24, 2026
497ae27
refactor: more accurate HTTP response status codes
null8626 Feb 25, 2026
a0e1ca7
doc: grammatical fixes
null8626 Feb 25, 2026
f1ad1cf
fix: add missing semicolons
null8626 Feb 25, 2026
fd27514
refactor: remove token validation
null8626 Mar 3, 2026
2128574
feat: rename created_at to voted_at
null8626 Mar 4, 2026
3d350bf
feat: rename userId to voterId for clarity
null8626 Mar 5, 2026
c7c2b92
doc: remove unclear untested examples
null8626 Mar 7, 2026
61c906d
refactor: make Vote extend PartialVote
null8626 Mar 9, 2026
e5ef76a
doc: Clarify next method description in PaginatedVotes
null8626 Mar 9, 2026
2a66cda
doc: minor docstring tweaks for widgets
null8626 Mar 10, 2026
250e5a7
meta: update package description for clarity
null8626 Mar 10, 2026
ff8539d
doc: fix documentation link
null8626 Mar 10, 2026
5ffb9f2
fix: fallback to warn + 204 instead of returning 422
null8626 Mar 10, 2026
e03dd80
doc: tweak examples
null8626 Mar 10, 2026
f0a569d
meta: refer to itself as an SDK, not a library
null8626 Mar 10, 2026
3ba3964
feat: improve widgets, rename Type to ProjectType
null8626 Mar 10, 2026
7825b74
[fix,style]: enforce body limits in webhooks, prettier
null8626 Mar 10, 2026
c115642
doc: update widget example ID
null8626 Mar 11, 2026
fb2b3e5
feat: migrate to built-in fetch()
null8626 Mar 16, 2026
f5fdf84
feat: add more error tips
null8626 Mar 16, 2026
426db7a
refactor: remove requireAuth from tests
null8626 Mar 16, 2026
60f070a
ci: test with node 21, 22, 24, and 25
null8626 Mar 16, 2026
001bd30
meta: make pre-commit script also run tests
null8626 Mar 17, 2026
06434ec
[feat,meta]: properly adapt SDK to use native fetch(), use jestless c…
null8626 Mar 17, 2026
b54caac
[deps,meta]: bump dependencies and make SDK ESM
null8626 Mar 17, 2026
71efc12
refactor: rewrite tests in node tests
null8626 Mar 17, 2026
442e9f8
fix: fix linting not working
null8626 Mar 17, 2026
2a5fe75
style: prettier [skip ci]
null8626 Mar 17, 2026
1076f77
refactor: remove redundant url search params addition
null8626 Mar 17, 2026
e4a013c
doc: change example to use secret instead of password [skip ci]
null8626 Mar 17, 2026
2a0e5a5
ci: get rid of mentions of Jest in the test CI
null8626 Mar 17, 2026
13b6e1a
meta: use nodenext module resolution
null8626 Mar 17, 2026
1a49f73
[feat,fix]: add webhook tests, add timeout handling, fix lots of bugs
null8626 Mar 17, 2026
bfe2d6f
refactor: explicitly use type imports
null8626 Mar 17, 2026
61bc8cc
refactor: use as any instead of an as unknown intermediate
null8626 Mar 17, 2026
8dec8bd
style: reorder imports [skip ci]
null8626 Mar 17, 2026
a4990fa
ci: compile ts on pre-commit instead of running unit tests
null8626 Mar 17, 2026
40daeb8
Merge branch 'split/deps'
null8626 Mar 17, 2026
c7e3f7c
revert: revert changes done to .nvmrc
null8626 Mar 17, 2026
f7ba2a0
ci: make the publish CI use node 21 instead of 20
null8626 Mar 17, 2026
e0972c2
fix: explicitly specify test path
null8626 Mar 17, 2026
c339356
doc: change 404 tip, better clarify the reasoning behind getVote() re…
null8626 Mar 17, 2026
4e42437
doc: minor grammatical fix
null8626 Mar 17, 2026
000334d
fix: return 408 in case of timeout
null8626 Mar 17, 2026
8c50621
feat: increase default timeout to 5 seconds
null8626 Mar 17, 2026
404a064
doc: simplify docs
null8626 Mar 18, 2026
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
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build library
name: Build SDK

on:
push:
Expand All @@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20]
node: [21, 22, 24, 25]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Cache node_modules
uses: actions/cache@v3
uses: actions/cache@v5
env:
cache-name: cache-node-modules
with:
Expand All @@ -26,7 +26,7 @@ jobs:
${{ runner.os }}-build-
${{ runner.os }}-
- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
check-latest: true
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 18
node-version: 21
check-latest: true
registry-url: https://registry.npmjs.org/
- run: npm publish --access public
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Jest Tests
name: Run tests

on:
push:
Expand All @@ -10,14 +10,14 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Use Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v6
with:
node-version: 18
node-version: 21
check-latest: true
registry-url: https://registry.npmjs.org/
- name: Install Dependencies
run: npm install
- name: Run Jest tests
run: npm run test
- name: Run tests
run: npm test
5 changes: 1 addition & 4 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint
npm run lint && npx tsc
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.18.2
18.18.2
183 changes: 148 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,175 @@
# Top.gg Node SDK
# Top.gg Node.js SDK

An official module for interacting with the Top.<span>gg API
> For more information, see the documentation here: <https://topgg.js.org>.

# Installation
The community-maintained Node.js SDK for Top.gg.

`yarn add @top-gg/sdk` or `npm i @top-gg/sdk`
## Chapters

# Introduction
- [Installation](#installation)
- [Setting up](#setting-up)
- [Usage](#usage)
- [Getting your project's information](#getting-your-projects-information)
- [Getting your project's vote information of a user](#getting-your-projects-vote-information-of-a-user)
- [Getting a cursor-based paginated list of votes for your project](#getting-a-cursor-based-paginated-list-of-votes-for-your-project)
- [Posting your bot's application commands list](#posting-your-bots-application-commands-list)
- [Generating widget URLs](#generating-widget-urls)
- [Webhooks](#webhooks)

The base client is Topgg.Api, and it takes your Top.gg token and provides you with plenty of methods to interact with the API.
## Installation

See [this tutorial](https://github.com/top-gg/rust-sdk/assets/60427892/d2df5bd3-bc48-464c-b878-a04121727bff) on how to retrieve your API token.

You can also setup webhooks via Topgg.Webhook, look down below at the examples for how to do so!
### NPM

# Links
```sh
$ npm i @top-gg/sdk
```

### Yarn

```sh
$ yarn add @top-gg/sdk
```

## Setting up

```js
import Topgg from "@top-gg/sdk";

const client = new Topgg.Api(process.env.TOPGG_TOKEN);
```

## Usage

### Getting your project's information

```js
const project = await client.getSelf();

console.log(project);
// =>
// {
// id: '218109768489992192',
// name: 'Miki',
// type: 'bot',
// platform: 'discord',
// headline: 'A great bot with tons of features! language | admin | cards | fun | levels | roles | marriage | currency | custom commands!',
// tags: [
// 'anime',
// 'customizable-behavior',
// 'economy',
// 'fun',
// 'game',
// 'leveling',
// 'multifunctional',
// 'role-management',
// 'roleplay',
// 'social'
// ],
// votes: { current: 1120, total: 313389 },
// review: { score: 4.38, count: 62245 }
// }
```

### Getting your project's vote information of a user

#### Discord ID

```js
const vote = await client.getVote("661200758510977084");
```

#### Top.gg ID

```js
const vote = await client.getVote("8226924471638491136", "topgg");
```

### Getting a cursor-based paginated list of votes for your project

[Documentation](https://topgg.js.org)
```js
const since = new Date("2026-01-01");

[API Reference](https://docs.top.gg) | [GitHub](https://github.com/top-gg/node-sdk) | [NPM](https://npmjs.com/package/@top-gg/sdk) | [Discord Server](https://discord.gg/EYHTgJX)
const firstPage = await client.getVotes(since);
console.log(firstPage.votes);

# Popular Examples
const secondPage = await firstPage.next();
console.log(secondPage.votes);
```

## Auto-Posting stats
### Posting your bot's application commands list

If you're looking for an easy way to post your bot's stats (server count, shard count), check out [`topgg-autoposter`](https://npmjs.com/package/topgg-autoposter)
#### Discord.js

```js
const client = Discord.Client(); // Your discord.js client or any other
const { AutoPoster } = require("topgg-autoposter");
const commands = (await bot.application.commands.fetch()).map(command => command.toJSON());

AutoPoster("topgg-token", client).on("posted", () => {
console.log("Posted stats to Top.gg!");
});
await client.postCommands(commands);
```

With this your server count and shard count will be posted to Top.<span>gg
#### Raw

```js
// Array of application commands that
// can be serialized to Discord API's raw JSON format.
await client.postCommands([
{
options: [],
name: 'test',
name_localizations: null,
description: 'command description',
description_localizations: null,
contexts: [],
default_permission: null,
default_member_permissions: null,
dm_permission: false,
integration_types: [],
nsfw: false
}
]);
```

### Generating widget URLs

#### Large

```js
const widgetUrl = Topgg.Widget.large("discord", "bot", "1026525568344264724");
```

## Webhook server
#### Votes

```js
const express = require("express");
const Topgg = require("@top-gg/sdk");
const widgetUrl = Topgg.Widget.votes("discord", "bot", "1026525568344264724");
```

const app = express(); // Your express app
#### Owner

const webhook = new Topgg.Webhook("topggauth123"); // add your Top.gg webhook authorization (not bot token)
```js
const widgetUrl = Topgg.Widget.owner("discord", "bot", "1026525568344264724");
```

app.post(
"/dblwebhook",
webhook.listener((vote) => {
// vote is your vote object
console.log(vote.user); // 221221226561929217
})
); // attach the middleware
#### Social

app.listen(3000); // your port
```js
const widgetUrl = Topgg.Widget.social("discord", "bot", "1026525568344264724");
```

With this example, your webhook dashboard (`https://top.gg/bot/{your bot's id}/webhooks`) should look like this:
![](https://i.imgur.com/cZfZgK5.png)
### Webhooks

With express:

```js
import { Webhook } from "@top-gg/sdk";
import express from "express";

const app = express();
const webhook = new Webhook(process.env.TOPGG_WEBHOOK_SECRET);

// POST /webhook
app.post("/webhook", webhook.listener((payload) => {
console.log(payload);
}));

app.listen(8080);
```
24 changes: 11 additions & 13 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
const js = require('@eslint/js');
const ts = require("@typescript-eslint/eslint-plugin");
import tsPlugin from "@typescript-eslint/eslint-plugin";
import ts from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
import js from "@eslint/js";

const tsPlugin = require('@typescript-eslint/eslint-plugin');
const jestPlugin = require('eslint-plugin-jest');

module.exports = [
export default [
{
ignores: ["node_modules/*", "docs/*", "dist/*"]
},
{
...js.configs.recommended,
files: ["src/**/*.ts"],
languageOptions: {
parser: require('@typescript-eslint/parser'),
parser: tsParser,
parserOptions: {
project: './tsconfig.json',
projectService: true
},
globals: {
es6: true,
browser: true,
node: true,
jest: true
}
node: true
},
sourceType: "module"
},
plugins: {
"@typescript-eslint": tsPlugin,
jest: jestPlugin
"@typescript-eslint": tsPlugin
},
rules: {
...ts.configs.recommended.rules,
Expand Down
6 changes: 0 additions & 6 deletions jest.config.js

This file was deleted.

Loading