mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
Threads Members Update (#46)
* PresenceUpdate * Thread Members Events * fix: fmt * fix: all fmt
This commit is contained in:
parent
f5e3eaaafc
commit
107374725b
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
16
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -7,21 +7,17 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
**Describe the bug** A clear and concise description of what the bug is.
|
||||
|
||||
**Biscuit Version**
|
||||
eg: 0.1.0-rc7
|
||||
**Biscuit Version** eg: 0.1.0-rc7
|
||||
|
||||
**To Reproduce** Steps to reproduce the behavior:
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
**Expected behavior** A clear and concise description of what you expected to happen.
|
||||
|
||||
**etc**
|
||||
Whatever
|
||||
**etc** Whatever
|
||||
|
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -7,14 +7,12 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
**Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem
|
||||
is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
**Describe the solution you'd like** A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
**Describe alternatives you've considered** A clear and concise description of any alternative solutions or features
|
||||
you've considered.
|
||||
|
||||
**Limitations**
|
||||
A set of limitations of the API or the library by itself
|
||||
**Limitations** A set of limitations of the API or the library by itself
|
||||
|
55
README.md
55
README.md
@ -1,32 +1,38 @@
|
||||
# biscuit
|
||||
|
||||
## A brand new bleeding edge non bloated Discord library
|
||||
|
||||
|
||||
### Install (for [node18](https://nodejs.org/en/download/))
|
||||
|
||||
```sh-session
|
||||
npm install @oasisjs/biscuit
|
||||
pnpm add @oasisjs/biscuit
|
||||
yarn add @oasisjs/biscuit
|
||||
```
|
||||
|
||||
> or via [cdn](https://nest.land/package/biscuit)
|
||||
|
||||
The biscuit Discord library is built ontop of Discordeno and webspec APIs, we aim to provide portability.
|
||||
Join our [Discord](https://discord.gg/zmuvzzEFz2)
|
||||
The biscuit Discord library is built ontop of Discordeno and webspec APIs, we aim to provide portability. Join our
|
||||
[Discord](https://discord.gg/zmuvzzEFz2)
|
||||
|
||||
### Most importantly, biscuit is:
|
||||
* A modular [Discordeno](https://github.com/discordeno/discordeno) fork
|
||||
* A framework to build Discord bots
|
||||
* A bleeding edge API to contact Discord
|
||||
|
||||
Biscuit is primarly inspired by Discord.js and Discordeno but it does not include a cache layer by default, we believe that you should not make software that does things it is not supposed to do.
|
||||
- A modular [Discordeno](https://github.com/discordeno/discordeno) fork
|
||||
- A framework to build Discord bots
|
||||
- A bleeding edge API to contact Discord
|
||||
|
||||
Biscuit is primarly inspired by Discord.js and Discordeno but it does not include a cache layer by default, we believe
|
||||
that you should not make software that does things it is not supposed to do.
|
||||
|
||||
### Why biscuit?:
|
||||
* [Minimal](https://en.wikipedia.org/wiki/Unix_philosophy), non feature-rich!
|
||||
* Crossplatform
|
||||
* Consistent
|
||||
* Performant
|
||||
|
||||
- [Minimal](https://en.wikipedia.org/wiki/Unix_philosophy), non feature-rich!
|
||||
- Crossplatform
|
||||
- Consistent
|
||||
- Performant
|
||||
|
||||
### Example bot (TS/JS)
|
||||
|
||||
```js
|
||||
import { GatewayIntents, Session } from "biscuit";
|
||||
|
||||
@ -49,23 +55,28 @@ session.start();
|
||||
```
|
||||
|
||||
### Mininal style guide
|
||||
* 4 spaces, no tabs
|
||||
* Semi-colons are mandatory
|
||||
* Run `deno fmt`
|
||||
* Avoid circular dependencies
|
||||
|
||||
- 4 spaces, no tabs
|
||||
- Semi-colons are mandatory
|
||||
- Run `deno fmt`
|
||||
- Avoid circular dependencies
|
||||
|
||||
### Contrib guide
|
||||
* Install Deno extension [here](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno)
|
||||
* Run `deno check` to make sure the library works
|
||||
* Avoid sharing state between classes
|
||||
|
||||
- Install Deno extension [here](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno)
|
||||
- Run `deno check` to make sure the library works
|
||||
- Avoid sharing state between classes
|
||||
|
||||
### Compatibility
|
||||
|
||||
#### bun
|
||||
|
||||
since bun is unestable I highly recommend running biscuit on node!
|
||||
* We got the library running on EndeavourOS but it spams the ready event multiple times
|
||||
* We got the library running on Arch/Artix Linux but breaks when sending fetch requests
|
||||
* We got the library running on WSL
|
||||
|
||||
- We got the library running on EndeavourOS but it spams the ready event multiple times
|
||||
- We got the library running on Arch/Artix Linux but breaks when sending fetch requests
|
||||
- We got the library running on WSL
|
||||
|
||||
#### node
|
||||
* all DNT shims work properly
|
||||
|
||||
- all DNT shims work properly
|
||||
|
56
build.ts
56
build.ts
@ -1,67 +1,67 @@
|
||||
import { build } from 'https://deno.land/x/dnt@0.23.0/mod.ts';
|
||||
import { build } from "https://deno.land/x/dnt@0.23.0/mod.ts";
|
||||
|
||||
await Deno.remove('npm', { recursive: true }).catch((_) => {});
|
||||
await Deno.remove("npm", { recursive: true }).catch((_) => {});
|
||||
|
||||
await build({
|
||||
shims: {
|
||||
custom: [
|
||||
{
|
||||
package: {
|
||||
name: 'ws',
|
||||
version: '^8.4.0',
|
||||
name: "ws",
|
||||
version: "^8.4.0",
|
||||
},
|
||||
globalNames: [
|
||||
{
|
||||
name: 'WebSocket',
|
||||
exportName: 'default',
|
||||
name: "WebSocket",
|
||||
exportName: "default",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
package: {
|
||||
author: 'Yuzuru',
|
||||
name: '@oasisjs/biscuit',
|
||||
author: "Yuzuru",
|
||||
name: "@oasisjs/biscuit",
|
||||
version: Deno.args[0],
|
||||
description: 'the Biscuit library',
|
||||
license: 'Apache License 2.0',
|
||||
description: "the Biscuit library",
|
||||
license: "Apache License 2.0",
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'git+https://github.com/deno-biscuit/biscuit.git',
|
||||
type: "git",
|
||||
url: "git+https://github.com/deno-biscuit/biscuit.git",
|
||||
},
|
||||
bugs: {
|
||||
url: 'https://github.com/deno-biscuit/biscuit/issues',
|
||||
url: "https://github.com/deno-biscuit/biscuit/issues",
|
||||
},
|
||||
typesVersions: {
|
||||
'*': {
|
||||
'*': ['./types/mod.d.ts'],
|
||||
'biscuit': ['./types/packages/biscuit/mod.d.ts'],
|
||||
'discordeno': ['./types/packages/discordeno/mod.d.ts'],
|
||||
'cache': ['./types/packages/cache/mod.d.ts'],
|
||||
"*": {
|
||||
"*": ["./types/mod.d.ts"],
|
||||
"biscuit": ["./types/packages/biscuit/mod.d.ts"],
|
||||
"discordeno": ["./types/packages/discordeno/mod.d.ts"],
|
||||
"cache": ["./types/packages/cache/mod.d.ts"],
|
||||
},
|
||||
},
|
||||
},
|
||||
entryPoints: [
|
||||
'./mod.ts',
|
||||
"./mod.ts",
|
||||
{
|
||||
name: './biscuit',
|
||||
path: 'packages/biscuit/mod.ts',
|
||||
name: "./biscuit",
|
||||
path: "packages/biscuit/mod.ts",
|
||||
},
|
||||
{
|
||||
name: './discordeno',
|
||||
path: 'packages/discordeno/mod.ts',
|
||||
name: "./discordeno",
|
||||
path: "packages/discordeno/mod.ts",
|
||||
},
|
||||
{
|
||||
name: './cache',
|
||||
path: 'packages/cache/mod.ts',
|
||||
name: "./cache",
|
||||
path: "packages/cache/mod.ts",
|
||||
},
|
||||
],
|
||||
outDir: './npm',
|
||||
outDir: "./npm",
|
||||
declaration: true,
|
||||
typeCheck: false,
|
||||
test: false,
|
||||
});
|
||||
|
||||
// post build steps
|
||||
Deno.copyFileSync('LICENSE', 'npm/LICENSE');
|
||||
Deno.copyFileSync('README.md', 'npm/README.md');
|
||||
Deno.copyFileSync("LICENSE", "npm/LICENSE");
|
||||
Deno.copyFileSync("README.md", "npm/README.md");
|
||||
|
@ -31,9 +31,9 @@ import type {
|
||||
DiscordScheduledEvent,
|
||||
DiscordScheduledEventUserAdd,
|
||||
DiscordScheduledEventUserRemove,
|
||||
// DiscordThreadMemberUpdate,
|
||||
// DiscordThreadMembersUpdate,
|
||||
DiscordThreadListSync,
|
||||
DiscordThreadMembersUpdate,
|
||||
DiscordThreadMemberUpdate,
|
||||
DiscordTypingStart,
|
||||
DiscordUser,
|
||||
DiscordWebhookUpdate,
|
||||
@ -192,6 +192,28 @@ export const THREAD_DELETE: RawHandler<DiscordChannel> = (session, _shardId, cha
|
||||
session.emit("threadDelete", new ThreadChannel(session, channel, channel.guild_id));
|
||||
};
|
||||
|
||||
export const THREAD_MEMBER_UPDATE: RawHandler<DiscordThreadMemberUpdate> = (session, _shardId, payload) => {
|
||||
session.emit("threadMemberUpdate", {
|
||||
guildId: payload.guild_id,
|
||||
id: payload.id,
|
||||
userId: payload.user_id,
|
||||
joinedAt: payload.joined_at,
|
||||
flags: payload.flags,
|
||||
});
|
||||
};
|
||||
|
||||
export const THREAD_MEMBERS_UPDATE: RawHandler<DiscordThreadMembersUpdate> = (session, _shardId, payload) => {
|
||||
session.emit("threadMembersUpdate", {
|
||||
memberCount: payload.member_count,
|
||||
addedMembers: payload.added_members
|
||||
? payload.added_members.map((tm) => new ThreadMember(session, tm))
|
||||
: undefined,
|
||||
removedMemberIds: payload.removed_member_ids ? payload.removed_member_ids : undefined,
|
||||
guildId: payload.guild_id,
|
||||
id: payload.id,
|
||||
});
|
||||
};
|
||||
|
||||
export const THREAD_LIST_SYNC: RawHandler<DiscordThreadListSync> = (session, _shardId, payload) => {
|
||||
session.emit("threadListSync", {
|
||||
guildId: payload.guild_id,
|
||||
@ -346,7 +368,7 @@ export const GUILD_SCHEDULED_EVENT_USER_REMOVE: RawHandler<DiscordScheduledEvent
|
||||
};
|
||||
|
||||
export const raw: RawHandler<unknown> = (session, shardId, data) => {
|
||||
session.emit("raw", data as { t: string, d: unknown }, shardId);
|
||||
session.emit("raw", data as { t: string; d: unknown }, shardId);
|
||||
};
|
||||
|
||||
export interface Ready extends Omit<DiscordReady, "user"> {
|
||||
@ -386,6 +408,8 @@ export interface Events {
|
||||
"threadUpdate": Handler<[ThreadChannel]>;
|
||||
"threadDelete": Handler<[ThreadChannel]>;
|
||||
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: ThreadMember[] }]>
|
||||
"threadMemberUpdate": Handler<[{id: Snowflake, userId: Snowflake, guildId: Snowflake, joinedAt: string, flags: number }]>
|
||||
"threadMembersUpdate": Handler<[{id: Snowflake, memberCount: number, addedMembers?: ThreadMember[], guildId: Snowflake, removedMemberIds?: Snowflake[]}]>
|
||||
"interactionCreate": Handler<[Interaction]>;
|
||||
"integrationCreate": Handler<[Integration]>;
|
||||
"integrationUpdate": Handler<[Integration]>;
|
||||
|
@ -9,7 +9,7 @@ export interface MessageReactionAdd {
|
||||
messageId: string;
|
||||
guildId?: string;
|
||||
member?: Member;
|
||||
emoji: Partial<Emoji>
|
||||
emoji: Partial<Emoji>;
|
||||
}
|
||||
|
||||
export function NewMessageReactionAdd(session: Session, data: DiscordMessageReactionAdd): MessageReactionAdd {
|
||||
@ -18,9 +18,11 @@ export function NewMessageReactionAdd(session: Session, data: DiscordMessageReac
|
||||
channelId: data.channel_id,
|
||||
messageId: data.message_id,
|
||||
guildId: data.guild_id,
|
||||
member: data.member ? new Member(session, (data.member as DiscordMemberWithUser), (data.guild_id || "")) : undefined,
|
||||
member: data.member
|
||||
? new Member(session, data.member as DiscordMemberWithUser, data.guild_id || "")
|
||||
: undefined,
|
||||
emoji: new Emoji(session, data.emoji),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,19 +210,19 @@ export class Guild extends BaseGuild implements Model {
|
||||
this.explicitContentFilterLevel = data.explicit_content_filter;
|
||||
|
||||
this.members = new Map(
|
||||
data.members?.map((member) => [data.id, new Member(session, { ...member, user: member.user! }, data.id)])
|
||||
data.members?.map((member) => [data.id, new Member(session, { ...member, user: member.user! }, data.id)]),
|
||||
);
|
||||
|
||||
this.roles = new Map(
|
||||
data.roles.map((role) => [data.id, new Role(session, role, data.id)])
|
||||
data.roles.map((role) => [data.id, new Role(session, role, data.id)]),
|
||||
);
|
||||
|
||||
this.emojis = new Map(
|
||||
data.emojis.map((guildEmoji) => [guildEmoji.id!, new GuildEmoji(session, guildEmoji, data.id)])
|
||||
data.emojis.map((guildEmoji) => [guildEmoji.id!, new GuildEmoji(session, guildEmoji, data.id)]),
|
||||
);
|
||||
|
||||
this.channels = new Map(
|
||||
data.channels?.map((guildChannel) => [guildChannel.id, new GuildChannel(session, guildChannel, data.id)])
|
||||
data.channels?.map((guildChannel) => [guildChannel.id, new GuildChannel(session, guildChannel, data.id)]),
|
||||
);
|
||||
}
|
||||
|
||||
|
80
packages/cache/mod.ts
vendored
80
packages/cache/mod.ts
vendored
@ -1,13 +1,13 @@
|
||||
import type {
|
||||
DiscordMessage,
|
||||
DiscordChannel,
|
||||
DiscordEmoji,
|
||||
DiscordGuild,
|
||||
DiscordMemberWithUser,
|
||||
DiscordMessage,
|
||||
DiscordMessageReactionAdd,
|
||||
DiscordMessageReactionRemove,
|
||||
DiscordMessageReactionRemoveEmoji,
|
||||
DiscordMessageReactionRemoveAll,
|
||||
DiscordMessageReactionRemoveEmoji,
|
||||
DiscordUser,
|
||||
Session,
|
||||
Snowflake,
|
||||
@ -15,22 +15,22 @@ import type {
|
||||
} from "./deps.ts";
|
||||
|
||||
import {
|
||||
ChannelTypes,
|
||||
ChannelFactory,
|
||||
ChannelTypes,
|
||||
DMChannel,
|
||||
Emoji,
|
||||
Guild,
|
||||
GuildChannel,
|
||||
GuildEmoji,
|
||||
GuildTextChannel,
|
||||
GuildChannel,
|
||||
Member,
|
||||
Message,
|
||||
MessageReaction,
|
||||
NewsChannel,
|
||||
textBasedChannels,
|
||||
ThreadChannel,
|
||||
User,
|
||||
VoiceChannel,
|
||||
textBasedChannels,
|
||||
} from "./deps.ts";
|
||||
|
||||
export const cache_sym = Symbol("@cache");
|
||||
@ -323,8 +323,7 @@ export function reactionBootstrapperDeletions(cache: SessionCache, payload: Disc
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
cache.dms.retrieve(payload.channel_id, (channel) => {
|
||||
channel.messages.retrieve(payload.message_id, (message) => {
|
||||
message.reactions = [];
|
||||
@ -414,29 +413,34 @@ export function channelBootstrapper(cache: SessionCache, channel: DiscordChannel
|
||||
cache.guilds.retrieve(channel.guild_id, (guild) => {
|
||||
if (textBasedChannels.includes(channel.type)) {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
guild.channels.set(channel.id, <any>Object.assign(
|
||||
guild.channels.set(
|
||||
channel.id,
|
||||
<any> Object.assign(
|
||||
ChannelFactory.fromGuildChannel(cache.session, channel),
|
||||
{ messages: new StructCache<CachedMessage>(cache.session) }
|
||||
));
|
||||
}
|
||||
else {
|
||||
{ messages: new StructCache<CachedMessage>(cache.session) },
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
guild.channels.set(channel.id, <any>ChannelFactory.fromGuildChannel(cache.session, channel));
|
||||
guild.channels.set(channel.id, <any> ChannelFactory.fromGuildChannel(cache.session, channel));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function memberBootstrapper(cache: SessionCache, member: DiscordMemberWithUser, guildId: Snowflake) {
|
||||
cache.guilds.retrieve(guildId, (guild) => {
|
||||
guild.members.set(member.user.id, Object.assign(
|
||||
guild.members.set(
|
||||
member.user.id,
|
||||
Object.assign(
|
||||
new Member(cache.session, member, guildId),
|
||||
{
|
||||
userId: member.user.id,
|
||||
get user(): User | undefined {
|
||||
return cache.users.get(this.userId);
|
||||
}
|
||||
}
|
||||
));
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -450,51 +454,67 @@ export function messageBootstrapper(cache: SessionCache, message: DiscordMessage
|
||||
if (cache.dms.has(message.channel_id)) {
|
||||
// is dm
|
||||
cache.dms.retrieve(message.channel_id, (dm) => {
|
||||
dm.messages[partial ? "updateFields" : "set"](message.id, Object.assign(
|
||||
dm.messages[partial ? "updateFields" : "set"](
|
||||
message.id,
|
||||
Object.assign(
|
||||
new Message(cache.session, message),
|
||||
{
|
||||
authorId: message.author.id,
|
||||
get author(): User | undefined {
|
||||
return cache.users.get(this.authorId);
|
||||
},
|
||||
}
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// is not dm
|
||||
cache.guilds.retrieve(message.guild_id!, (guild) => guild.channels.retrieve(message.channel_id, (dm) => {
|
||||
dm.messages[partial ? "updateFields" : "set"](message.id, Object.assign(
|
||||
cache.guilds.retrieve(message.guild_id!, (guild) =>
|
||||
guild.channels.retrieve(message.channel_id, (dm) => {
|
||||
dm.messages[partial ? "updateFields" : "set"](
|
||||
message.id,
|
||||
Object.assign(
|
||||
new Message(cache.session, message),
|
||||
{
|
||||
authorId: message.author.id,
|
||||
get author(): User | undefined {
|
||||
return cache.users.get(this.authorId);
|
||||
},
|
||||
}
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export function guildBootstrapper(cache: SessionCache, guild: DiscordGuild) {
|
||||
const members = new StructCache(cache.session, guild.members?.map((data) => {
|
||||
const obj: CachedMember = Object.assign(new Member(cache.session, data as DiscordMemberWithUser, guild.id), {
|
||||
const members = new StructCache(
|
||||
cache.session,
|
||||
guild.members?.map((data) => {
|
||||
const obj: CachedMember = Object.assign(
|
||||
new Member(cache.session, data as DiscordMemberWithUser, guild.id),
|
||||
{
|
||||
userId: data.user!.id,
|
||||
get user(): User | undefined {
|
||||
return cache.users.get(this.userId);
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
return [data.user!.id, obj as CachedMember];
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
const channels = new StructCache(cache.session, guild.channels?.map((data) => {
|
||||
const channels = new StructCache(
|
||||
cache.session,
|
||||
guild.channels?.map((data) => {
|
||||
const obj = Object.assign(ChannelFactory.from(cache.session, data), {
|
||||
messages: new Map(),
|
||||
});
|
||||
|
||||
return [data.id, obj as CachedGuildChannel];
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
cache.guilds.set(
|
||||
guild.id,
|
||||
|
@ -27,7 +27,7 @@ export async function connect(shard: Shard): Promise<void> {
|
||||
gotHello = true;
|
||||
// END WSL GATEWAY PATCH
|
||||
shard.handleMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
socket.onopen = () => {
|
||||
|
@ -2268,6 +2268,8 @@ export interface DiscordThreadMembersUpdate {
|
||||
export interface DiscordThreadMemberUpdate {
|
||||
/** The id of the thread */
|
||||
id: string;
|
||||
/** The id of the user */
|
||||
user_id: string;
|
||||
/** The id of the guild */
|
||||
guild_id: string;
|
||||
/** The timestamp when the bot joined this thread. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user