├── .eslintignore
├── .eslintrc
├── .github
├── CODEOWNERS
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_reports.md
│ ├── new_version_reports.md
│ └── suggestions.md
└── SECURITY.md
├── .glitterrc
├── CONTRIBUTING.md
├── FAQ.MD
├── LICENSE
├── README.md
├── assets
└── logo.png
├── package.json
├── src
├── client
│ ├── Client.ts
│ └── ClientUser.ts
├── gateway
│ └── WebSocketManager.ts
├── handlers
│ ├── BaseHandler.ts
│ ├── CommandHandler.ts
│ ├── DatabaseHandler.ts
│ └── EventHandler.ts
├── index.ts
├── structures
│ ├── Base.ts
│ ├── CategoryChannel.ts
│ ├── GenCollection.ts
│ ├── Guild.ts
│ ├── GuildMember.ts
│ ├── Permissions.ts
│ ├── User.ts
│ ├── VoiceChannel.ts
│ ├── channel
│ │ ├── BaseChannel.ts
│ │ ├── DMChannel.ts
│ │ ├── GuildChannel.ts
│ │ ├── NewsChannel.ts
│ │ ├── StoreChannel.ts
│ │ └── TextChannel.ts
│ └── message
│ │ └── Message.ts
└── typings
│ ├── APIOptions.ts
│ ├── ActivityOptions.ts
│ ├── ChannelOptions.ts
│ ├── ClientEvents.ts
│ ├── ClientOptions.ts
│ ├── Constants.ts
│ └── MessageOptions.ts
├── tests
└── testing.ts
└── tsconfig.json
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parser": "@typescript-eslint/parser",
4 | "plugins": ["@typescript-eslint"],
5 | "extends": [
6 | "eslint:recommended",
7 | "plugin:@typescript-eslint/eslint-recommended",
8 | "plugin:@typescript-eslint/recommended"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Global Owner
2 |
3 | * @PraveshKunwar
4 | * @EternalMoon
5 | * @NerdThatNoOneLikes
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: Gencord
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_reports.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ""
5 | labels: bug
6 | ---
7 |
8 | **Describe the bug**
9 | A clear and concise description of what the bug is.
10 |
11 | **To Reproduce**
12 | Steps to reproduce the behavior:
13 |
14 | 1. Go to '...'
15 | 2. Click on '....'
16 | 3. Scroll down to '....'
17 | 4. See error
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **What device are you on?**
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/new_version_reports.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report For New Gencord Version
3 | about: Create a report to help us improve
4 | title: "New Version Bug: "
5 | labels: new-version-bug
6 | ---
7 |
8 | **Describe the bug**
9 | A clear and concise description of what the bug is.
10 |
11 | **To Reproduce**
12 | Steps to reproduce the behavior:
13 |
14 | 1. Go to '...'
15 | 2. Click on '....'
16 | 3. Scroll down to '....'
17 | 4. See error
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **What device are you on?**
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/suggestions.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Suggestions for Gencord
3 | about: Create a suggestion to help us improve
4 | title: "New suggestion: "
5 | labels: new-suggestion
6 | ---
7 |
8 | **Tell us your suggestion**
9 |
10 | Let us know what your suggestion is:
11 |
12 | **How will this suggestion improve Gencord?**
13 |
14 | How will this suggestion change Gencord? Will it be helpful?
15 |
--------------------------------------------------------------------------------
/.github/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policies and Procedures
2 |
3 | This document outlines security procedures and general policies for the `Gencord`
4 | project.
5 |
6 | - [Reporting a Bug](#reporting-a-bug)
7 | - [Disclosure Policy](#disclosure-policy)
8 | - [Comments on this Policy](#comments-on-this-policy)
9 |
10 | ## Reporting a Bug
11 |
12 | The `Gencord` team and community take all security bugs in `Gencord` seriously.
13 | Thank you for improving the security of `Gencord`. We appreciate your efforts and
14 | responsible disclosure and will make every effort to acknowledge your
15 | contributions.
16 |
17 | Report security bugs by emailing the lead maintainer at feross@feross.org.
18 |
19 | The lead maintainer will acknowledge your email within 48 hours, and will send a
20 | more detailed response within 48 hours indicating the next steps in handling
21 | your report. After the initial reply to your report, the security team will
22 | endeavor to keep you informed of the progress towards a fix and full
23 | announcement, and may ask for additional information or guidance.
24 |
25 | Report security bugs in third-party modules to the person or team maintaining
26 | the module.
27 |
28 | ## Disclosure Policy
29 |
30 | When the security team receives a security bug report, they will assign it to a
31 | primary handler. This person will coordinate the fix and release process,
32 | involving the following steps:
33 |
34 | - Confirm the problem and determine the affected versions.
35 | - Audit code to find any potential similar problems.
36 | - Prepare fixes for all releases still under maintenance. These fixes will be
37 | released as fast as possible to npm.
38 |
39 | ## Comments on this Policy
40 |
41 | If you have suggestions on how this process could be improved please submit a
42 | pull request.
43 |
--------------------------------------------------------------------------------
/.glitterrc:
--------------------------------------------------------------------------------
1 | {
2 | "commit_message": "$1($2): $3+"
3 | }
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # 🌌 Contributing
2 |
3 | Welcome to the contributing page for Gencord. If you want to contribute, please check out the guidelines down below. If you have already forked and cloned, skip to the Development section.
4 |
5 | ## 🚀 Development
6 |
7 | For development, please use yarn. We will not be using npm as our package manager. To check if you have yarn installed:
8 |
9 | ```js
10 | yarn version
11 | ```
12 |
13 | If you have it installed, great. Now, lets talk about coding. Gencord is written and maintained by Typescript. Please make sure you have typescript installed:
14 |
15 | ```js
16 | yarn add typescript
17 | ```
18 |
19 | Before you make any changes, please make sure that you are up to date with the latest version of the repo. Switch the base, make a pull request, submit it, then merge the PR to your codebase. To get the latest changes from the repo after updating run:
20 |
21 | ```js
22 | git pull
23 | ```
24 |
25 | After making changes, please run:
26 |
27 | ```js
28 | yarn run lint
29 | ```
30 |
31 | To format the code. This is MANDATORY, so we do not have any formatting issues, and that code looks concise and clean.
32 |
33 | Any changes that you want to make are all welcomed and will be reviewed. However, it is MANDATORY that you use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#summary). All commit messages be written within conventional commit standards:
34 |
35 | ```
36 | // Example:
37 | 🌌 (fix): Fixed issues with typings in Client.ts
38 | 🚀 (feat): New structure added: VoiceChannel.ts
39 | 🎉 (docs): Updated CONTRIBUTING.md.
40 | //and any conventional commit you want. Emojis are optional, but they must follow this standard.
41 | ```
42 |
43 | After you have committed the changes, make a pull request, and please provide a detailed description of what changes you made. This way, things will run a lot more smoother.
44 |
45 | ### 🔰 Naming methods and properties
46 |
47 | When it comes to naming methods and properties, here at Gencord, we have created a "system" to help name methods and properties. Note that for properties, we follow the **camel case** method. Check it out:
48 |
49 | | Before | After |
50 | | ----------------- | --------------- |
51 | | fetchAllMembers() | members.fetch() |
52 | | slash-commands | slashCommands |
53 |
54 | If a mistake was made, we will review it and submit comments. Then, you can recommit and we will review until it looks good!
55 |
56 | ## 🔗 Links
57 |
58 | - [Gist on conventional commits](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)
59 | - [Conventional commits official](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#summary)
60 |
61 | Thank you for all the contributions. If you have any questions, feel free to join the [Discord Server.](https://discord.gg/GGQyhXRNZ2)
62 |
--------------------------------------------------------------------------------
/FAQ.MD:
--------------------------------------------------------------------------------
1 | # 🌌 FAQ (Frequently Asked Questions)
2 |
3 | Here are some frequently asked questions about Gencord:
4 |
5 | ## How can I contribute?
6 |
7 | Check out CONTRIBUTING.md in the root directory to check out our contributing guidelines.
8 |
9 | ## Why did you use Typescript?
10 |
11 | The initial developers of Gencord loved Typescript, and decided to use Typescript as the main language of the project.
12 |
13 | ## More questions?
14 |
15 | Have more questions? Join our [Discord Server](https://discord.gg/YJgUkRA6be) to get more support!
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Gencord
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |

5 |

6 |

7 |

8 |

9 |

10 |

11 |

12 |

13 |

14 |

15 |

16 |
17 |
18 | ## Welcome! 👋
19 |
20 | Welcome to Gencord. A simple, beginner-friendly, and easy-to-use library for interacting with the Discord API, with minimal syntax.
21 |
22 | Support server can be found [here.](https://discord.gg/YJgUkRA6be)
23 |
24 | ```sh
25 | ❓ Q: Why should I use this Library?
26 | ```
27 |
28 | > ❗ A: Great question! We know that for beginners, using Discord.JS can be a challenge. Gencord tries to solve this problem by using minimal syntax to make the challenge a lot easier.
29 |
30 | ```sh
31 | ❓ Q: How can I contribute to this project?
32 | ```
33 |
34 | > ❗ A: If you would like to contribute, more information will be down below, and you can also check out CONTRIBUTING.md in the root directory of this project!
35 |
36 | ## Contributions 📜
37 |
38 | If you would like to contribute by:
39 |
40 | - 🔰 New suggestions.
41 | - 🔰 Changing code, or code suggestions.
42 | - 🔰 Bot website, or contributing to a bot website.
43 | - 🔰 Patreon.
44 |
45 | You may contact us through one of the following:
46 |
47 | > Join our [Discord Server.](https://discord.gg/YJgUkRA6be)
48 |
49 | ### Author Creds:
50 |
51 | © 2021, Gencord. All rights reserved.
52 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/festiveelephantseal/gencord/67ea1e2a6e16029b6eec5638a1954ee5d6f8994e/assets/logo.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gencord",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "src/index.ts",
6 | "scripts": {
7 | "test": "ts-node tests/testing.ts",
8 | "lint": "prettier --write .",
9 | "build": "tsc"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/Gencord/gencord.git"
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/Gencord/gencord/issues"
20 | },
21 | "homepage": "https://github.com/Gencord/gencord#readme",
22 | "devDependencies": {
23 | "@types/node": "^14.14.37",
24 | "@types/node-fetch": "^2.5.10",
25 | "@types/ws": "^7.4.1",
26 | "prettier": "^2.2.1",
27 | "ts-node": "^9.1.1",
28 | "ts-node-dev": "^1.1.6",
29 | "typescript": "^4.2.4"
30 | },
31 | "dependencies": {
32 | "node-fetch": "^2.6.1",
33 | "ws": "^7.4.4"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/client/Client.ts:
--------------------------------------------------------------------------------
1 | import WebSocketManager from "../gateway/WebSocketManager";
2 | import { ClientOptions } from "../typings/ClientOptions";
3 | import EventEmitter from "events";
4 | import { ClientEvents } from "src/typings/ClientEvents";
5 | import { ClientUser } from "./ClientUser";
6 | import ws from "ws";
7 | import fetch from "node-fetch";
8 | import { BaseConstants } from "../typings/Constants";
9 | import { Message } from "../structures/message/Message";
10 | import { APIOptions } from "../typings/APIOptions";
11 |
12 | export declare interface Client {
13 | login(token: string): Promise;
14 | token: string;
15 | options: ClientOptions;
16 | user: ClientUser;
17 | on(event: E, listener: ClientEvents[E]): this;
18 | }
19 |
20 | export class Client extends EventEmitter {
21 | /**
22 | * Represents the Gencord Client.
23 | * @extends EventEmitter
24 | * @arg {String} token The token for the bot to use.
25 | * @arg {Object} [options] Options for the client.
26 | * @arg {Number | String} [options.intents] The intents for the client.
27 | */
28 | public constructor(token: string, options: ClientOptions) {
29 | super();
30 | this.options = options;
31 | this.token = token;
32 | }
33 | private socket: ws;
34 |
35 | protected heartbeat(ms: number) {
36 | setInterval(() => {
37 | this.socket.send(JSON.stringify({ op: 1, d: null }));
38 | }, ms);
39 | }
40 |
41 | public async request(options: APIOptions) {
42 | const fetched = await fetch(`${BaseConstants.API}${options.endpoint}`, {
43 | method: options.method,
44 | headers: {
45 | "Content-Type": "application/json",
46 | Authorization: `Bot ${this.token}`,
47 | },
48 | body: options.body,
49 | });
50 | if (fetched.status === 429) {
51 | const json = await fetched.json();
52 | throw new Error(
53 | `You have been ratelimited, Request will be retried after ${json.retry_after}`
54 | );
55 | }
56 | }
57 |
58 | /**
59 | * Logs on to Discords API.
60 | * @returns {Promise} Resolves when it has logged on.
61 | */
62 |
63 | public async login(): Promise {
64 | try {
65 | this.socket = new ws(BaseConstants.GATEWAY);
66 |
67 | this.socket.on("open", () => {
68 | this.identify();
69 | });
70 |
71 | this.socket.on("message", async (message) => {
72 | const payload = JSON.parse(message.toString());
73 | const { t, s, op, d } = payload;
74 |
75 | if (op === 10) {
76 | const { heartbeat_interval } = d;
77 | this.heartbeat(heartbeat_interval);
78 | } else if (payload.op === 0) {
79 | this.emit(t, d);
80 | }
81 | switch (t) {
82 | case "READY":
83 | this.emit("ready");
84 | break;
85 | case "MESSAGE_CREATE":
86 | this.emit("message", new Message(payload.d, this));
87 | break;
88 | }
89 | });
90 |
91 | this.socket.on("error", (error: string) => {
92 | console.log("Error", error);
93 | });
94 |
95 | this.socket.on("close", (error: any) => {
96 | if (error === 4004) throw new Error("Invalid token.");
97 | if (error === 4000) throw new Error("Unknown Error.");
98 | if (error === 4008) throw new Error("Ratelimited.");
99 | if (error === 4009) throw new Error("Session Timed Out.");
100 | this;
101 | });
102 | } catch (e) {
103 | e ? console.log(e) : false;
104 | }
105 | }
106 |
107 | public async ping(): Promise {
108 | try {
109 | this.socket.ping();
110 | return setTimeout(() => {
111 | this.ping();
112 | }, 60000);
113 | } catch (err) {
114 | this.emit("error", err);
115 | }
116 | }
117 |
118 | public identify() {
119 | this.socket.send(
120 | JSON.stringify({
121 | op: 2,
122 | d: {
123 | token: this.token,
124 | intents: this.options.intents,
125 | properties: {
126 | $os: "linux",
127 | $browser: "gencord",
128 | $device: "gencord",
129 | },
130 | presence: {
131 | status: this.options.status,
132 | activities: [
133 | {
134 | name: this.options.activityName,
135 | type: this.options.activityType,
136 | },
137 | ],
138 | },
139 | },
140 | })
141 | );
142 | }
143 | }
144 |
145 | export default Client;
146 |
--------------------------------------------------------------------------------
/src/client/ClientUser.ts:
--------------------------------------------------------------------------------
1 | export class ClientUser {
2 | constructor(
3 | private username: string,
4 | private discriminator: string,
5 | private verified: boolean,
6 | private id: string,
7 | private flags: number,
8 | private email: string | null,
9 | private bot: boolean,
10 | private avatar: string
11 | ) {}
12 | public get _username(): string {
13 | return this.username;
14 | }
15 | public get _discriminator(): string {
16 | return this.discriminator;
17 | }
18 | public get _verified(): boolean {
19 | return this.verified;
20 | }
21 | public get _id(): string {
22 | return this.id;
23 | }
24 | public get _flags(): number {
25 | return this.flags;
26 | }
27 | public get _email(): string | null {
28 | return this.email;
29 | }
30 | public get _bot(): boolean {
31 | return this.bot;
32 | }
33 | public get _avatar(): string {
34 | return this.avatar;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/gateway/WebSocketManager.ts:
--------------------------------------------------------------------------------
1 | import { Client } from "../client/Client";
2 | import EventEmitter from "events";
3 | import ws from "ws";
4 | import WebSocket from "ws";
5 | import { BaseConstants } from "../typings/Constants";
6 |
7 | export default class WebSocketManager extends EventEmitter {
8 | public socket: ws;
9 |
10 | public constructor(private client: Client) {
11 | super();
12 | }
13 |
14 | public connect(token: string) {}
15 |
16 | protected heartbeat(ms: number) {
17 | setInterval(() => {
18 | this.socket.send(JSON.stringify({ op: 1, d: null }));
19 | }, ms);
20 | }
21 |
22 | public destroy(reason?: string) {
23 | this.socket.close();
24 | console.log(`The socket was closed, ${reason || "No reason provided"}`);
25 | process.exit();
26 | }
27 |
28 | public async ping(): Promise {
29 | try {
30 | this.socket.ping();
31 | return setTimeout(() => {
32 | this.ping();
33 | }, 60000);
34 | } catch (err) {
35 | this.emit("error", err);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/handlers/BaseHandler.ts:
--------------------------------------------------------------------------------
1 | export abstract class BaseHandler {}
2 |
--------------------------------------------------------------------------------
/src/handlers/CommandHandler.ts:
--------------------------------------------------------------------------------
1 | import { BaseHandler } from "./BaseHandler";
2 |
3 | export class CommandHandler extends BaseHandler {}
4 |
--------------------------------------------------------------------------------
/src/handlers/DatabaseHandler.ts:
--------------------------------------------------------------------------------
1 | import { BaseHandler } from "./BaseHandler";
2 |
3 | export class DatabaseHandler extends BaseHandler {}
4 |
--------------------------------------------------------------------------------
/src/handlers/EventHandler.ts:
--------------------------------------------------------------------------------
1 | import { BaseHandler } from "./BaseHandler";
2 |
3 | export class EventHandler extends BaseHandler {}
4 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { Client } from "./client/Client";
2 | export { Message } from "./structures/message/Message";
3 |
--------------------------------------------------------------------------------
/src/structures/Base.ts:
--------------------------------------------------------------------------------
1 | import { Client } from "../client/Client";
2 |
3 | export abstract class Base {
4 | public client: Client;
5 |
6 | public get _client(): Client {
7 | return this.client;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/structures/CategoryChannel.ts:
--------------------------------------------------------------------------------
1 | import { TextChannel } from "./channel/TextChannel";
2 |
3 | export class CategoryChannel extends TextChannel {}
4 |
--------------------------------------------------------------------------------
/src/structures/GenCollection.ts:
--------------------------------------------------------------------------------
1 | export class GenCollection extends Map {
2 | public first(){
3 |
4 | }
5 | public last(){
6 |
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/structures/Guild.ts:
--------------------------------------------------------------------------------
1 | import { Base } from "./Base";
2 |
3 | export class Guild extends Base {}
4 |
--------------------------------------------------------------------------------
/src/structures/GuildMember.ts:
--------------------------------------------------------------------------------
1 | import { Base } from "./Base";
2 |
3 | export class GuildMember extends Base {}
4 |
--------------------------------------------------------------------------------
/src/structures/Permissions.ts:
--------------------------------------------------------------------------------
1 | export class Permissions {}
2 |
--------------------------------------------------------------------------------
/src/structures/User.ts:
--------------------------------------------------------------------------------
1 | import { Base } from "./Base";
2 |
3 | export class User extends Base {
4 | private bot?: boolean;
5 |
6 | public get _bot(): boolean | undefined {
7 | return this.bot;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/structures/VoiceChannel.ts:
--------------------------------------------------------------------------------
1 | import { TextChannel } from "./channel/TextChannel";
2 |
3 | export class VoiceChannel extends TextChannel {}
4 |
--------------------------------------------------------------------------------
/src/structures/channel/BaseChannel.ts:
--------------------------------------------------------------------------------
1 | import { Base } from "../Base";
2 | import { ChannelTypes } from "../../typings/ChannelOptions";
3 | export abstract class BaseChannel extends Base {
4 | private _id: string;
5 | private readonly _createdAt: Date;
6 | private readonly _createdTimestamp: number;
7 | private _deleted: boolean;
8 | private _type: ChannelTypes;
9 |
10 | public constructor(data: any) {
11 | super();
12 | this._id = data.id;
13 | this._type = data.type;
14 | }
15 |
16 | public get id(): string {
17 | return this._id;
18 | }
19 |
20 | public get type(): ChannelTypes {
21 | return this._type;
22 | }
23 |
24 | public get deleted(): boolean {
25 | return this.deleted;
26 | }
27 |
28 | public async delete(): Promise {
29 | return new Promise((resolve, reject) => {
30 | this.client
31 | .request({
32 | method: "DELETE",
33 | endpoint: `/channels/${this.id}`,
34 | })
35 | .catch((err) => {
36 | err ? reject(this) : false;
37 | });
38 |
39 | resolve(this);
40 | });
41 | }
42 |
43 | public async get(): Promise {
44 | return new Promise((resolve, reject) => {
45 | this.client
46 | .request({
47 | method: "GET",
48 | endpoint: `/channels/${this.id}`,
49 | })
50 | .catch((err) => {
51 | err ? reject(this) : false;
52 | });
53 | resolve(this);
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/structures/channel/DMChannel.ts:
--------------------------------------------------------------------------------
1 | import { TextChannel } from "./TextChannel";
2 |
3 | export class DMChannel extends TextChannel {}
4 |
--------------------------------------------------------------------------------
/src/structures/channel/GuildChannel.ts:
--------------------------------------------------------------------------------
1 | import { BaseChannel } from "./BaseChannel";
2 | import { ChannelTypes } from "../../typings/ChannelOptions";
3 | import { GenCollection } from "../GenCollection";
4 | import { Permissions } from "../Permissions";
5 | import { Client } from "../../client/Client";
6 | import { Guild } from "../Guild";
7 | import { GuildMember } from "../GuildMember";
8 |
9 | export abstract class GuildChannel extends BaseChannel {
10 | private _lastMessageID: string;
11 | private _lastPinAt: Date;
12 | private _position: number;
13 | private _parentID: string;
14 | private _topic: string;
15 | private _members = new GenCollection();
16 | private _guild: Guild;
17 | private _nsfw: boolean;
18 | private _rateLimit: number;
19 | public constructor(data: any, client: Client) {
20 | super(data);
21 | this._lastMessageID = data.lastMessageID;
22 | this._lastPinAt = data.lastPinAt;
23 | this._position = data.position;
24 | this._topic = data.topic;
25 | this._guild = data.guild;
26 | this._members = data.members;
27 | this._rateLimit = data.rateLimit;
28 | }
29 | public get lastMessageID(): string {
30 | return this._lastMessageID;
31 | }
32 |
33 | public get lastPinAt(): Date {
34 | return this._lastPinAt;
35 | }
36 |
37 | public get position(): number {
38 | return this._position;
39 | }
40 |
41 | public get parentID(): string {
42 | return this._parentID;
43 | }
44 |
45 | public get topic(): string {
46 | return this._topic;
47 | }
48 |
49 | public get guild(): Guild {
50 | return this._guild;
51 | }
52 |
53 | public get members(): GenCollection {
54 | return this._members;
55 | }
56 |
57 | public get rateLimit(): number {
58 | return this._rateLimit;
59 | }
60 |
61 | public get nsfw(): boolean {
62 | return this._nsfw;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/structures/channel/NewsChannel.ts:
--------------------------------------------------------------------------------
1 | import { TextChannel } from "./TextChannel";
2 |
3 | export class NewsChannel extends TextChannel {}
4 |
--------------------------------------------------------------------------------
/src/structures/channel/StoreChannel.ts:
--------------------------------------------------------------------------------
1 | import { TextChannel } from "./TextChannel";
2 |
3 | export class StoreChannel extends TextChannel {}
4 |
--------------------------------------------------------------------------------
/src/structures/channel/TextChannel.ts:
--------------------------------------------------------------------------------
1 | import { GuildChannel } from "./GuildChannel";
2 | import { GuildMember } from "../GuildMember";
3 | import { GenCollection } from "../GenCollection";
4 | import { Message } from "../message/Message";
5 |
6 | export class TextChannel extends GuildChannel {
7 | /* private _messages = new Collection();
8 | public constructor(){
9 | super(data, this.client);
10 | }
11 | public async send(content: string): Promise {
12 | return new Promise(async (resolve, reject) => {
13 | await this.client
14 | .request({
15 | method: "POST",
16 | endpoint: `channels/${this.id}/messages`,
17 | body: JSON.stringify(content),
18 | })
19 | .catch((err) => {
20 | err ? reject(this) : false;
21 | throw new Error(err);
22 | });
23 | });
24 | }*/
25 | }
--------------------------------------------------------------------------------
/src/structures/message/Message.ts:
--------------------------------------------------------------------------------
1 | import { Client } from "../../client/Client";
2 | import { Base } from "../Base";
3 | import { MessageTypes } from "../../typings/MessageOptions";
4 | import {
5 | MessageDeleteOptions,
6 | MessagePinOptions,
7 | } from "../../typings/MessageOptions";
8 | //import { TextChannel } from "../TextChannel";
9 | import { DMChannel } from "../channel/DMChannel";
10 | import { NewsChannel } from "../channel/NewsChannel";
11 | import { TextChannel } from "../channel/TextChannel";
12 | import { GuildMember } from "../GuildMember";
13 | import { GuildChannel } from "../channel/GuildChannel";
14 | import { ChannelTypes } from "src/typings/ChannelOptions";
15 | import { StoreChannel } from "../channel/StoreChannel";
16 | import { User } from "../User";
17 |
18 | export class Message {
19 | private client: Client;
20 | private id: string;
21 | private channel_id: string;
22 | private type: ChannelTypes;
23 | private tts: boolean;
24 | private member: GuildMember;
25 | private author: User;
26 | private content: string;
27 | private timestamp: Date;
28 | private editedAt: Date;
29 | private mentionedEveryone: boolean;
30 | private nonce: string | number;
31 | public channel: TextChannel | StoreChannel | NewsChannel;
32 | public constructor(data: any, client: Client) {
33 | this.client = client;
34 | this.id = data.id;
35 | this.channel_id = data.channel_id;
36 | this.type = data.type;
37 | this.tts = data.tts;
38 | this.client
39 | .request({
40 | method: "GET",
41 | endpoint: `/channels/${data.channel_id}`,
42 | })
43 | .then((c: any) => {
44 | return (this.channel = c);
45 | });
46 | this.content = data.content;
47 | this.timestamp = data.timestamp;
48 | this.editedAt = data.editedAt;
49 | this.mentionedEveryone = data.mentionedEveryone;
50 | this.nonce = data.nonce;
51 | this.type = data.type;
52 | this.author = data.author;
53 | }
54 |
55 | public get _type(): ChannelTypes {
56 | return this.type;
57 | }
58 |
59 | public get _author(): User {
60 | return this.author;
61 | }
62 |
63 | public get _id(): string {
64 | return this.id;
65 | }
66 |
67 | public get _timestamp(): Date {
68 | return this.timestamp;
69 | }
70 |
71 | public get _channel(): TextChannel | NewsChannel | StoreChannel {
72 | return this.channel;
73 | }
74 |
75 | public get _nonce(): string | number {
76 | return this.nonce;
77 | }
78 |
79 | public get _content(): string {
80 | return this.content;
81 | }
82 |
83 | public get _tts(): boolean {
84 | return this.tts;
85 | }
86 |
87 | public get _editedAt(): Date {
88 | return this.editedAt;
89 | }
90 |
91 | public get _mentionedEveryone(): boolean {
92 | return this.mentionedEveryone;
93 | }
94 |
95 | public get _member(): GuildMember {
96 | return this.member;
97 | }
98 |
99 | /*public get channel(): TextChannel | NewsChannel | StoreChannel {
100 | return this.channel;
101 | }*/
102 |
103 | public async delete(options: MessageDeleteOptions): Promise {
104 | return new Promise((resolve, reject) => {
105 | setTimeout(async () => {
106 | await this.client
107 | .request({
108 | method: "DELETE",
109 | endpoint: `channels/${this.channel.id}/messages/${this.id}`,
110 | })
111 | .catch((err) => {
112 | err ? reject(this) : false;
113 | throw new Error(err);
114 | });
115 |
116 | resolve(this);
117 | }, options.timeout);
118 | });
119 | }
120 |
121 | public async pin(options: MessagePinOptions): Promise {
122 | return new Promise((resolve, reject) => {
123 | this.client
124 | .request({
125 | method: "PUT",
126 | endpoint: `/channels/${this.channel_id}/pins/${this.id}`,
127 | body: options,
128 | })
129 | .catch((err) => {
130 | err ? reject(this) : false;
131 | throw new Error(err);
132 | });
133 |
134 | resolve(this);
135 | });
136 | }
137 |
138 | public async reply(content: string): Promise {
139 | console.log("asd");
140 | return new Promise(async (resolve, reject) => {
141 | await this.client
142 | .request({
143 | method: "POST",
144 | endpoint: `channels/${this.channel_id}/messages`,
145 | body: JSON.stringify({
146 | content: content,
147 | tts: false,
148 | message_reference: {
149 | message_id: this.id,
150 | channel_id: this.channel_id,
151 | },
152 | }),
153 | })
154 | .catch((err) => {
155 | err ? reject(this) : false;
156 | throw new Error(err);
157 | });
158 | resolve(this);
159 | });
160 | }
161 |
162 | public async unpin(options: MessagePinOptions): Promise {
163 | return new Promise((resolve, reject) => {
164 | this.client
165 | .request({
166 | method: "DELETE",
167 | endpoint: `/channels/${this.channel_id}/pins/${this.id}`,
168 | body: options,
169 | })
170 | .catch((err) => {
171 | err ? reject(this) : false;
172 | throw new Error(err);
173 | });
174 | resolve(this);
175 | });
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/typings/APIOptions.ts:
--------------------------------------------------------------------------------
1 | export interface APIOptions {
2 | endpoint: string;
3 | method: "GET" | "POST" | "DELETE" | "PUT" | "PATCH";
4 | body?: any;
5 | }
6 |
--------------------------------------------------------------------------------
/src/typings/ActivityOptions.ts:
--------------------------------------------------------------------------------
1 | export enum ActivityOptions {
2 | Playing = 0,
3 | Streaming = 1,
4 | Listening = 2,
5 | Custom = 4,
6 | Competing = 5,
7 | }
8 |
--------------------------------------------------------------------------------
/src/typings/ChannelOptions.ts:
--------------------------------------------------------------------------------
1 | export type ChannelTypes =
2 | | "dm"
3 | | "text"
4 | | "voice"
5 | | "category"
6 | | "news"
7 | | "store"
8 | | "unknown";
9 |
--------------------------------------------------------------------------------
/src/typings/ClientEvents.ts:
--------------------------------------------------------------------------------
1 | import { Message } from "../structures/message/Message";
2 |
3 | export interface ClientEvents {
4 | ready: () => void;
5 | message: (message: Message) => void;
6 | }
7 |
--------------------------------------------------------------------------------
/src/typings/ClientOptions.ts:
--------------------------------------------------------------------------------
1 | import { ActivityOptions } from "./ActivityOptions";
2 | export interface ClientOptions {
3 | intents?: number | string;
4 | status?: "online" | "idle" | "dnd" | "invisible";
5 | activityName?: string;
6 | activityType?: ActivityOptions;
7 | }
8 |
--------------------------------------------------------------------------------
/src/typings/Constants.ts:
--------------------------------------------------------------------------------
1 | export enum BaseConstants {
2 | GATEWAY = "wss://gateway.discord.gg/?v=8&encoding=json",
3 | API = "https://discord.com/api/v8/",
4 | }
5 |
--------------------------------------------------------------------------------
/src/typings/MessageOptions.ts:
--------------------------------------------------------------------------------
1 | export type MessageTypes =
2 | | "DEFAULT"
3 | | "RECIPIENT_ADD"
4 | | "RECIPIENT_REMOVE"
5 | | "CALL"
6 | | "CHANNEL_NAME_CHANGE"
7 | | "CHANNEL_ICON_CHANGE"
8 | | "PINS_ADD"
9 | | "GUILD_MEMBER_JOIN"
10 | | "USER_PREMIUM_GUILD_SUBSCRIPTION"
11 | | "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1"
12 | | "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2"
13 | | "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3"
14 | | "CHANNEL_FOLLOW_ADD"
15 | | "GUILD_DISCOVERY_DISQUALIFIED"
16 | | "GUILD_DISCOVERY_REQUALIFIED";
17 |
18 | export interface MessageDeleteOptions {
19 | timeout?: number;
20 | reason?: string;
21 | }
22 |
23 | export interface MessagePinOptions {
24 | reason?: string;
25 | }
26 |
--------------------------------------------------------------------------------
/tests/testing.ts:
--------------------------------------------------------------------------------
1 | import { Message } from "src";
2 | import { Client } from "../src/client/Client";
3 | import { token } from "./token";
4 |
5 | const client = new Client(token, {
6 | intents: 513,
7 | status: "idle",
8 | activityType: 0,
9 | activityName: "github.com/Gencord/gencord",
10 | });
11 |
12 | client.on("ready", () => {
13 | console.log("ready");
14 | });
15 |
16 | client.on("message", (message: Message) => {
17 | if (message._content === "!hello") {
18 | message.reply("Hello!");
19 | }
20 | });
21 |
22 | client.login();
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
6 | "sourceMap": true,
7 | "outDir": "./dist",
8 | "moduleResolution": "node",
9 | "removeComments": false, //set to false because of documentation of code.
10 | "noImplicitAny": true,
11 | "strictNullChecks": true,
12 | "strictFunctionTypes": true,
13 | "noImplicitThis": true,
14 | "noUnusedLocals": false,
15 | "noUnusedParameters": false,
16 | "noImplicitReturns": true,
17 | "noFallthroughCasesInSwitch": true,
18 | "allowSyntheticDefaultImports": true,
19 | "esModuleInterop": true,
20 | "emitDecoratorMetadata": true,
21 | "experimentalDecorators": true,
22 | "resolveJsonModule": true,
23 | "baseUrl": "."
24 | },
25 | "exclude": ["node_modules"],
26 | "include": ["./tests/*.ts", "./src/**/*.ts"]
27 | }
28 |
--------------------------------------------------------------------------------