@merkl/api 0.10.313 → 0.10.315
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/dist/src/backgroundJobs/index.js +4 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.d.ts +34 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.js +8 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.d.ts +0 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.js +1 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.d.ts +5 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.js +72 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.d.ts +3 -0
- package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.js +15 -0
- package/dist/src/modules/v4/dungeonKeeper/index.d.ts +2 -0
- package/dist/src/modules/v4/dungeonKeeper/index.js +2 -0
- package/dist/src/modules/v4/status/status.model.js +5 -3
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -1,4 +1,5 @@
|
|
1
1
|
import { redisClient } from "../cache/redis";
|
2
|
+
import { DungeonKeeperController } from "../modules/v4/dungeonKeeper";
|
2
3
|
import { log } from "../utils/logger";
|
3
4
|
import { engineDbClient } from "../utils/prisma";
|
4
5
|
import { swagger } from "@elysiajs/swagger";
|
@@ -20,6 +21,9 @@ new Elysia()
|
|
20
21
|
.use(priceUpdater) // /v3/updatePrices
|
21
22
|
.use(healthCheck) // /v3/health
|
22
23
|
.use(sync) // GET /jobs/api/sync-with-engine
|
24
|
+
.group("/v4", app => {
|
25
|
+
return app.use(DungeonKeeperController);
|
26
|
+
})
|
23
27
|
.onError(ctx => {
|
24
28
|
console.error(ctx.error.message);
|
25
29
|
console.error(ctx.error.stack);
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import Elysia from "elysia";
|
2
|
+
export declare const DungeonKeeperController: Elysia<"/dungeonkeeper", false, {
|
3
|
+
decorator: {};
|
4
|
+
store: {};
|
5
|
+
derive: {};
|
6
|
+
resolve: {};
|
7
|
+
}, {
|
8
|
+
type: {};
|
9
|
+
error: {};
|
10
|
+
}, {
|
11
|
+
schema: {};
|
12
|
+
macro: {};
|
13
|
+
macroFn: {};
|
14
|
+
}, {
|
15
|
+
dungeonkeeper: {
|
16
|
+
get: {
|
17
|
+
body: unknown;
|
18
|
+
params: {};
|
19
|
+
query: unknown;
|
20
|
+
headers: unknown;
|
21
|
+
response: {
|
22
|
+
200: void;
|
23
|
+
};
|
24
|
+
};
|
25
|
+
};
|
26
|
+
}, {
|
27
|
+
derive: {};
|
28
|
+
resolve: {};
|
29
|
+
schema: {};
|
30
|
+
}, {
|
31
|
+
derive: {};
|
32
|
+
resolve: {};
|
33
|
+
schema: {};
|
34
|
+
}>;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import Elysia from "elysia";
|
2
|
+
import { DungeonKeeperService } from ".";
|
3
|
+
// ─── DungeonKeeper Controller ──────────────────────────────────────────────────
|
4
|
+
export const DungeonKeeperController = new Elysia({ prefix: "/dungeonkeeper", detail: { hide: true } })
|
5
|
+
// ─── Assign the daily DungeonKeeper ──────────────────────────────────────────
|
6
|
+
.get("", async () => await DungeonKeeperService.create(), {
|
7
|
+
detail: { hide: true },
|
8
|
+
});
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import type { PartialDatabaseObjectResponse } from "@notionhq/client/build/src/api-endpoints";
|
2
|
+
export declare abstract class DungeonKeeperRepository {
|
3
|
+
static fetchEntriesForDateWithTag(databaseId: string, date: string, tag: string): Promise<PartialDatabaseObjectResponse[]>;
|
4
|
+
static assignRole(notionId: string): Promise<void>;
|
5
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import { Client } from "@notionhq/client";
|
2
|
+
import { Client as DiscordClient, GatewayIntentBits } from "discord.js";
|
3
|
+
const notion = new Client({ auth: process.env.NOTION_TOKEN });
|
4
|
+
const discord = new DiscordClient({ intents: [GatewayIntentBits.GuildMembers] });
|
5
|
+
const NOTION_EMAIL_TO_DISCORD_ID = {
|
6
|
+
picodes: "thepicodes",
|
7
|
+
hugo: "ugolxt",
|
8
|
+
alex: "wombomango",
|
9
|
+
nileco: ".nileco",
|
10
|
+
thibaudb: ".greedythib",
|
11
|
+
gnervo: "gs8nrv",
|
12
|
+
vincent: "vince_merkl",
|
13
|
+
hicham: "lamicham_93854",
|
14
|
+
pveyrat: "sogipec",
|
15
|
+
baptiste: "baptistg",
|
16
|
+
clement: "clmntngl",
|
17
|
+
};
|
18
|
+
export class DungeonKeeperRepository {
|
19
|
+
static async fetchEntriesForDateWithTag(databaseId, date, tag) {
|
20
|
+
const response = await notion.databases.query({
|
21
|
+
database_id: databaseId,
|
22
|
+
filter: {
|
23
|
+
and: [
|
24
|
+
{
|
25
|
+
property: "Date",
|
26
|
+
date: {
|
27
|
+
equals: date,
|
28
|
+
},
|
29
|
+
},
|
30
|
+
{
|
31
|
+
property: "Database",
|
32
|
+
select: {
|
33
|
+
equals: tag,
|
34
|
+
},
|
35
|
+
},
|
36
|
+
],
|
37
|
+
},
|
38
|
+
});
|
39
|
+
return response.results;
|
40
|
+
}
|
41
|
+
static async assignRole(notionId) {
|
42
|
+
const discordId = NOTION_EMAIL_TO_DISCORD_ID[notionId];
|
43
|
+
if (!discordId)
|
44
|
+
throw "Discord ID not found.";
|
45
|
+
await discord.login(process.env.DISCORD_TOKEN);
|
46
|
+
const guild = await discord.guilds.cache.get("862708408711643136");
|
47
|
+
if (!guild)
|
48
|
+
throw "Guild not found.";
|
49
|
+
const roles = await guild.roles.fetch();
|
50
|
+
const teamRole = roles.find(r => r.name === "Team");
|
51
|
+
const dkRole = roles.find(r => r.name === "Dungeon Keeper");
|
52
|
+
if (!teamRole || !dkRole)
|
53
|
+
throw "Roles not found.";
|
54
|
+
const users = await guild.members.fetch();
|
55
|
+
for (const [_id, dkUser] of users.filter(member => member.roles.cache.has(dkRole.id))) {
|
56
|
+
console.log(dkUser.user.tag);
|
57
|
+
await dkUser.roles.remove(dkRole);
|
58
|
+
}
|
59
|
+
const user = users
|
60
|
+
.filter(member => member.roles.cache.has(teamRole.id))
|
61
|
+
.find(member => member.user.tag === discordId);
|
62
|
+
if (!user)
|
63
|
+
throw "User not found";
|
64
|
+
await user.roles.add(dkRole);
|
65
|
+
const channel = await discord.channels.fetch("1328383110957633630");
|
66
|
+
if (!channel)
|
67
|
+
throw "Channel not found";
|
68
|
+
if (channel.isSendable()) {
|
69
|
+
await channel.send(`Lucky you <@${user.id}>! You're the <@&${dkRole.id}> today!`);
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import moment from "moment";
|
2
|
+
import { DungeonKeeperRepository } from "./dungeonKeeper.repository";
|
3
|
+
export class DungeonKeeperService {
|
4
|
+
static async create() {
|
5
|
+
const entries = await DungeonKeeperRepository.fetchEntriesForDateWithTag("8546f6a84641406bafb2358762281e81", moment().format("YYYY-MM-DD"), "Dungeon Keeper");
|
6
|
+
const user = entries?.[0];
|
7
|
+
if (!user) {
|
8
|
+
throw "No dk found for today";
|
9
|
+
}
|
10
|
+
const notionId = (user?.properties["Qui ?"]).people[0].person.email
|
11
|
+
.replace("@angle.money", "")
|
12
|
+
.replace("@merkl.xyz", "");
|
13
|
+
await DungeonKeeperRepository.assignRole(notionId);
|
14
|
+
}
|
15
|
+
}
|
@@ -6,9 +6,11 @@ export const CampaignUniqueDto = t.Object({
|
|
6
6
|
campaignId: t.String(),
|
7
7
|
});
|
8
8
|
export const DelayDto = t.Object({
|
9
|
-
endTimestampLowerBound: t.Optional(t.Numeric(
|
10
|
-
|
11
|
-
|
9
|
+
endTimestampLowerBound: t.Optional(t.Numeric({
|
10
|
+
description: "Lower bound of end timestamps - by default it'll take all campaigns where endTimestamp is more than now - 1 week",
|
11
|
+
})),
|
12
|
+
delayLowerBound: t.Optional(t.Numeric({ description: "To filter small delays (in seconds)" })),
|
13
|
+
chainId: t.Optional(t.Numeric({ description: "To get delays for Campaigns on a given chain only" })),
|
12
14
|
});
|
13
15
|
export const CampaignStatusResourceDto = t.Object({
|
14
16
|
campaignId: t.String(),
|