-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbasic.ts
110 lines (91 loc) · 3.12 KB
/
basic.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
require("dotenv").config();
import * as Redis from "redis";
import * as Rx from "rxjs";
import * as RxO from "rxjs/operators";
import { createClient, Intents } from "droff";
import { Guild, Role, Channel } from "droff/types";
import { createStores } from "../src/mod";
// some constants
const second = 1000;
const minute = 60 * second;
// Redis client
const redisClient = Redis.createClient();
redisClient.connect();
// Create the redis store factories
const redis = createStores({ client: redisClient });
const caches = {
guilds: () => redis.nonParentCache<Guild>("guilds"),
roles: () => redis.cacheWithTTL<Role>("roles", 10 * minute),
channels: () => redis.cacheWithTTL<Channel>("channels", 10 * minute),
};
// Parent client
const sourceClient = createClient({
token: process.env.DISCORD_BOT_TOKEN!,
// Use the redis backed rate limit store
rateLimitStore: redis.rateLimit(),
gateway: {
intents: Intents.GUILD_MESSAGES,
shardConfig: { count: 5 },
// Set the sharder store, for horizontal scaling shard processes
// It takes a deployment name and a node id.
sharderStore: redis.sharder("test-deploy", `${Date.now()}`),
},
});
// Push the gateway events to redis
const push$ = redis.pushPayloads(sourceClient);
// Cache some resources in redis
const [, guildsCache$] = sourceClient.guildsCache(caches.guilds());
const [, rolesCache$] = sourceClient.rolesCache(caches.roles());
const [, channelsCache$] = sourceClient.channelsCache(caches.channels());
// Start the source client
Rx.merge(
sourceClient.effects$,
push$,
guildsCache$,
rolesCache$,
channelsCache$,
).subscribe();
// === Child clients
// Setup the child client
const childClient = createClient({
token: process.env.DISCORD_BOT_TOKEN!,
rateLimitStore: redis.rateLimit(),
gateway: {
// Pull the payloads from redis here
payloads$: redis.pullPayloads(),
},
});
// Use a shared cache
// We dont need the cache effects$ observable, as we don't perform any syncing
// in the child clients.
const [rolesCache] = childClient.rolesCache(caches.roles());
const roles$ = childClient.fromDispatch("MESSAGE_CREATE").pipe(
RxO.filter((msg) => msg.author.bot !== true),
RxO.filter((msg) => msg.content === "!roles"),
childClient.withCaches({
roles: rolesCache.getForParent,
})((msg) => msg.guild_id),
childClient.onlyWithCacheResults(),
RxO.flatMap(([msg, { roles }]) =>
childClient.createMessage(msg.channel_id, {
message_reference: { message_id: msg.id },
content: JSON.stringify(Array.from(roles.values()), null, 2),
}),
),
);
const roleCount$ = childClient.fromDispatch("MESSAGE_CREATE").pipe(
RxO.filter((msg) => msg.author.bot !== true),
RxO.filter((msg) => msg.content === "!rolecount"),
childClient.withCaches({
roleCount: rolesCache.sizeForParent,
})((msg) => msg.guild_id),
childClient.onlyWithCacheResults(),
RxO.flatMap(([msg, { roleCount }]) =>
childClient.createMessage(msg.channel_id, {
message_reference: { message_id: msg.id },
content: `There are ${roleCount} roles in the cache`,
}),
),
);
// Subscribe
Rx.merge(childClient.effects$, roles$, roleCount$).subscribe();