@hokkiai/djs-level-importer 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,11 @@
1
- # `djs-level-importer`
2
-
3
- An open, JavaScript-based library to import leveling data from MEE6 and other bots.
4
- Made jointly by the [Sokora](https://sokora.org) and [Hokki](https://www.hokki.app) Discord bots.
1
+ <div align="center">
2
+ <br><h1>Discord Level Importer</h1>
3
+ <br>An open, JavaScript-based library for importing leveling data from MEE6 and other bots.<br>
4
+ <br><br><a href="https://www.hokki.app"><img height="100" src="https://raw.githubusercontent.com/hokkiai/djs-level-importer/refs/heads/master/assets/sokoraXhokki.png?raw=true"></a>
5
+ <br>Made jointly by the <a href="https://sokora.org">Sokora</a> and <a href="https://www.hokki.app">Hokki</a> Discord bots.
6
+ </div>
7
+ <br>
8
+ <br>
5
9
 
6
10
  ## Usage
7
11
 
@@ -60,15 +64,16 @@ This interface division is not the most intuitive, but the best thing we can do
60
64
 
61
65
  ## Bot support
62
66
 
63
- As of now, MEE6, Lurkr, and Tatsu are supported. Most bots don't document their APIs and it's therefore difficult to add new bots, so no guarantees are made; however we do try to add new bots to this library.
67
+ As of now, MEE6, Lurkr, Tatsu and Amari are supported. Most bots don't document their APIs and it's therefore difficult to add new bots, so no guarantees are made; however we do try to add new bots to this library. You can check `TODO.txt` at the root of this repo for a list of planned (or discarded) bots, and you may suggest any bot you know about that isn't listed there by opening an issue.
64
68
 
65
- **Bots are selected using integers** when calling `GetLeaderboard`. You can check int-bot associations by looking at the exported `SupportedBots` enum. Or just look at it here:
69
+ **Bots are selected using integers** when calling `GetLeaderboard`. You can check integer-bot associations by looking at the exported `SupportedBots` TypeScript enum. Or just look at it here:
66
70
 
67
71
  ```ts
68
72
  export enum SupportedBots {
69
73
  MEE6 = 0,
70
74
  TATSU = 1,
71
75
  LURKR = 2,
76
+ AMARI = 3,
72
77
  }
73
78
  ```
74
79
 
@@ -104,6 +109,16 @@ Lastly, you need to manually change `Choose the visibility for the web leaderboa
104
109
 
105
110
  Nothing is required. -->
106
111
 
112
+ #### Amari
113
+
114
+ You need an API key, obtained by manually requesting it from Amari's Discord server at [this link](https://amaribot.com/support) and passed to the constructor via the `amari_api` parameter.
115
+
116
+ ```ts
117
+ new Leveler({ guild: "...", amari_api: "123ABC..." });
118
+ ```
119
+
120
+ > It's worth noting we tried to get it ourselves to test and were told that they're currently not issuing API keys as they're redoing the system or something like that.
121
+
107
122
  ## Credits and license
108
123
 
109
124
  Originally made by [ZakaHaceCosas](https://zakahacecosas.github.io/) for the [Hokki](https://www.hokki.app) and [Sokora](https://sokora.org) Discord bots. Made open source under the MIT license for everyone to use, so long as our work is attributed (which'd make us really happy as reverse engineering some APIs was a true pain, to be fair).
@@ -0,0 +1,56 @@
1
+ /** Lurkr API docs have a "copy TypeScript definitions" for this */
2
+ export interface LURKRResponse {
3
+ guild: {
4
+ icon: string | null;
5
+ id: string;
6
+ memberCount: number;
7
+ name: string;
8
+ };
9
+ isManager: boolean;
10
+ levels: {
11
+ level: number;
12
+ messageCount: number;
13
+ nextLevelXp: number;
14
+ progress: number;
15
+ rank: number;
16
+ user: {
17
+ accentColour: string | null;
18
+ } & any;
19
+ userId: string;
20
+ xp: number;
21
+ }[];
22
+ multipliers: {
23
+ id: string;
24
+ multiplier: number;
25
+ targets: any[];
26
+ type: "Channel" | "Role";
27
+ }[];
28
+ roleRewards: {
29
+ id: string;
30
+ level: number;
31
+ roles: any[];
32
+ }[];
33
+ vanity: string | null;
34
+ /**
35
+ * The cooldown period for XP gain in seconds
36
+ */
37
+ xpGainInterval: number;
38
+ xpGlobalMultiplier: number;
39
+ /**
40
+ * Maximum XP to gain per message
41
+ */
42
+ xpPerMessageMax: number;
43
+ /**
44
+ * Minimum XP to gain per message
45
+ */
46
+ xpPerMessageMin: number;
47
+ }
48
+ /**
49
+ * Get the leaderboard of a guild.
50
+ *
51
+ * @async
52
+ * @param {(string | null)} tkn API token for Lurkr.
53
+ * @param {string} guildId Guild to get the leaderboard from.
54
+ * @returns {Promise<LURKRResponse["levels"]>} Leaderboard of the guild.
55
+ */
56
+ export declare function LURKRGetLeaderboard(tkn: string | null, guildId: string): Promise<LURKRResponse["levels"]>;
package/dist/lurkr.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Get the leaderboard of a guild.
3
+ *
4
+ * @async
5
+ * @param {(string | null)} tkn API token for Lurkr.
6
+ * @param {string} guildId Guild to get the leaderboard from.
7
+ * @returns {Promise<LURKRResponse["levels"]>} Leaderboard of the guild.
8
+ */
9
+ export async function LURKRGetLeaderboard(tkn, guildId) {
10
+ if (!tkn)
11
+ throw "No Lurkr API key provided. Cannot use Lurkr API.";
12
+ const leaderboard = [];
13
+ let pageNumber = 1;
14
+ while (true) {
15
+ const page = await fetch(`https://api.lurkr.gg/v2/levels/${guildId}?page=${pageNumber}`, {
16
+ method: "GET",
17
+ });
18
+ const content = (await page.json());
19
+ if (!page.ok)
20
+ throw `Failed to import from Lurkr: ${content.message}`;
21
+ leaderboard.push(...content.levels);
22
+ if (content.levels.length < 1000)
23
+ break;
24
+ pageNumber += 1;
25
+ }
26
+ return leaderboard;
27
+ }
package/dist/main.d.ts CHANGED
@@ -26,8 +26,13 @@ export interface BaseUserLevels {
26
26
  * @interface FullUserLevels
27
27
  */
28
28
  export interface FullUserLevels extends BaseUserLevels {
29
- /** Current XP **relative to the level**. */
30
- current_lvl_xp: number;
29
+ /** Current XP **relative to the level**.
30
+ *
31
+ * Not all APIs return this, therefore it's optional.
32
+ *
33
+ * @deprecated Should've thought about this when initially designing the API. Next major release will probably just remove this property entirely, as it's not that useful anyway. Try not to depend on it.
34
+ */
35
+ current_lvl_xp?: number;
31
36
  /** Current level. */
32
37
  lvl: number;
33
38
  /** XP required to level up. */
@@ -40,30 +45,33 @@ export declare function SUPPORTS_LEVELS(a: any): a is FullUserLevels;
40
45
  *
41
46
  * ```ts
42
47
  * MEE6 = 0,
43
- * TATSU = 1
48
+ * TATSU = 1,
49
+ * LURKR = 2,
44
50
  * ```
45
51
  * @enum {number}
46
52
  */
47
53
  export declare enum SupportedBots {
48
54
  MEE6 = 0,
49
- TATSU = 1
55
+ TATSU = 1,
56
+ LURKR = 2
50
57
  }
51
58
  export declare class Leveler {
52
59
  private guild;
53
60
  private tatsu_api;
61
+ private lurkr_api;
54
62
  /**
55
63
  * Creates an instance of a Leveler, with which you'll be able to import leveling data from supported bots.
56
64
  *
57
65
  * @constructor
58
66
  * @param {string} guild Guild ID.
59
67
  * @param {?string} tatsu_api If importing from Tatsu, you need to bring in your own API key. This is free and pretty easy to get from the Tatsu bot itself.
68
+ * @param {?string} lurkr_api If importing from Tatsu, you need to bring in your own API key. This is free and pretty easy to get from the Tatsu bot itself.
60
69
  */
61
70
  constructor(options: {
62
71
  guild: string;
63
72
  tatsu_api?: string;
73
+ lurkr_api?: string;
64
74
  });
65
- /** Gets the whole server leaderboard from MEE6. Throws if unable to get it. */
66
- GetLeaderboard(target: SupportedBots.MEE6): Promise<FullUserLevels[]>;
67
- /** Gets the whole server leaderboard from Tatsu. Throws if unable to get it. */
68
- GetLeaderboard(target: SupportedBots.TATSU): Promise<BaseUserLevels[]>;
75
+ /** Gets the whole server leaderboard from a supported bot. Throws if unable to get it. */
76
+ GetLeaderboard(target: SupportedBots): Promise<BaseUserLevels[] | FullUserLevels[]>;
69
77
  }
package/dist/main.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { LURKRGetLeaderboard } from "./lurkr.js";
1
2
  import { MEE6GetLeaderboard } from "./mee6.js";
2
3
  import { TATSUGetLeaderboard } from "./tatsu.js";
3
4
  /**
@@ -23,7 +24,8 @@ export function SUPPORTS_LEVELS(a) {
23
24
  *
24
25
  * ```ts
25
26
  * MEE6 = 0,
26
- * TATSU = 1
27
+ * TATSU = 1,
28
+ * LURKR = 2,
27
29
  * ```
28
30
  * @enum {number}
29
31
  */
@@ -31,26 +33,32 @@ export var SupportedBots;
31
33
  (function (SupportedBots) {
32
34
  SupportedBots[SupportedBots["MEE6"] = 0] = "MEE6";
33
35
  SupportedBots[SupportedBots["TATSU"] = 1] = "TATSU";
36
+ SupportedBots[SupportedBots["LURKR"] = 2] = "LURKR";
34
37
  })(SupportedBots || (SupportedBots = {}));
35
38
  export class Leveler {
36
39
  guild;
37
40
  tatsu_api = null;
41
+ lurkr_api = null;
38
42
  /**
39
43
  * Creates an instance of a Leveler, with which you'll be able to import leveling data from supported bots.
40
44
  *
41
45
  * @constructor
42
46
  * @param {string} guild Guild ID.
43
47
  * @param {?string} tatsu_api If importing from Tatsu, you need to bring in your own API key. This is free and pretty easy to get from the Tatsu bot itself.
48
+ * @param {?string} lurkr_api If importing from Tatsu, you need to bring in your own API key. This is free and pretty easy to get from the Tatsu bot itself.
44
49
  */
45
50
  constructor(options) {
46
51
  this.guild = options.guild;
47
52
  if (options.tatsu_api)
48
53
  this.tatsu_api = options.tatsu_api;
54
+ if (options.lurkr_api)
55
+ this.lurkr_api = options.lurkr_api;
49
56
  }
57
+ /** Gets the whole server leaderboard from a supported bot. Throws if unable to get it. */
50
58
  async GetLeaderboard(target) {
51
59
  if (target === SupportedBots.MEE6) {
52
60
  const levels = await MEE6GetLeaderboard(this.guild);
53
- return levels.map(u => {
61
+ return levels.map((u) => {
54
62
  return {
55
63
  uid: u.id,
56
64
  lvl: u.level,
@@ -60,12 +68,23 @@ export class Leveler {
60
68
  };
61
69
  });
62
70
  }
71
+ else if (target === SupportedBots.LURKR) {
72
+ const levels = await LURKRGetLeaderboard(this.lurkr_api, this.guild);
73
+ return levels.map((u) => {
74
+ return {
75
+ uid: u.userId,
76
+ lvl: u.level,
77
+ current_xp: u.xp,
78
+ next_lvl_xp: u.nextLevelXp,
79
+ };
80
+ });
81
+ }
63
82
  else {
64
83
  const levels = await TATSUGetLeaderboard(this.tatsu_api, this.guild);
65
- return levels.rankings.map(r => {
84
+ return levels.rankings.map((u) => {
66
85
  return {
67
- uid: r.user_id,
68
- current_xp: r.score,
86
+ uid: u.user_id,
87
+ current_xp: u.score,
69
88
  };
70
89
  });
71
90
  }
package/dist/tatsu.js CHANGED
@@ -10,7 +10,7 @@ import { Tatsu } from "tatsu";
10
10
  */
11
11
  export async function TATSUGetLeaderboard(tkn, guildId) {
12
12
  if (!tkn)
13
- throw `No Tatsu API key provided. Cannot use Tatsu API.`;
13
+ throw "No Tatsu API key provided. Cannot use Tatsu API.";
14
14
  const tatsu = new Tatsu(tkn);
15
15
  return await tatsu.getGuildRankings(guildId);
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hokkiai/djs-level-importer",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "An open, JavaScript-based library to import leveling data from MEE6 and other bots. Made jointly by the Sokora and Hokki Discord bots.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/hokkiai/djs-level-importer",