├── .eslintignore
├── .eslintrc.js
├── .github
├── CODEOWNER
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── ci.yml
│ └── docs.yml
├── .gitignore
├── .husky
├── .gitignore
├── commit-msg
└── pre-commit
├── LICENSE
├── README.md
├── babel.config.js
├── commitlint.config.js
├── examples
├── README.md
├── command-handler
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ │ ├── commands
│ │ ├── embed.js
│ │ └── ping.js
│ │ └── index.js
├── getting-started
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ │ └── index.js
└── reactions
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ └── index.js
├── jest.config.js
├── lerna.json
├── lint-staged.config.js
├── package-lock.json
├── package.json
├── packages
├── common
│ ├── README.md
│ ├── __tests__
│ │ ├── CacheCollection.test.ts
│ │ ├── MessageUtil.test.data.json
│ │ ├── MessageUtil.test.ts
│ │ └── util.test.ts
│ ├── lib
│ │ ├── CacheCollection.ts
│ │ ├── MessageUtil.ts
│ │ ├── UUID.ts
│ │ ├── index.ts
│ │ └── util.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── embeds
│ ├── LICENSE
│ ├── README.md
│ ├── __tests__
│ │ ├── embed.test.ts
│ │ └── util.test.ts
│ ├── lib
│ │ ├── Embed.ts
│ │ ├── consts.ts
│ │ ├── index.ts
│ │ └── util.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── guilded-api-typings
│ ├── README.md
│ ├── lib
│ │ ├── common
│ │ │ ├── Content.ts
│ │ │ ├── Document.ts
│ │ │ ├── Plant.ts
│ │ │ ├── index.ts
│ │ │ └── structures
│ │ │ │ ├── Channel.ts
│ │ │ │ ├── Emoji.ts
│ │ │ │ ├── Team.ts
│ │ │ │ ├── User.ts
│ │ │ │ ├── Webhook.ts
│ │ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── rest
│ │ │ ├── Channel.ts
│ │ │ ├── Emoji.ts
│ │ │ ├── Team.ts
│ │ │ ├── User.ts
│ │ │ ├── Webhook.ts
│ │ │ └── index.ts
│ │ └── ws
│ │ │ ├── ChatMessageCreated.ts
│ │ │ ├── ChatMessageReactionAdded.ts
│ │ │ ├── ChatMessageReactionDeleted.ts
│ │ │ ├── ChatMessageUpdated.ts
│ │ │ ├── Ready.ts
│ │ │ └── index.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── guilded.js
│ ├── LICENSE
│ ├── README.md
│ ├── __tests__
│ │ ├── colors.js
│ │ ├── index.js
│ │ └── modules
│ │ │ ├── connection.js
│ │ │ ├── embed.js
│ │ │ ├── invite.js
│ │ │ ├── message.js
│ │ │ ├── role.js
│ │ │ └── ws.js
│ ├── lib
│ │ ├── index.ts
│ │ ├── structures
│ │ │ ├── Base.ts
│ │ │ ├── Channel.ts
│ │ │ ├── Client.ts
│ │ │ ├── Group.ts
│ │ │ ├── Member.ts
│ │ │ ├── Message.ts
│ │ │ ├── Role.ts
│ │ │ ├── Team.ts
│ │ │ ├── User.ts
│ │ │ ├── Webhook.ts
│ │ │ ├── index.ts
│ │ │ └── managers
│ │ │ │ ├── BaseManager.ts
│ │ │ │ ├── ChannelManager.ts
│ │ │ │ ├── MessageManager.ts
│ │ │ │ ├── TeamGroupChannelManager.ts
│ │ │ │ ├── TeamGroupManager.ts
│ │ │ │ ├── TeamManager.ts
│ │ │ │ ├── TeamMemberManager.ts
│ │ │ │ ├── TeamMemberRoleManager.ts
│ │ │ │ ├── TeamRoleManager.ts
│ │ │ │ ├── TeamWebhookManager.ts
│ │ │ │ ├── UserManager.ts
│ │ │ │ └── index.ts
│ │ ├── typings.ts
│ │ ├── util.ts
│ │ └── ws
│ │ │ ├── ClientGatewayHandler.ts
│ │ │ ├── GatewayHandler.ts
│ │ │ ├── Heartbeater.ts
│ │ │ └── events
│ │ │ ├── ChatMessageCreated.ts
│ │ │ ├── ChatMessageReactionAdded.ts
│ │ │ ├── ChatMessageReactionDeleted.ts
│ │ │ ├── ChatMessageUpdated.ts
│ │ │ └── Event.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── rest
│ ├── README.md
│ ├── lib
│ │ ├── GuildedAPIError.ts
│ │ ├── RestManager.ts
│ │ └── index.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
└── webhook-client
│ ├── README.md
│ ├── __tests__
│ └── Webhook.test.ts
│ ├── lib
│ ├── Webhook.ts
│ └── index.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── prettier.config.js
├── scripts
├── jest.js
├── post-docs.js
├── refresh.js
├── reset.js
└── setup.js
├── static
├── guilded-icon.png
├── itami-transparent.png
└── readme-header.png
├── testing.env.example
├── tsconfig.base.json
├── typedoc.config.js
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | types/
4 | *.d.ts
5 | packages/**/*.js
--------------------------------------------------------------------------------
/.github/CODEOWNER:
--------------------------------------------------------------------------------
1 | / @zaida04
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | https://discord.gg/jf66UUN.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 | The issue tracker for bug reports and enhancement suggestions. If you have a question, please ask away!
3 |
4 | If you wish to contribute to the codebase or documentation, feel free to fork the repository and submit a pull request. We use ESLint to enforce a consistent coding style, so having that set up in your editor of choice is a great boon to your development process.
5 |
6 | # Setup
7 | To get ready to work on the codebase, please do the following:
8 |
9 | Fork & clone the repository, and make sure you're on the main branch
10 | Run npm install
11 | Code your heart out!
12 | Run npm run test to run ESLint and ensure any JSDoc changes are valid
13 | Submit a pull request (Make sure you follow the conventional commit format)
14 |
15 | > Adapted from https://github.com/discordjs/discord.js/blob/master/.github/CONTRIBUTING.md
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Report something not working at expected.
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Please complete the following information**
27 | - NodeJS version (`node -v`)
28 | - NPM version (`npm -v`)
29 | - Package version (`npm ls @guildedjs/guilded.js`)
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: zaida04
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Please describe the changes this PR makes and why it should be merged:
2 |
3 | Status
4 | [] Code changes have been tested.
5 |
6 | Semantic versioning classification:
7 | [] This PR changes the library's interface (methods or parameters added)
8 | [] This PR includes breaking changes (methods removed or renamed, parameters moved or removed)
9 | [] This PR only includes non-code changes, like changes to documentation, README, etc.
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI workflows
2 | on: [push, pull_request]
3 | jobs:
4 | lint:
5 | name: ESLint
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout repository
9 | uses: actions/checkout@v2
10 |
11 | - name: Install Node v14
12 | uses: actions/setup-node@v1
13 | with:
14 | node-version: 14
15 |
16 | - name: Use node_modules cache
17 | uses: actions/cache@v2
18 | with:
19 | path: '**/node_modules'
20 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
21 |
22 | - name: Install Main Dependencies
23 | if: ${{ !steps.cache-restore.outputs.cache-hit }}
24 | run: npm i
25 |
26 | - name: Install Sub Dependencies
27 | run: npm run bootstrap
28 |
29 | - name: Run ESLint
30 | run: npm run lint
31 |
32 | typescript:
33 | name: TypeScript Build
34 | runs-on: ubuntu-latest
35 | steps:
36 | - name: Checkout repository
37 | uses: actions/checkout@v2
38 |
39 | - name: Install Node v14
40 | uses: actions/setup-node@v1
41 | with:
42 | node-version: 14
43 |
44 | - name: Use node_modules cache
45 | uses: actions/cache@v2
46 | with:
47 | path: '**/node_modules'
48 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
49 |
50 | - name: Install Main Dependencies
51 | if: ${{ !steps.cache-restore.outputs.cache-hit }}
52 | run: npm i
53 |
54 | - name: Install Sub Dependencies
55 | run: npm run bootstrap
56 |
57 | - name: Run TSC
58 | run: npm run build
59 |
60 | tests:
61 | name: Jest tests
62 | runs-on: ubuntu-latest
63 | steps:
64 | - name: Checkout repository
65 | uses: actions/checkout@v2
66 |
67 | - name: Install Node v14
68 | uses: actions/setup-node@v1
69 | with:
70 | node-version: 14
71 |
72 | - name: Use node_modules cache
73 | uses: actions/cache@v2
74 | with:
75 | path: '**/node_modules'
76 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
77 |
78 | - name: Install Main Dependencies
79 | if: ${{ !steps.cache-restore.outputs.cache-hit }}
80 | run: npm i
81 |
82 | - name: Install Sub Dependencies
83 | run: npm run bootstrap
84 |
85 | - name: Run TSC
86 | run: npm run build
87 |
88 | - name: Run Jest
89 | run: npm run test
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Docs
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | docs:
8 | name: Deploy Docs
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout repository
12 | uses: actions/checkout@v2
13 |
14 | - name: Install Node v14
15 | uses: actions/setup-node@v1
16 | with:
17 | node-version: 14
18 |
19 | - name: Install Main Dependencies
20 | run: npm i
21 |
22 | - name: Install Sub Dependencies
23 | run: npm run bootstrap
24 |
25 | - name: Run TypeScript compiler
26 | run: npm run build
27 |
28 | - name: Build the docs
29 | run: npm run docs
30 |
31 | - name: Commit the Docs
32 | uses: cpina/github-action-push-to-another-repository@main
33 | env:
34 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
35 | with:
36 | source-directory: "docs"
37 | destination-github-username: "github-actions[bot]"
38 | destination-repository-username: "zaida04"
39 | destination-repository-name: "guildedjs-selfbot-docs"
40 | target-branch: "master"
41 | user-email: 41898282+github-actions[bot]@users.noreply.github.com
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | types/
4 | coverage/
5 |
6 | .npmrc
7 | *.tsbuildinfo
8 | *.log
9 |
10 | *.config.json
11 | .vscode/
12 | .idea/
13 | *.env
14 | docs/
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx --no-install commitlint --edit "$1"
5 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run build && npx lint-staged
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Zaid - Nico
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 | > # 🚨 This library has been discontinued in favor of the bot API version, which can be found [here](https://github.com/guildedjs/guilded.js-next)
2 |
3 |
4 |

5 |
Tools for interacting with the Guilded.gg API.
6 |
7 |
8 |
9 |
10 | 
11 |
12 |
13 |
14 | ## 📝 About
15 |
16 | > ### ⚠️ This library only works with selfbots, which are a gray zone in Guilded. Use at your own risk.
17 |
18 | This repo serves as a monorepo that houses several packages, mainly the `@guildedjs/guilded.js` package, which is a library for the Guilded API. Inspired heavily by [discord.js](https://github.com/discordjs/discord.js)
19 |
20 | ## 📦 Packages
21 |
22 | - `@guildedjs/guilded.js` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded.js#readme), [NPM](https://www.npmjs.com/package/@guildedjs/guilded.js)**) - main package that provides a lib for the guilded.gg API. Comes with built in caching, structures, etc.
23 | - `@guildedjs/guilded-api-types` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded-api-typings#readme), [NPM](https://www.npmjs.com/package/@guildedjs/guilded-api-typings)**) - thinking of making your own guilded lib/wrapper? This package consists of typings for the guilded.gg API compiled together by the community. No need to write your own typings and reinvent the wheel.
24 | - `@guildedjs/rest` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/rest#readme), [NPM](https://www.npmjs.com/package/@guildedjs/rest)**) - Utility for making REST requests.
25 | - `@guildedjs/webhook-client` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/webhook-client#readme), [NPM](https://www.npmjs.com/package/@guildedjs/webhook-client)**) - Library-agnostic webhook client for interaction with guilded.gg API webhooks.
26 | - `@guildedjs/embeds` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/embeds#readme), [NPM](https://www.npmjs.com/package/@guildedjs/embeds)**) - Library-agnostic embed builder for sending messages with rich content through the guilded.gg API.
27 | - `@guildedjs/common` (**[GitHub](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/common#readme), [NPM](https://www.npmjs.com/package/@guildedjs/common)**) - Utilities and structures shared across various @guildedjs packages.
28 |
29 | ## 📥 Installation
30 |
31 |
32 |
33 | **Recommended that you use node v12+**
34 |
35 | - `npm install @guildedjs/guilded.js`
36 | - `yarn add @guildedjs/guilded.js`
37 |
38 | ## ⚡ Usage
39 |
40 | You can find extra examples [here](https://github.com/zaida04/guilded.js-selfbot/tree/main/examples)
41 |
42 | ```ts
43 | const { Client } = require("@guildedjs/guilded.js");
44 |
45 | /*
46 | * ES6:
47 | * import { Client } from "@guildedjs/guilded.js";
48 | */
49 |
50 | const client = new Client();
51 |
52 | client.on("ready", () => console.log(`Bot is successfully logged in`));
53 |
54 | client.on("messageCreate", (message) => {
55 | if (message.content === "poggers") {
56 | return message.channel.send("poggers indeed");
57 | }
58 | });
59 |
60 | client.login({
61 | email: "email",
62 | password: "password",
63 | });
64 | ```
65 |
66 | ## 📃 Documentation
67 |
68 | Documentation is viewable here: https://zaida04.github.io/guildedjs-selfbot-docs
69 |
70 |
71 |
72 | ## ✋ Contributing
73 |
74 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
75 |
76 | **Please run `npm run bootstrap` after running npm install in your local environment.**
77 | **Please ensure your commits pass the test, lint, and build scripts.**
78 |
79 | **We make use of [lerna](https://lerna.js.org/) to manage our monorepo. The main commands used are below**
80 |
81 | - `lerna add [--scope=package-name]` - add npm module dependency to all/specific package(s)
82 | - `lerna create ` - create a new package
83 | - `npm run bootstrap` = `lerna bootstrap` - recursively install dependencies in all packages and symlink local packages
84 | - `lerna run ` - recursively execute command in all packages (must exist in each packages package.json)
85 |
86 | ## 🤝 Acknowledgements
87 |
88 | [Discord.js](https://github.com/discordjs/discord.js) - Main inspiration & lots of derived work.
89 |
90 | ## ⚖️ LICENSING
91 |
92 | > **Guilded.JS** © [zaida04](https://github.com/zaida04). All packages released under [MIT](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE).
93 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | comments: true,
3 | parserOpts: { strictMode: true },
4 | plugins: ['babel-plugin-replace-ts-export-assignment', 'babel-plugin-const-enum'],
5 | presets: [
6 | [
7 | '@babel/preset-env',
8 | {
9 | modules: 'commonjs',
10 | targets: { node: 'current' },
11 | },
12 | ],
13 | '@babel/preset-typescript',
14 | ],
15 | sourceMaps: 'inline',
16 | };
17 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-angular'],
3 | rules: {
4 | 'scope-case': [2, 'always', 'pascal-case'],
5 | 'type-enum': [
6 | 2,
7 | 'always',
8 | ['chore', 'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'],
9 | ],
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Examples
2 | Examples for some common functionalities of this lib.
3 | These examples are tested to work on latest before being updated.
4 |
5 | **If you are using this as a drop in starting point for your project, please change the lib require from "../../../packages/guilded.js" to "@guildedjs/guilded.js" and run `npm install @guildedjs/guilded.js`**
6 |
7 | ## Support
8 | If you encounter a legitimate error, please open an issue.
9 | If you have a question, please use the [Discord Server](https://discord.gg/jf66UUN).
--------------------------------------------------------------------------------
/examples/command-handler/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/command-handler-example",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@discordjs/collection": {
8 | "version": "0.1.6",
9 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
10 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/examples/command-handler/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/command-handler-example",
3 | "version": "1.0.0",
4 | "description": "Example of a command handler using @guildedjs",
5 | "main": "src/index.js",
6 | "private": true,
7 | "dependencies": {
8 | "@discordjs/collection": "^0.1.6"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
13 | },
14 | "author": "Zaid \"Nico\"",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
18 | },
19 | "homepage": "https://github.com/zaida04/guilded.js-selfbot#readme"
20 | }
21 |
--------------------------------------------------------------------------------
/examples/command-handler/src/commands/embed.js:
--------------------------------------------------------------------------------
1 | const { Embed } = require('@guildedjs/guilded.js');
2 |
3 | module.exports = {
4 | execute: (msg, args) =>
5 | msg.channel.send(new Embed().setTitle('Test Embed!').setDescription(`Here are your args: ${args.join(', ')}`)),
6 | name: 'embed',
7 | };
8 |
--------------------------------------------------------------------------------
/examples/command-handler/src/commands/ping.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | aliases: ['ding'],
3 | execute: msg => msg.channel.send('pong!'),
4 | name: 'ping',
5 | };
6 |
--------------------------------------------------------------------------------
/examples/command-handler/src/index.js:
--------------------------------------------------------------------------------
1 | const Guilded = require('../../../packages/guilded.js');
2 | const Collection = require('@discordjs/collection');
3 | // function to construct paths to files
4 | const { join } = require('path');
5 | // we use fs/promises here for the promisifed versions of fs functions
6 | const { readdir } = require('fs/promises');
7 | const client = new Guilded.Client();
8 | const context = {
9 | commands: new Collection(),
10 | };
11 | const prefix = '!';
12 |
13 | client.on('ready', () => {
14 | console.log('Guilded Bot is ready!');
15 | });
16 |
17 | client.on('messageCreate', async msg => {
18 | if (!msg.content.startsWith(prefix)) return;
19 | let [commandName, ...args] = msg.content.slice(prefix.length).trim().split(/ +/);
20 | commandName = commandName.toLowerCase();
21 |
22 | const command = context.commands.get(commandName) ?? context.commands.find(x => x.aliases?.includes(commandName));
23 | if (!command) return;
24 |
25 | try {
26 | await command.execute(msg, args);
27 | } catch (e) {
28 | msg.channel.send('There was an error executing that command!');
29 | void console.error(e);
30 | }
31 | });
32 |
33 | (async () => {
34 | // read the commands dir and have the file extensions.
35 | const commandDir = await readdir(join(__dirname, 'commands'), { withFileTypes: true });
36 |
37 | // go through all the files/dirs scanned from the readdir, and make sure we only have js files
38 | for (const file of commandDir.filter(x => x.name.endsWith('.js'))) {
39 | const command = require(join(__dirname, 'commands', file.name));
40 | context.commands.set(command.name, command);
41 | }
42 |
43 | client.login({
44 | email: process.env.EMAIL,
45 | password: process.env.PASSWORD,
46 | });
47 | })();
48 |
--------------------------------------------------------------------------------
/examples/getting-started/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/getting-started-example",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1
5 | }
6 |
--------------------------------------------------------------------------------
/examples/getting-started/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/getting-started-example",
3 | "version": "1.0.0",
4 | "description": "Getting started example for the @guildedjs/guilded.js",
5 | "main": "src/index.js",
6 | "private": true,
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
10 | },
11 | "author": "Zaid \"Nico\"",
12 | "license": "MIT",
13 | "bugs": {
14 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
15 | },
16 | "homepage": "https://github.com/zaida04/guilded.js-selfbot#readme"
17 | }
18 |
--------------------------------------------------------------------------------
/examples/getting-started/src/index.js:
--------------------------------------------------------------------------------
1 | // if you are not running this code in the examples directory, please run npm install @guildedjs/guilded.js and swap below.
2 | const Guilded = require('../../../packages/guilded.js');
3 | const client = new Guilded.Client();
4 | const prefix = '!';
5 |
6 | // log to the console when the bot is "ready"
7 | client.on('ready', () => {
8 | console.log('Guilded Bot is ready!');
9 | });
10 |
11 | // on every message sent that your account can see in guilded (including your own), run the callback function provided.
12 | client.on('messageCreate', msg => {
13 | // if the message doesn't start with our prefix, we want to discard this message
14 | if (!msg.content.startsWith(prefix)) return;
15 | // we first slice off the prefix from the message content, get rid of spaces at the beginning and end of the message
16 | // and then split the string into an array based on every space in the message
17 | // we then destructure the returned array because we know the first element will always be the command name, and the rest are args
18 | const [commandName, ...args] = msg.content.slice(botConfig.GLOBAL_PREFIX.length).trim().split(/ +/);
19 |
20 | switch (commandName) {
21 | case 'hi': {
22 | return msg.channel.send('Hello!');
23 | }
24 | case 'ping': {
25 | return msg.channel.send('Pong');
26 | }
27 | case 'say': {
28 | return msg.channel.send(args.join(' '));
29 | }
30 | case 'embed': {
31 | return msg.channel.send(
32 | new Guilded.Embed()
33 | .setTitle('Test Embed')
34 | .setDescription('Test Description')
35 | .setTimestamp()
36 | .setURL('https://google.com')
37 | .setFooter('Test Footer'),
38 | );
39 | }
40 | }
41 | });
42 |
43 | client.login({
44 | email: process.env.EMAIL,
45 | password: process.env.PASSWORD,
46 | });
47 |
--------------------------------------------------------------------------------
/examples/reactions/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/getting-started-example",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1
5 | }
6 |
--------------------------------------------------------------------------------
/examples/reactions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/reactions-example",
3 | "version": "1.0.0",
4 | "description": "Getting started example for the @guildedjs/guilded.js",
5 | "main": "src/index.js",
6 | "private": true,
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
10 | },
11 | "author": "Zaid \"Nico\"",
12 | "license": "MIT",
13 | "bugs": {
14 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
15 | },
16 | "homepage": "https://github.com/zaida04/guilded.js-selfbot#readme"
17 | }
18 |
--------------------------------------------------------------------------------
/examples/reactions/src/index.js:
--------------------------------------------------------------------------------
1 | const Guilded = require('../../../packages/guilded.js');
2 | const client = new Guilded.Client({
3 | // without this, we would only receive events involving cached messages, so reactions on messages that were sent
4 | // before the bot was logged in would not be counted.
5 | partials: ['MESSAGE', 'CHANNEL'],
6 | });
7 |
8 | // log to the console when the bot is "ready"
9 | client.on('ready', () => {
10 | console.log('Guilded Bot is ready!');
11 | });
12 |
13 | client.on('messageReactionAdd', (reaction, userOrId) =>
14 | console.log(`${userOrId?.name ?? userOrId} just reacted with ${reaction.id}`),
15 | );
16 | client.on('messageReactionDelete', (reactionOrId, userOrId) =>
17 | // we use optional chaining here to tell whether it's a user object or an user ID
18 | // we also use optional chaining here to tell whether it's a reaction object or a reaction ID.
19 | console.log(`${userOrId?.name ?? userOrId} just removed their reaction ${reactionOrId?.id ?? reactionOrId}`),
20 | );
21 |
22 | client.login({
23 | email: process.env.EMAIL,
24 | password: process.env.PASSWORD,
25 | });
26 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('@jest/types').Config.InitialOptions} */
2 | module.exports = {
3 | collectCoverage: true,
4 | coverageDirectory: 'coverage',
5 | coveragePathIgnorePatterns: ['dist/'],
6 | coveragePathIgnorePatterns: ['/node_modules/', '/packages/rest'],
7 | coverageReporters: ['text', 'lcov', 'clover'],
8 | coverageThreshold: {
9 | global: {
10 | branches: 80,
11 | functions: 80,
12 | lines: 80,
13 | statements: 80,
14 | },
15 | },
16 | roots: ['/packages'],
17 | setupFilesAfterEnv: ['/scripts/jest.js', 'dotenv/config'],
18 | testEnvironment: 'node',
19 | testMatch: ['**/__tests__/**/*.test.ts'],
20 | };
21 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "command": {
3 | "publish": {
4 | "message": "chore: release"
5 | }
6 | },
7 | "publishConfig": {
8 | "access": "public"
9 | },
10 | "packages": [
11 | "packages/*"
12 | ],
13 | "version": "independent"
14 | }
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '*.{js,ts}': 'eslint --fix --ext ts,js',
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/main",
3 | "version": "0.0.0",
4 | "description": "Main overarching package utilizing lerna to manage all the @guildedjs packages",
5 | "private": true,
6 | "author": "Zaid \"Nico\"",
7 | "license": "MIT",
8 | "scripts": {
9 | "build": "npx lerna run build",
10 | "bootstrap": "npx lerna bootstrap",
11 | "lint": "npx eslint packages/ scripts/ --ext .ts,.js",
12 | "lint:fix": "npm run lint -- --fix",
13 | "docs": "npx rimraf docs && npx typedoc --options typedoc.config.js packages && node scripts/post-docs.js",
14 | "test": "npx jest",
15 | "test:build": "npm run build && npx jest",
16 | "prepublishOnly": "npm run lint && npx lerna run prepublishOnly",
17 | "prepare": "husky install",
18 | "changelog": "npx conventional-changelog -p angular -i CHANGELOG.md -s",
19 | "reset": "cd scripts && node refresh.js"
20 | },
21 | "devDependencies": {
22 | "@babel/core": "^7.12.17",
23 | "@babel/generator": "^7.13.0",
24 | "@babel/preset-env": "^7.12.17",
25 | "@babel/preset-typescript": "^7.12.17",
26 | "@commitlint/cli": "^11.0.0",
27 | "@commitlint/config-angular": "^11.0.0",
28 | "@strictsoftware/typedoc-plugin-monorepo": "^0.3.1",
29 | "@types/jest": "^26.0.24",
30 | "@typescript-eslint/eslint-plugin": "^3.9.0",
31 | "@typescript-eslint/parser": "^3.9.0",
32 | "babel-jest": "^26.6.3",
33 | "babel-plugin-const-enum": "^1.0.1",
34 | "babel-plugin-replace-ts-export-assignment": "^0.0.2",
35 | "conventional-changelog-cli": "^2.1.1",
36 | "dotenv": "^8.2.0",
37 | "eslint": "^7.6.0",
38 | "eslint-config-prettier": "^6.11.0",
39 | "eslint-plugin-prettier": "^3.1.4",
40 | "eslint-plugin-simple-import-sort": "^5.0.3",
41 | "eslint-plugin-sort-keys-fix": "^1.1.1",
42 | "husky": "^6.0.0",
43 | "jest": "^27.0.6",
44 | "lerna": "^3.22.1",
45 | "lint-staged": "^10.4.2",
46 | "prettier": "^2.0.5",
47 | "rimraf": "^3.0.2",
48 | "typedoc": "^0.19.2",
49 | "typedoc-plugin-remove-references": "0.0.5",
50 | "typescript": "^4.0.5"
51 | },
52 | "repository": {
53 | "type": "git",
54 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
55 | },
56 | "bugs": {
57 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
58 | },
59 | "homepage": "https://github.com/zaida04/guilded.js-selfbot#readme"
60 | }
61 |
--------------------------------------------------------------------------------
/packages/common/README.md:
--------------------------------------------------------------------------------
1 | # `@guildedjs/common`
2 |
3 | [](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
4 | [](https://www.npmjs.com/package/@guildedjs/common)
5 | [](https://github.com/zaida04/guilded.js-selfbot/actions/workflows/ci.yml)
6 |
7 | Common structures and utilities used in various @guildedjs packages
8 |
9 | > ⚠️ If you intend to use `@guildedjs/guilded.js` you won't need to install this, as it's already a dependency of that package.
10 |
11 | ## Installation
12 |
13 | You can install this package from [NPM](https://www.npmjs.com/package/@guildedjs/common)
14 |
15 | - `npm install @guildedjs/common`
16 | - `yarn add @guildedjs/common`
17 |
18 | ## Contributing
19 |
20 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
21 |
22 | ## Credits
23 |
24 | Concept and structure dervied from https://github.com/discordjs/discord.js/blob/stable/src/structures/MessageEmbed.js#L9 - [Discord.js](https://github.com/discordjs/discord.js) ([License](https://github.com/discordjs/discord.js/blob/stable/LICENSE))
25 |
26 | ## LICENSE
27 |
28 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
29 |
--------------------------------------------------------------------------------
/packages/common/__tests__/CacheCollection.test.ts:
--------------------------------------------------------------------------------
1 | import { CacheCollection } from '..';
2 | const zeroOrNegativeErrorMessage = 'Cannot pass 0 or negative value as maxSize.';
3 |
4 | test('Successful construction with default cache maxSize', () => {
5 | expect(new CacheCollection().maxSize).toStrictEqual(Infinity);
6 | expect(() => new CacheCollection({ maxSize: undefined })).not.toThrow();
7 | });
8 |
9 | test('Abiding by cache maxSize', () => {
10 | const cache = new CacheCollection({ maxSize: 500 });
11 | for (let i = 0; i < 505; i++) {
12 | cache.set(`test-${i}`, i);
13 | }
14 | expect(cache.size).toStrictEqual(500);
15 | });
16 |
17 | test('Properly error on invalid maxSize being passed', () => {
18 | expect(() => new CacheCollection({ maxSize: 0 })).toThrow(new TypeError(zeroOrNegativeErrorMessage));
19 | expect(() => new CacheCollection({ maxSize: -1 })).toThrow(new TypeError(zeroOrNegativeErrorMessage));
20 | });
21 |
--------------------------------------------------------------------------------
/packages/common/__tests__/MessageUtil.test.ts:
--------------------------------------------------------------------------------
1 | import { generateMessage, parseMessage, parseToMessage } from '..';
2 | import { Embed } from '../../embeds';
3 | import data from './MessageUtil.test.data.json';
4 |
5 | const testingMessage1 = 'TESTING MESSAGE' as const;
6 | const testingMessage2 = 'TESTING MESSAGE 2' as const;
7 | const testingMessage3 = 'TESTING MESSAGE 3' as const;
8 |
9 | // taken from https://stackoverflow.com/a/13653180, show them some love.
10 | const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
11 |
12 | test('convert plain-text content to proper message format', () => {
13 | expect(parseToMessage(testingMessage1)).toStrictEqual(data['plain-message']);
14 | });
15 | test('convert embed content to proper message format', () => {
16 | expect(parseToMessage(new Embed().setTitle(testingMessage1))).toEqual(data['embed-message']);
17 | });
18 | test('convert both plain-text and embed content to proper message format', () => {
19 | expect(parseToMessage(testingMessage2, new Embed().setTitle(testingMessage3))).toEqual(data['mixed-message']);
20 | });
21 | test('generate valid sendable plain-text message structure', () => {
22 | const [id, message] = generateMessage(testingMessage1);
23 | expect(id).toMatch(UUID_REGEX);
24 | expect(message.content).toStrictEqual(data['plain-message']);
25 | });
26 | test('generate valid sendable embed message structure', () => {
27 | const [id, message] = generateMessage(new Embed().setTitle(testingMessage1));
28 | expect(id).toMatch(UUID_REGEX);
29 | expect(message.content).toEqual(data['embed-message']);
30 | });
31 | test('generate valid sendable embed and plain-text message structure', () => {
32 | const [id, message] = generateMessage(testingMessage2, new Embed().setTitle(testingMessage3));
33 | expect(id).toMatch(UUID_REGEX);
34 | expect(message.content).toEqual(data['mixed-message']);
35 | });
36 |
37 | test('parse regular message', () => {
38 | expect(parseMessage(data['plain-message'])).toStrictEqual({
39 | embeds: [],
40 | mentions: {
41 | channels: [],
42 | reactions: [],
43 | roles: [],
44 | users: [],
45 | },
46 | parsedArr: [{ content: 'TESTING MESSAGE', type: 'text' }],
47 | parsedText: 'TESTING MESSAGE',
48 | });
49 | });
50 |
51 | test('parse embed message', () => {
52 | expect(parseMessage(data['embed-message'])).toStrictEqual({
53 | embeds: [
54 | {
55 | fields: [],
56 | title: 'TESTING MESSAGE',
57 | },
58 | ],
59 | mentions: {
60 | channels: [],
61 | reactions: [],
62 | roles: [],
63 | users: [],
64 | },
65 | parsedArr: [],
66 | parsedText: '',
67 | });
68 | });
69 |
70 | test('parse multi-line message', () => {
71 | expect(parseMessage(data['multi-line'])).toStrictEqual({
72 | embeds: [],
73 | mentions: {
74 | channels: [],
75 | reactions: [],
76 | roles: [],
77 | users: [],
78 | },
79 | parsedArr: [
80 | { content: 'MULTILINE', type: 'text' },
81 | { content: 'STRING', type: 'text' },
82 | { content: 'TEST', type: 'text' },
83 | ],
84 | parsedText: 'MULTILINE\nSTRING\nTEST',
85 | });
86 | });
87 |
88 | test('parse message with user mentions', () => {
89 | expect(parseMessage(data['user-mention'])).toStrictEqual({
90 | embeds: [],
91 | mentions: {
92 | channels: [],
93 | reactions: [],
94 | roles: [],
95 | users: ['user-id'],
96 | },
97 | parsedArr: [
98 | {
99 | content: '@nico',
100 | mention: {
101 | avatar: data.avatarURL,
102 | color: '#ececee',
103 | id: 'user-id',
104 | matcher: '@nico',
105 | name: 'nico',
106 | nickname: false,
107 | type: 'person',
108 | },
109 | type: 'user',
110 | },
111 | { content: ' testing testing!', type: 'text' },
112 | ],
113 | parsedText: '@nico testing testing!',
114 | });
115 | });
116 | test('parse message with role mentions', () => {
117 | expect(parseMessage(data['role-mention'])).toStrictEqual({
118 | embeds: [],
119 | mentions: {
120 | channels: [],
121 | reactions: [],
122 | roles: ['10000000'],
123 | users: [],
124 | },
125 | parsedArr: [
126 | {
127 | content: '@Captain',
128 | mention: {
129 | color: '#d9acff',
130 | id: 10000000,
131 | matcher: '@captain',
132 | name: 'Captain',
133 | type: 'role',
134 | },
135 | type: 'role',
136 | },
137 | { content: ' testing testing 3!', type: 'text' },
138 | ],
139 | parsedText: '@Captain testing testing 3!',
140 | });
141 | });
142 | test('parse message with channel mentions', () => {
143 | expect(parseMessage(data['channel-mention'])).toStrictEqual({
144 | embeds: [],
145 | mentions: {
146 | channels: ['channel-id'],
147 | reactions: [],
148 | roles: [],
149 | users: [],
150 | },
151 | parsedArr: [
152 | {
153 | channel: {
154 | id: 'channel-id',
155 | matcher: '#testing',
156 | name: 'testing',
157 | },
158 | content: '#testing',
159 | type: 'channel',
160 | },
161 | { content: ' testing testing!', type: 'text' },
162 | ],
163 | parsedText: '#testing testing testing!',
164 | });
165 | });
166 | test('parse message with mixed mentions', () => {});
167 |
--------------------------------------------------------------------------------
/packages/common/lib/CacheCollection.ts:
--------------------------------------------------------------------------------
1 | import Collection from '@discordjs/collection';
2 |
3 | /**
4 | * A collection with a max cap size, which will remove a random element
5 | */
6 | export class CacheCollection extends Collection {
7 | public maxSize: number;
8 |
9 | public constructor(options?: CacheCollectionOptions, entries?: readonly (readonly [K, V])[] | null | undefined) {
10 | super(entries);
11 | if (options?.maxSize !== undefined && options.maxSize < 1) {
12 | throw new TypeError('Cannot pass 0 or negative value as maxSize.');
13 | }
14 | this.maxSize = options?.maxSize ?? Infinity;
15 | }
16 |
17 | public set(...args: Parameters): this {
18 | if (this.size >= this.maxSize) this.delete(this.firstKey()!);
19 | return super.set(...args);
20 | }
21 | }
22 |
23 | export interface CacheCollectionOptions {
24 | maxSize?: number;
25 | }
26 |
--------------------------------------------------------------------------------
/packages/common/lib/UUID.ts:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 | export { v4 as generateUUID } from 'uuid';
3 |
--------------------------------------------------------------------------------
/packages/common/lib/index.ts:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 | export * from './MessageUtil';
3 | export * from './util';
4 | export * from './CacheCollection';
5 | export * from './UUID';
6 |
--------------------------------------------------------------------------------
/packages/common/lib/util.ts:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 |
3 | export enum IMG_EXTENSION {
4 | PNG = 'png',
5 | GIF = 'gif',
6 | WEBP = 'webp',
7 | }
8 |
9 | export type IMG_SIZE = 'Small' | 'Medium' | 'Large';
10 |
11 | const formAssetURL = (
12 | route: string,
13 | hash: string,
14 | extension: string,
15 | width?: number,
16 | height?: number,
17 | size?: string,
18 | ) => {
19 | const url = new URL(`https://${ROUTES.IMAGE_CDN_DOMAIN}/${route}/${hash}-${size}.${extension.toLowerCase()}`);
20 | if (width) url.searchParams.append('w', width.toString());
21 | if (height) url.searchParams.append('h', height.toString());
22 | return url.toString();
23 | };
24 |
25 | export const ROUTES = {
26 | ASSETS: {
27 | AVATAR_URL: (hash: string, size: IMG_SIZE = 'Medium'): string =>
28 | formAssetURL('UserAvatar', hash, IMG_EXTENSION.PNG, undefined, undefined, size),
29 | IMAGE_IN_CHAT: (hash: string, size = 'Full', width?: number, height?: number): string =>
30 | formAssetURL('ContentMedia', hash, IMG_EXTENSION.WEBP, width, height, size),
31 | PROFILE_BANNER: (hash: string, size = 'Hero', width?: number, height?: number): string =>
32 | formAssetURL('UserBanner', hash, IMG_EXTENSION.PNG, width, height, size),
33 | TEAM_BANNER: (hash: string, size = 'Hero', width?: number, height?: number): string =>
34 | formAssetURL('TeamBanner', hash, IMG_EXTENSION.PNG, width, height, size),
35 | TEAM_EMOJI: (
36 | hash: string,
37 | size = 'Full',
38 | extension: 'WEBP' | 'APNG' = 'WEBP',
39 | width?: number,
40 | height?: number,
41 | ): string => formAssetURL('CustomReaction', hash, extension.toLowerCase(), width, height, size),
42 | TEAM_ICON: (hash: string, size: 'Small' | 'Medium' | 'Large' = 'Medium'): string =>
43 | formAssetURL('TeamAvatar', hash, IMG_EXTENSION.PNG, undefined, undefined, size),
44 | },
45 | AWS_CDN: 'https://s3-us-west-2.amazonaws.com/www.guilded.gg/' as const,
46 | BASE_DOMAIN: 'api.guilded.gg' as const,
47 | CDN: 'img.guildedcdn.com' as const,
48 | IMAGE_CDN_DOMAIN: 'img.guildedcdn.com' as const,
49 | MEDIA_DOMAIN: 'media.guilded.gg' as const,
50 | };
51 |
--------------------------------------------------------------------------------
/packages/common/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/common",
3 | "version": "1.0.5-selfbot",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@guildedjs/common",
9 | "version": "1.0.3-selfbot",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@discordjs/collection": "^0.1.6",
13 | "uuid": "^8.3.2"
14 | },
15 | "devDependencies": {
16 | "@guildedjs/guilded-api-typings": "^1.3.1",
17 | "@types/uuid": "^8.3.0",
18 | "typescript": "^4.4.2"
19 | }
20 | },
21 | "node_modules/@discordjs/collection": {
22 | "version": "0.1.6",
23 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
24 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ=="
25 | },
26 | "node_modules/@guildedjs/guilded-api-typings": {
27 | "version": "1.3.1",
28 | "resolved": "https://registry.npmjs.org/@guildedjs/guilded-api-typings/-/guilded-api-typings-1.3.1.tgz",
29 | "integrity": "sha512-deoCfmBpnltL3G5nwxFKKdn+tyq7YfB/0VKoXE8vx3XrjrRWuipXnlXsDs4CtrwVdhmrflQCXQG3TtQf0Bv5LQ==",
30 | "dev": true
31 | },
32 | "node_modules/@types/uuid": {
33 | "version": "8.3.0",
34 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
35 | "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
36 | "dev": true
37 | },
38 | "node_modules/typescript": {
39 | "version": "4.4.2",
40 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
41 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
42 | "dev": true,
43 | "bin": {
44 | "tsc": "bin/tsc",
45 | "tsserver": "bin/tsserver"
46 | },
47 | "engines": {
48 | "node": ">=4.2.0"
49 | }
50 | },
51 | "node_modules/uuid": {
52 | "version": "8.3.2",
53 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
54 | "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
55 | "bin": {
56 | "uuid": "dist/bin/uuid"
57 | }
58 | }
59 | },
60 | "dependencies": {
61 | "@discordjs/collection": {
62 | "version": "0.1.6",
63 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
64 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ=="
65 | },
66 | "@guildedjs/guilded-api-typings": {
67 | "version": "1.3.1",
68 | "resolved": "https://registry.npmjs.org/@guildedjs/guilded-api-typings/-/guilded-api-typings-1.3.1.tgz",
69 | "integrity": "sha512-deoCfmBpnltL3G5nwxFKKdn+tyq7YfB/0VKoXE8vx3XrjrRWuipXnlXsDs4CtrwVdhmrflQCXQG3TtQf0Bv5LQ==",
70 | "dev": true
71 | },
72 | "@types/uuid": {
73 | "version": "8.3.0",
74 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
75 | "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
76 | "dev": true
77 | },
78 | "typescript": {
79 | "version": "4.4.2",
80 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
81 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
82 | "dev": true
83 | },
84 | "uuid": {
85 | "version": "8.3.2",
86 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
87 | "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/packages/common/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/common",
3 | "version": "1.0.5-selfbot",
4 | "description": "Common structures and utilities used in various @guildedjs packages",
5 | "author": "Zaid \"Nico\" ",
6 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/common#readme",
7 | "license": "MIT",
8 | "types": "types/index.d.ts",
9 | "main": "dist/index.js",
10 | "scripts": {
11 | "test": "npm run build && node ./__tests__/index.js",
12 | "build": "tsc",
13 | "prepublishOnly": "npx rimraf dist/ && npx rimraf types/ && npm run build"
14 | },
15 | "devDependencies": {
16 | "@guildedjs/guilded-api-typings": "^1.3.1",
17 | "@types/uuid": "^8.3.0",
18 | "typescript": "^4.4.2"
19 | },
20 | "dependencies": {
21 | "@discordjs/collection": "^0.1.6",
22 | "@guildedjs/embeds": "^1.0.5-selfbot",
23 | "uuid": "^8.3.2"
24 | },
25 | "keywords": [
26 | "guilded-gg",
27 | "guilded-api",
28 | "guilded-webhook"
29 | ],
30 | "directories": {
31 | "lib": "lib",
32 | "test": "__tests__"
33 | },
34 | "files": [
35 | "dist",
36 | "types"
37 | ],
38 | "publishConfig": {
39 | "access": "public"
40 | },
41 | "repository": {
42 | "type": "git",
43 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
44 | },
45 | "bugs": {
46 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
47 | },
48 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/common/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declarationDir": "./types"
6 | },
7 | "include": [ "./lib/**/*.ts" ],
8 | "exclude": [ "*.test.ts"]
9 | }
--------------------------------------------------------------------------------
/packages/embeds/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Zaid - Nico
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.
--------------------------------------------------------------------------------
/packages/embeds/README.md:
--------------------------------------------------------------------------------
1 | # `@guildedjs/embeds`
2 |
3 | [](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
4 | [](https://www.npmjs.com/package/@guildedjs/embeds)
5 | [](https://github.com/zaida04/guilded.js-selfbot/actions/workflows/ci.yml)
6 |
7 | Library-agnostic embed builder utility for the guilded.gg API
8 |
9 | > ⚠️ If you intend to use `@guildedjs/guilded.js` you won't need to install this, as it's already a dependency of that package.
10 |
11 | ## Installation
12 |
13 | You can install this package from [NPM](https://www.npmjs.com/package/@guildedjs/embeds)
14 |
15 | - `npm install @guildedjs/embeds`
16 | - `yarn add @guildedjs/embeds`
17 |
18 | ## Contributing
19 |
20 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
21 |
22 | ## Credits
23 |
24 | Concept and structure dervied from https://github.com/discordjs/discord.js/blob/stable/src/structures/MessageEmbed.js#L9 - [Discord.js](https://github.com/discordjs/discord.js) ([License](https://github.com/discordjs/discord.js/blob/stable/LICENSE))
25 |
26 | ## LICENSE
27 |
28 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
29 |
--------------------------------------------------------------------------------
/packages/embeds/__tests__/util.test.ts:
--------------------------------------------------------------------------------
1 | import { resolveColor } from '..';
2 |
3 | test('parse Hexadecimal string', () => {
4 | expect(resolveColor('#f5c400')).toStrictEqual(0xf5c400);
5 | });
6 | test('parse Color string', () => {
7 | expect(resolveColor('GUILDED')).toStrictEqual(0xf5c400);
8 | });
9 | test('parse RGB value', () => {
10 | expect(resolveColor([245, 196, 0])).toStrictEqual(0xf5c400);
11 | });
12 | test('test RANDOM value', () => {
13 | expect(typeof resolveColor('RANDOM')).toEqual('number');
14 | });
15 | test('Get error on out of range number', () => {
16 | expect(() => resolveColor(0xfffffff)).toThrow(new RangeError('COLOR_RANGE'));
17 | });
18 | test('Get error on bad string input', () => {
19 | expect(() => resolveColor('SIUDFHUISDHFIUHSDUDIFHIUSDHFUISDI')).toThrow(new TypeError('COLOR_CONVERT'));
20 | });
21 |
--------------------------------------------------------------------------------
/packages/embeds/lib/consts.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2015 - 2021 Amish Shah
3 | * Copyrights licensed under the Apache License 2.0, https://github.com/discordjs/discord.js/blob/master/LICENSE
4 | * Taken from https://github.com/discordjs/discord.js/blob/stable/src/util/Constants.js
5 | */
6 | export const COLORS: { [key: string]: number } = {
7 | AQUA: 0x1abc9c,
8 | BLUE: 0x3498db,
9 | DARKER_GREY: 0x7f8c8d,
10 | DARK_AQUA: 0x11806a,
11 | DARK_BLUE: 0x206694,
12 | DARK_BUT_NOT_BLACK: 0x2c2f33,
13 | DARK_GOLD: 0xc27c0e,
14 | DARK_GREEN: 0x1f8b4c,
15 | DARK_GREY: 0x979c9f,
16 | DARK_NAVY: 0x2c3e50,
17 | DARK_ORANGE: 0xa84300,
18 | DARK_PURPLE: 0x71368a,
19 | DARK_RED: 0x992d22,
20 | DARK_VIVID_PINK: 0xad1457,
21 | DEFAULT: 0x000000,
22 | GOLD: 0xf1c40f,
23 | GREEN: 0x2ecc71,
24 | GREY: 0x95a5a6,
25 | GREYPLE: 0x99aab5,
26 | GUILDED: 0xf5c400,
27 | LIGHT_GREY: 0xbcc0c0,
28 | LUMINOUS_VIVID_PINK: 0xe91e63,
29 | NAVY: 0x34495e,
30 | NOT_QUITE_BLACK: 0x23272a,
31 | ORANGE: 0xe67e22,
32 | PURPLE: 0x9b59b6,
33 | RED: 0xe74c3c,
34 | WHITE: 0xffffff,
35 | YELLOW: 0xffff00,
36 | } as const;
37 |
--------------------------------------------------------------------------------
/packages/embeds/lib/index.ts:
--------------------------------------------------------------------------------
1 | import { Embed } from './Embed';
2 | export * from './util';
3 | export { Embed };
4 | export default Embed;
5 |
--------------------------------------------------------------------------------
/packages/embeds/lib/util.ts:
--------------------------------------------------------------------------------
1 | import { COLORS } from './consts';
2 |
3 | /**
4 | * Copyright 2015 - 2021 Amish Shah
5 | * Copyrights licensed under the Apache License 2.0, https://github.com/discordjs/discord.js/blob/master/LICENSE
6 | * Taken from https://github.com/discordjs/discord.js/blob/stable/src/util/Util.js#L436
7 | */
8 | export function resolveColor(color: string | number | [number, number, number]): number {
9 | if (typeof color === 'string') {
10 | if (color === 'RANDOM') return Math.floor(Math.random() * (0xffffff + 1));
11 | color = COLORS[color.toUpperCase()] ?? parseInt(color.replace('#', ''), 16);
12 | } else if (Array.isArray(color)) {
13 | color = (color[0] << 16) + (color[1] << 8) + color[2];
14 | }
15 |
16 | if (color < 0 || color > 0xffffff) throw new RangeError('COLOR_RANGE');
17 | else if (isNaN(color)) throw new TypeError('COLOR_CONVERT');
18 |
19 | return color;
20 | }
21 |
--------------------------------------------------------------------------------
/packages/embeds/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/embeds",
3 | "version": "1.0.5-selfbot",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@guildedjs/embeds",
9 | "version": "1.0.3-selfbot",
10 | "license": "MIT",
11 | "devDependencies": {
12 | "typescript": "^4.4.2"
13 | }
14 | },
15 | "node_modules/typescript": {
16 | "version": "4.4.2",
17 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
18 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
19 | "dev": true,
20 | "bin": {
21 | "tsc": "bin/tsc",
22 | "tsserver": "bin/tsserver"
23 | },
24 | "engines": {
25 | "node": ">=4.2.0"
26 | }
27 | }
28 | },
29 | "dependencies": {
30 | "typescript": {
31 | "version": "4.4.2",
32 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
33 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
34 | "dev": true
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/embeds/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/embeds",
3 | "version": "1.0.5-selfbot",
4 | "description": "Library-agnostic guilded embed builder utility for the guilded.gg API",
5 | "author": "Zaid \"Nico\" ",
6 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/embeds#readme",
7 | "license": "MIT",
8 | "types": "types/index.d.ts",
9 | "main": "dist/index.js",
10 | "scripts": {
11 | "test": "npm run build && node ./__tests__/index.js",
12 | "build": "tsc",
13 | "prepublishOnly": "npx rimraf dist/ && npx rimraf types/ && npm run build"
14 | },
15 | "devDependencies": {
16 | "@guildedjs/guilded-api-typings": "^1.4.1-selfbot",
17 | "typescript": "^4.4.2"
18 | },
19 | "keywords": [
20 | "guilded-gg",
21 | "guilded-api",
22 | "guilded-embed",
23 | "embed"
24 | ],
25 | "directories": {
26 | "lib": "lib",
27 | "test": "__tests__"
28 | },
29 | "files": [
30 | "dist",
31 | "types"
32 | ],
33 | "publishConfig": {
34 | "access": "public"
35 | },
36 | "repository": {
37 | "type": "git",
38 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
39 | },
40 | "bugs": {
41 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
42 | },
43 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
44 | }
45 |
--------------------------------------------------------------------------------
/packages/embeds/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declarationDir": "./types"
6 | },
7 | "include": [ "./lib/**/*.ts" ],
8 | "exclude": [ "*.test.ts"]
9 | }
--------------------------------------------------------------------------------
/packages/guilded-api-typings/README.md:
--------------------------------------------------------------------------------
1 | # `@guildedjs/guilded-api-typings`
2 |
3 | [](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
4 | [](https://www.npmjs.com/package/@guildedjs/guilded-api-typings)
5 | [](https://github.com/zaida04/guilded.js-selfbot/actions/workflows/ci.yml)
6 |
7 | TypeScript Typings for the Guilded.gg API.
8 |
9 | > ⚠️ If you intend to use `@guildedjs/guilded.js` you won't need to install this, as it's already a dependency of that package.
10 |
11 | ## Installation
12 |
13 | You can install this package from [NPM](https://www.npmjs.com/package/@guildedjs/guilded-api-typings)
14 |
15 | - `npm install @guildedjs/guilded-api-typings`
16 | - `yarn add @guildedjs/guilded-api-typings`
17 |
18 | ## Structure
19 |
20 | - `lib/rest` - Response from REST reqs to the API. Typings here are prefixed with `API`, then the `HTTP METHOD` that the request uses, then the request title. So for example `APIGetAPIChannels`, `APIGetChannelMessage`. If the request contains a body or query, the typings will have either `Result`, `Body`, or `Query` appended to the end of the typing name. E.x. `APIPostChannelMessagesBody`, `APIPostChannelMessagesResult`. `Body` is the body of the request you send, while `Result` is the response you get back from the API, and `Query` is the URL queries that you will put into the URL.
21 | - `lib/ws` - Payloads from the WS Gateway. Typings here are prefixed with `WS`.
22 | - `lib/common` - Common structures that may be sent by either WS or REST. Typings here are prefixed with `API`.
23 |
24 | ## Contributing
25 |
26 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
27 |
28 | ## Credits
29 |
30 | Huge thank you to [Shay](https://github.com/shayypy) and the rest of the [Unofficial GuildedAPI Team](https://github.com/GuildedAPI). The third rewrite of these API typings were based entirely on https://guildedapi.com/, which they built.
31 |
32 | Thank you to [Vlad](https://github.com/vladfrangu) and the rest of the contributors at https://github.com/discordjs/discord-api-types for the structure in which I based my typings structure on.
33 |
34 | ## LICENSE
35 |
36 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
37 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/Content.ts:
--------------------------------------------------------------------------------
1 | import { APIDocument } from './Document';
2 |
3 | export interface APIContent {
4 | object: string;
5 | document: APIDocument;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/Document.ts:
--------------------------------------------------------------------------------
1 | import { APILeaf } from './Plant';
2 |
3 | export interface APIDocument {
4 | data: unknown;
5 | nodes: APIDocumentNode[];
6 | object: string;
7 | }
8 |
9 | export interface APIDocumentNode {
10 | data: unknown;
11 | type: string;
12 | nodes: APINestedNode[];
13 | object: string;
14 | }
15 |
16 | export interface APINestedNode {
17 | leaves?: APILeaf[];
18 | object: string;
19 | data?: unknown;
20 | type?: string;
21 | nodes?: APINestedNode[];
22 | }
23 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/Plant.ts:
--------------------------------------------------------------------------------
1 | export interface APILeaf {
2 | text: string;
3 | marks: APIMark[];
4 | object: 'leaf' | string;
5 | }
6 |
7 | export interface APIMark {
8 | data: unknown;
9 | type: string;
10 | object: string;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/index.ts:
--------------------------------------------------------------------------------
1 | // API Structures
2 | export * from './structures';
3 |
4 | // Weird API Structures
5 | export * from './Content';
6 | export * from './Document';
7 | export * from './Plant';
8 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/Channel.ts:
--------------------------------------------------------------------------------
1 | import { APIContent } from '../Content';
2 | import { APICustomReaction } from './Emoji';
3 | import { RolePermissions } from './Team';
4 | import { APIUser } from './User';
5 |
6 | export interface APIDMChannel {
7 | id: string;
8 | type: CHANNEL_TYPES;
9 | name: string | null;
10 | description: string | null;
11 | users: APIUser[];
12 | createdAt: string;
13 | createdBy: string;
14 | updatedAt: string | null;
15 | contentType: CHANNEL_CONTENT_TYPES;
16 | archivedAt: string | null;
17 | autoArchiveAt: string | null;
18 | archivedBy: string | null;
19 | parentChannelId: string | null;
20 | deletedAt: string | null;
21 | createdByWebhookId: string | null;
22 | archivedByWebhookId: string | null;
23 | dmType: 'Default' | string;
24 | ownerId: string;
25 | voiceParticipants: APIUser[];
26 | }
27 |
28 | export interface APITeamChannel {
29 | id: string;
30 | type: CHANNEL_TYPES;
31 | createdAt: string;
32 | createdBy: string;
33 | updatedAt: string | null;
34 | name: string;
35 | contentType: CHANNEL_CONTENT_TYPES;
36 | archivedAt: string | null;
37 | parentChannelId: string | null;
38 | autoArchiveAt: string | null;
39 | deletedAt: string | null;
40 | archivedBy: string | null;
41 | description: string | null;
42 | createdByWebhookId: string | null;
43 | archivedByWebhookId: string | null;
44 | teamId: string;
45 | channelCategoryId: string | null;
46 | addedAt: string | null;
47 | channelId: string | null;
48 | isRoleSynced: boolean | null;
49 | roles: string[] | null;
50 | userPermissions: string[] | null;
51 | tournamentRoles: string[] | null;
52 | isPublic: boolean;
53 | priority: number;
54 | groupId: number;
55 | settings: unknown;
56 | groupType: string;
57 | rolesById: {
58 | [key: string]: APITeamChannelRolePermissionOverwrite;
59 | };
60 | tournamentRolesById: {
61 | [key: string]: APITeamChannelRolePermissionOverwrite;
62 | };
63 | createdByInfo: {
64 | id: string;
65 | name: string;
66 | profilePicture: string;
67 | profilePictureSm: string;
68 | };
69 | }
70 |
71 | export type CHANNEL_TYPES = 'Team' | 'DM';
72 | export type CHANNEL_CONTENT_TYPES = 'chat' | 'voice' | 'forum' | 'doc';
73 |
74 | export interface APIMessageReaction {
75 | customReactionId: number;
76 | createdAt: string;
77 | users: {
78 | id: string;
79 | webhookId: string | null;
80 | botId: string | null;
81 | }[];
82 | customReaction: APICustomReaction;
83 | }
84 |
85 | export interface APIReactionUsage {
86 | id: number;
87 | total: number;
88 | }
89 |
90 | export interface DenyPermissions {
91 | [key: string]: number;
92 | }
93 |
94 | export interface AllowPermissions {
95 | [key: string]: number;
96 | }
97 |
98 | export interface APIRoleOverwrite {
99 | teamId: string;
100 | createdAt: string;
101 | updatedAt: string | null;
102 | teamRoleId: number;
103 | denyPermissions: DenyPermissions;
104 | allowPermissions: AllowPermissions;
105 | channelId?: string;
106 | channelCategoryId?: number;
107 | }
108 |
109 | export type APIUserOverwrite = APIRoleOverwrite;
110 |
111 | export type APICategoryChannelRoleOverwrite = APIRoleOverwrite;
112 |
113 | export type APITeamChannelRoleOverwrite = APIRoleOverwrite;
114 |
115 | export interface APIMessage {
116 | id: string;
117 | content: APIContent;
118 | type: APIContentMessageType;
119 | reactions?: APIMessageReaction[];
120 | createdBy: string;
121 | createdAt: string;
122 | editedAt?: string | null;
123 | deletedAt?: string | null;
124 | channelId: string;
125 | repliesToIds: string[];
126 | repliesTo: string | null;
127 | webhookId?: string | null;
128 | botId?: string | null;
129 | isPinned?: boolean;
130 | pinnedBy?: string | null;
131 | }
132 |
133 | export interface APIMessageMention {
134 | id: string;
135 | name: string;
136 | type: string;
137 | color: string;
138 | avatar: string;
139 | matcher: string;
140 | nickname: boolean;
141 | description: string;
142 | }
143 |
144 | export type APIPartialMessage = Pick;
145 |
146 | export interface APIEmbed {
147 | title?: string;
148 | description?: string;
149 | url?: string;
150 | timestamp?: string;
151 | color?: number;
152 | footer?: APIEmbedFooter;
153 | image?: APIEmbedImage;
154 | thumbnail?: APIEmbedThumbnail;
155 | video?: APIEmbedVideo;
156 | provider?: APIEmbedProvider;
157 | author?: APIEmbedAuthor;
158 | fields?: APIEmbedField[];
159 | }
160 |
161 | export interface APIEmbedFooter {
162 | text: string;
163 | icon_url?: string;
164 | proxy_icon_url?: string;
165 | }
166 | export interface APIEmbedImage {
167 | url: string;
168 | proxy_url?: string;
169 | height?: string;
170 | width?: string;
171 | }
172 | export type APIEmbedThumbnail = APIEmbedImage;
173 |
174 | export type APIEmbedVideo = APIEmbedImage;
175 |
176 | export interface APIEmbedProvider {
177 | name?: string;
178 | url?: string;
179 | }
180 |
181 | export interface APIEmbedAuthor {
182 | name: string;
183 | icon_url?: string;
184 | url?: string;
185 | proxy_icon_url?: string;
186 | }
187 | export interface APIEmbedField {
188 | inline?: boolean;
189 | name: string;
190 | value: string;
191 | }
192 |
193 | export type APIContentMessageType = 'block' | 'text' | string;
194 | export type DocumentNodeMessageType = 'code-container' | 'paragraph' | string;
195 |
196 | export interface APITeamChannelRolePermissionOverwrite {
197 | teamId: string;
198 | channelId: string;
199 | createdAt: string;
200 | updatedAt: string | null;
201 | teamRoleId: number;
202 | denyPermissions: RolePermissions;
203 | allowPermissions: RolePermissions;
204 | }
205 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/Emoji.ts:
--------------------------------------------------------------------------------
1 | export interface APICustomReaction {
2 | id: number;
3 | name: string;
4 | png: string | null;
5 | webp: string | null;
6 | apng: string | null;
7 | }
8 |
9 | export interface APIEmoji {
10 | id: number;
11 | name: string;
12 | createdBy: string;
13 | createdAt: string;
14 | png: string;
15 | webp: string;
16 | apng: string;
17 | aliases: string[];
18 | teamId: string;
19 | isDeleted: boolean;
20 | discordEmojiId: string | null;
21 | discordSyncedAt: string | null;
22 | }
23 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/Team.ts:
--------------------------------------------------------------------------------
1 | import { APITeamChannelRoleOverwrite } from './Channel';
2 | import { APIAboutInfo, APIAlias, APISocialLink, APIUserStatus } from './User';
3 | import { APIWebhook } from './Webhook';
4 |
5 | export interface APITeam {
6 | additionalGameInfo: unknown;
7 | additionalInfo: {
8 | platform: string;
9 | };
10 | alphaInfo: unknown;
11 | alwaysShowTeamHome: boolean;
12 | autoSyncDiscordRoles: boolean;
13 | bannerImages: unknown;
14 | baseGroup: APIGroup;
15 | bio: string | null;
16 | bots: unknown[];
17 | canInviteMembers?: boolean;
18 | canManageTournaments?: boolean;
19 | canUpdateTeam?: boolean;
20 | characteristics: string | null;
21 | createdAt: string;
22 | customizationInfo: unknown;
23 | deafenedMembers?: unknown[];
24 | description: string;
25 | discordGuildId: string | null;
26 | discordServerName: string | null;
27 | flair: unknown[];
28 | followerCount: number;
29 | followingGroups: string[] | null;
30 | games: unknown[];
31 | homeBannerImageLg: string | null;
32 | homeBannerImageMd: string | null;
33 | homeBannerImageSm: string | null;
34 | id: string;
35 | insightsInfo: unknown;
36 | isAdmin?: boolean;
37 | isFavorite?: boolean;
38 | isPro: boolean;
39 | isPublic: boolean;
40 | isRecruiting: boolean;
41 | isUserApplicant: boolean;
42 | isUserBannedFromTeam: boolean;
43 | isUserInvited: boolean;
44 | isVerified: boolean;
45 | lfmStatusByGameId: unknown;
46 | measurements: APIMeasurements;
47 | members: APIMember[];
48 | mutedMembers: string[];
49 | memberCount?: string;
50 | membershipRole: string;
51 | name: string;
52 | notificationPreference: string | null;
53 | ownerId: string;
54 | profilePicture: string;
55 | rankNames: string | null;
56 | roleIds?: number[] | null;
57 | rolesById: {
58 | [key: string]: APITeamRole;
59 | };
60 | rolesVersion: number;
61 | socialInfo: unknown;
62 | status: string | null;
63 | subdomain: string;
64 | subscriptionInfo: string | null;
65 | teamDashImage: string | null;
66 | teamPreferences: string | null;
67 | timezone: string | null;
68 | type: string | null;
69 | upsell: null;
70 | userFollowsTeam: boolean;
71 | webhooks: APIWebhook[];
72 | }
73 |
74 | export interface APIPartialTeam {
75 | id: string;
76 | name: string;
77 | subdomain: string;
78 | activity: unknown[];
79 | games: string[] | null[];
80 | profilePicture: string;
81 | teamDashImage: string;
82 | homeBannerImageSm: string;
83 | homeBannerImageMd: string;
84 | homeBannerImageLg: string;
85 | gameIds: string[] | null;
86 | bannerImages: string[] | null[];
87 | memberCount: number;
88 | }
89 |
90 | export interface APITeamBan {
91 | reason: string;
92 | userId: string;
93 | bannedBy: string;
94 | createdAt: string;
95 | }
96 |
97 | export interface APITeamRole {
98 | id: string;
99 | name: string;
100 | color: string;
101 | priority: number;
102 | permissions: RolePermissions;
103 | isBase: boolean;
104 | teamId: string;
105 | createdAt: string;
106 | updatedAt: string | null;
107 | isMentionable: boolean;
108 | discordRoleId: string | null;
109 | discordSyncedAt: string | null;
110 | isSelfAssignable: boolean;
111 | isDisplayedSeparately: boolean;
112 | }
113 |
114 | export interface APIGroup {
115 | id: string;
116 | name: string;
117 | description: string | null;
118 | priority: string | null;
119 | type: string;
120 | avatar: string | null;
121 | banner: string | null;
122 | teamId: string;
123 | gameId: string | null;
124 | visibilityTeamRoleId: number;
125 | membershipTeamRoleId: number;
126 | isBase: boolean;
127 | additionalGameInfo: unknown;
128 | createdBy: string | null;
129 | createdAt: string;
130 | updatedBy: string | null;
131 | updatedAt: string | null;
132 | deletedAt: string | null;
133 | customReactionId: string | null;
134 | isPublic: boolean;
135 | archivedAt: string | null;
136 | archivedBy: string | null;
137 | }
138 |
139 | export interface APIMeasurements {
140 | numMembers: number;
141 | numFollowers: number;
142 | numRecentMatches: number;
143 | numRecentMatchWins: number;
144 | matchmakingGameRanks: unknown[];
145 | numFollowersAndMembers: number;
146 | numMembersAddedInLastDay: number;
147 | numMembersAddedInLastWeek: number;
148 | mostRecentMemberLastOnline: number;
149 | numMembersAddedInLastMonth: number;
150 | subscriptionMonthsRemaining: number | null;
151 | }
152 |
153 | export interface RoleOverwriteById {
154 | [key: string]: APITeamChannelRoleOverwrite;
155 | }
156 |
157 | /*
158 | Taken from: https://github.com/Skillz4Killz/gapi/blob/master/src/lib/Team.ts#L181
159 | GAPI created by https://github.com/Skillz4Killz, LICENSED under Apache License 2.0
160 | */
161 | export interface RolePermissions extends Record {
162 | chat: 119;
163 | docs: 15;
164 | forms: 18;
165 | lists: 63;
166 | media: 15;
167 | voice: 8179;
168 | forums: 123;
169 | general: 15412;
170 | calendar: 31;
171 | scheduling: 11;
172 | matchmaking: 1;
173 | recruitment: 55;
174 | announcements: 7;
175 | customization: 49;
176 | }
177 |
178 | export interface APIMember {
179 | id: string;
180 | name: string;
181 | nickname: string | null;
182 | badges: string[] | null;
183 | joinDate: string;
184 | membershipRole: MembershipRole;
185 | lastOnline: string | null;
186 | profilePicture: null | string;
187 | profileBannerBlur: null | string;
188 | aboutInfo: APIAboutInfo | null;
189 | userStatus: APIUserStatus;
190 | socialLinks: APISocialLink[] | null;
191 | roleIds: number[] | null;
192 | subscriptionType: string | null;
193 | aliases: APIAlias[];
194 | userPresenceStatus: number;
195 | teamXp: number;
196 | }
197 |
198 | export type MembershipRole = 'member' | 'admin' | 'formerMember';
199 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/User.ts:
--------------------------------------------------------------------------------
1 | import { APIContent } from '../Content';
2 | import { APICustomReaction } from './Emoji';
3 |
4 | export interface APIUserStatus {
5 | content: APIContent | null;
6 | customReactionId: number | null;
7 | customReaction?: APICustomReaction;
8 | }
9 |
10 | export interface APIAboutInfo {
11 | bio?: string;
12 | tagLine?: string;
13 | }
14 |
15 | export interface APISocialLink {
16 | type: SocialLinkSource;
17 | handle: null | string;
18 | additionalInfo: APISocialLinkAdditionalInfo;
19 | }
20 |
21 | export interface APISocialLinkAdditionalInfo {
22 | channelName?: string;
23 | }
24 |
25 | export enum USER_PRESENCE {
26 | ONLINE = 1,
27 | IDLE = 2,
28 | DND = 3,
29 | INVISIBLE = 4,
30 | }
31 |
32 | export interface APIAlias {
33 | alias?: string;
34 | discriminator: null | string;
35 | name: string;
36 | createdAt?: string;
37 | userId?: string;
38 | gameId: number;
39 | socialLinkSource: SocialLinkSource | null;
40 | additionalInfo: unknown;
41 | editedAt?: string;
42 | playerInfo: unknown;
43 | }
44 |
45 | export type SocialLinkSource =
46 | | 'bnet'
47 | | 'discord'
48 | | 'psn'
49 | | 'steam'
50 | | 'switch'
51 | | 'twitch'
52 | | 'twitter'
53 | | 'xbox'
54 | | 'youtube';
55 |
56 | export interface APIDevice {
57 | type: string;
58 | id: string;
59 | lastOnline: string;
60 | isActive: boolean;
61 | }
62 |
63 | export interface APIUser {
64 | aboutInfo: APIAboutInfo | null;
65 | aliases: APIAlias[];
66 | email: string | null;
67 | id: string;
68 | joinDate: string;
69 | lastOnline: string;
70 | moderationStatus: string | null;
71 | name: string;
72 | profileBannerBlur: string | null;
73 | profileBannerLg: string | null;
74 | profileBannerSm: string | null;
75 | profilePicture: string | null;
76 | profilePictureBlur: string | null;
77 | profilePictureLg: string | null;
78 | profilePictureSm: string | null;
79 | serviceEmail: string | null;
80 | steamId: string | null;
81 | subdomain: string;
82 | userStatus: APIUserStatus;
83 | }
84 |
85 | export interface APIClientUser extends APIUser {
86 | useMinimalNav: boolean;
87 | blockedUsers: unknown[];
88 | socialLinks: APIUserSocialLinks[];
89 | userPresenceStatus: number;
90 | badges: string[];
91 | canRedeemGold: boolean;
92 | isUnrecoverable: boolean;
93 | devices: APIDevice[];
94 | userChannelNotificationSettings: unknown[];
95 | upsell: null;
96 | }
97 |
98 | export interface APIUserSocialLinks {
99 | type: string;
100 | handle: string;
101 | additionalInfo: unknown;
102 | }
103 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/Webhook.ts:
--------------------------------------------------------------------------------
1 | export interface APIWebhook {
2 | id: string;
3 | name: string;
4 | channelId: string;
5 | teamId: string;
6 | iconUrl: string | null;
7 | createdBy: string;
8 | createdAt: string;
9 | deletedAt: string | null;
10 | token?: string;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/common/structures/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Channel';
2 | export * from './Emoji';
3 | export * from './Team';
4 | export * from './User';
5 | export * from './Webhook';
6 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/index.ts:
--------------------------------------------------------------------------------
1 | export * from './rest';
2 | export * from './common';
3 | export * from './ws';
4 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/Channel.ts:
--------------------------------------------------------------------------------
1 | import { APIContent, APIEmbed, APIMessage, APITeamChannel, CHANNEL_TYPES } from '../common';
2 |
3 | /**
4 | * Get Channel Result
5 | * @destination /channels/:channelID
6 | */
7 | export type APIGetChannel = APITeamChannel;
8 |
9 | /**
10 | * Modify Channel
11 | * @destination /channels/:id
12 | */
13 | export interface APIPatchChannelBody {
14 | name?: string;
15 | type?: CHANNEL_TYPES;
16 | position?: number | null;
17 | topic?: string | null;
18 | nsfw?: boolean | null;
19 | rate_limit_per_user?: number | null;
20 | bitrate?: number | null;
21 | user_limit?: number | null;
22 | parent_id?: string | null;
23 | }
24 |
25 | /**
26 | * Modify Channel Result
27 | * @destination /channels/:id
28 | */
29 | export type APIPatchChannelResult = APITeamChannel;
30 |
31 | /**
32 | * Delete/Close Channel
33 | * @destination /channels/:id
34 | */
35 | export type APIDeleteChannel = never;
36 |
37 | /**
38 | * Get Channel Messages
39 | * @destination /channels/:id/messages?limit=:amt
40 | */
41 | export interface APIGetChannelMessages {
42 | messages: APIMessage[];
43 | hasPastMessages: boolean;
44 | }
45 |
46 | /**
47 | * Get Channel Message
48 | * @destination /content/route/metadata?route=//channels/:channelID/chat&messageId=:messageID
49 | */
50 | export interface APIGetChannelMessageQuery {
51 | route: string;
52 | messageId: string;
53 | }
54 |
55 | /**
56 | * Get Channel Message Result
57 | * @destination /content/route/metadata?route=//channels/:channelID/chat&messageId=:messageID
58 | */
59 | export type APIGetChannelMessageResult = APIMessage;
60 |
61 | /**
62 | * Get Channel Messages
63 | * @destination /channels/:id/messages?limit=:amt
64 | * Tested upto 50k messages
65 | */
66 | export interface APIGetChannelMessagesQuery {
67 | limit?: number;
68 | }
69 |
70 | /**
71 | * Send Message
72 | * @destination /channels/:id/messages
73 | */
74 | export interface APIPostChannelMessagesBody {
75 | messageId: string;
76 | content: APIContent;
77 | embed: APIEmbed;
78 | }
79 |
80 | /**
81 | * Send Message
82 | * @destination /channels/:id/messages
83 | */
84 | export type APIPostChannelMessagesResult = APIMessage;
85 |
86 | /**
87 | * Edit Message
88 | * @destination /channels/:id/messages/:messageID
89 | */
90 | export interface APIPatchChannelMessageBody {
91 | content: string;
92 | embed: APIEmbed;
93 | }
94 |
95 | /**
96 | * Edit Message Result
97 | * @destination /channels/:id/messages/:messageID
98 | */
99 | export type APIPatchChannelMessageResult = APIMessage;
100 |
101 | /**
102 | * Delete Message
103 | * @destination /channels/:channelID/messages/:messageID
104 | */
105 | export type APIDeleteChannelMessage = never;
106 |
107 | /**
108 | * Add Reaction
109 | * @destination /channels/:channelID/messages/:messageID/reactions/:reactionID
110 | */
111 | export type APIPostMessageReactions = never;
112 |
113 | /**
114 | * Delete Own Reactioon
115 | * @destination /channels/:channelID/messages/:messageID/reactions/:reactionID
116 | */
117 | export type APIDeleteMessageReactionsOwn = never;
118 |
119 | /**
120 | * Get Pinned Messages
121 | * @destination /channels/:id/pins
122 | */
123 | export interface APIGetChannelPinnedMessages {
124 | message: APIMessage[];
125 | }
126 |
127 | /**
128 | * Pin Message
129 | * @destination /channels/:id/pins
130 | */
131 | export interface APIPostChannelPinnedMessagesBody {
132 | messageId: string;
133 | }
134 |
135 | /**
136 | * Unpin Message
137 | * @destination /channels/:id/pins/messageID
138 | */
139 | export type APIDeleteChannelPinnedMessage = never;
140 |
141 | /**
142 | * Create Thread
143 | * @destination /channels/:id/threads
144 | */
145 | export interface APIPostChannelCreateThread {
146 | name: string;
147 | message: APIMessage;
148 | channelId: string;
149 | threadMessageId: string;
150 | initialThreadMessage: APIMessage;
151 | contentType: string;
152 | confirmed: boolean;
153 | }
154 |
155 | /**
156 | * Delete Thread
157 | * @destination /teams/:teamID/groups/:groupID/channels/threadID
158 | */
159 | export type APIDeleteChannelThread = never;
160 |
161 | /**
162 | * Post Team Announcements
163 | * @destination /teams/:teamID/announcements
164 | */
165 | export interface APIPostTeamAnnouncement {
166 | title: string;
167 | content: APIMessage;
168 | }
169 |
170 | /**
171 | * Post Announcement
172 | * @destination /channels/:id/announcements
173 | */
174 | export interface APIPostChannelAnnouncementsBody {
175 | title: string;
176 | content: APIMessage;
177 | dontSendNotifications: boolean;
178 | }
179 |
180 | /**
181 | * @destination /teams/:id/channels
182 | */
183 | export interface APIGetTeamChannels {
184 | channels: APITeamChannel[];
185 | badgedChannelContentByChannelId: unknown;
186 | temporalChannels: unknown[];
187 | categories: APITeamChannel[];
188 | }
189 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/Emoji.ts:
--------------------------------------------------------------------------------
1 | import { APIEmoji } from '../common/structures/Emoji';
2 |
3 | /**
4 | * Get Team Emojis
5 | * @destination
6 | */
7 | export interface APIGetTeamEmojisResult {
8 | emojis: APIEmoji[];
9 | }
10 |
11 | /**
12 | * Get Team Emojis
13 | * @destination
14 | */
15 | export interface APIGetTeamEmojisQuery {
16 | maxItems: number;
17 | when: {
18 | upperValue: string;
19 | lowerValue: string;
20 | };
21 | createdBy: string;
22 | searchTerm: string;
23 | beforeId: string;
24 | }
25 |
26 | /**
27 | * Create Team Emoji
28 | * @destination
29 | */
30 | export interface APIPostTeamEmojisBody {
31 | name: string;
32 | png?: string;
33 | webp?: string;
34 | apng?: string;
35 | }
36 |
37 | /**
38 | * Create Team Emoji
39 | * @destination
40 | */
41 | export type APIPostTeamEmojisResult = APIEmoji;
42 |
43 | /**
44 | * Modify Team Emoji
45 | * @destination
46 | */
47 | export interface APIPatchTeamEmojiBody {
48 | name: string;
49 | }
50 |
51 | /**
52 | * Modify Team Emoji
53 | * @destination
54 | */
55 | export type APIPatchTeamEmojisResult = never;
56 |
57 | /**
58 | * Delete Team Emoji
59 | * @destination
60 | */
61 | export type APIDeleteTeamEmojiResult = never;
62 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/Team.ts:
--------------------------------------------------------------------------------
1 | import { APITeam } from '../common';
2 |
3 | /**
4 | * @destination /teams/:id
5 | */
6 | export interface APIGetTeam {
7 | team: APITeam;
8 | }
9 | /**
10 | * @destination /teams/:id/invites
11 | */
12 | export interface APIPostCreateInviteResult {
13 | id: string;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/User.ts:
--------------------------------------------------------------------------------
1 | import {
2 | APIAboutInfo,
3 | APIClientUser,
4 | APICustomReaction,
5 | APIDMChannel,
6 | APIReactionUsage,
7 | APITeam,
8 | APIUser,
9 | } from '../common';
10 |
11 | /**
12 | * Get User
13 | * @destination /users/:id
14 | */
15 | export interface APIGetUser {
16 | user: APIUser;
17 | }
18 |
19 | /**
20 | * Get Current User
21 | * @destination /me
22 | */
23 | export interface APIGetCurrentUser {
24 | updateMessage: string | null;
25 | user: APIClientUser;
26 | teams: APITeam[];
27 | customReactions: APICustomReaction[];
28 | reactionUsages: APIReactionUsage[];
29 | landingUrl: boolean;
30 | }
31 |
32 | /**
33 | * Modify Current User
34 | * @destination /users/:userID/profilev2
35 | */
36 | export interface APIPutCurrentUserBody {
37 | name: string;
38 | avatar: string;
39 | subdomain: string;
40 | aboutInfo: APIAboutInfo;
41 | }
42 |
43 | /**
44 | * Modify Current User
45 | * @destination /users/:userID/profilev2
46 | */
47 | export type APIPutCurrentUserResult = APIUser;
48 |
49 | /**
50 | * Leave Team
51 | * @destination /teams/:teamID/members/:userID
52 | */
53 | export type APIDeleteUserTeam = never;
54 |
55 | /**
56 | * Login the Client
57 | * @destination /login
58 | */
59 | export interface APIPostLoginResponse {
60 | user: Omit;
61 | }
62 |
63 | /**
64 | * Get all of a user's DM Channel
65 | * @destination /users/:id/channels
66 | */
67 | export interface APIGetUserDMChannels {
68 | channels: APIDMChannel[];
69 | unreadInfoByChannelId: unknown;
70 | users: APIUser[];
71 | }
72 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/Webhook.ts:
--------------------------------------------------------------------------------
1 | import { APIContent, APIEmbed, APIWebhook } from '../common';
2 |
3 | /**
4 | * Create Webhook
5 | * @destination /webhooks
6 | */
7 | export interface APIPostCreateWebhookBody {
8 | name: string;
9 | channelId: string;
10 | }
11 |
12 | /**
13 | * Create Webhook Result
14 | * @destination /webhooks
15 | */
16 | export type APIPostCreateWebhookResult = APIWebhook;
17 |
18 | /**
19 | * Get Channel Webhooks
20 | * @destination /teams/:teamID/channels/:channelID/webhooks
21 | */
22 | export interface APIGetTeamChannelWebhooks {
23 | webhooks: APIWebhook[];
24 | }
25 |
26 | /**
27 | * Modify Webhook
28 | * @destination /webhooks/:webhookID
29 | */
30 | export interface APIPutWebhookBody {
31 | name: string;
32 | iconUrl: string;
33 | channelId: string;
34 | }
35 |
36 | /**
37 | * Modify Webhook Result
38 | * @destination /webhooks/:webhookID
39 | */
40 | export type APIPutWebhookResult = APIWebhook;
41 |
42 | /**
43 | * Delete Webhook Result
44 | * @destination /webhooks/:webhookID
45 | */
46 | export type APIDeleteWebhookResult = Pick;
47 |
48 | /**
49 | * Execute Webhook
50 | * @destination /webhooks/:webhookID/:webhookToken
51 | */
52 | export interface APIPostWebhookBody {
53 | content: string;
54 | embeds: APIEmbed[];
55 | }
56 |
57 | export interface APIPostWebhookResult {
58 | id: string;
59 | channelId: string;
60 | content: APIContent;
61 | type: string;
62 | createdBy: string;
63 | createdAt: string;
64 | webhookId: string;
65 | botId: string | null;
66 | }
67 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/rest/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Channel';
2 | export * from './Emoji';
3 | export * from './Team';
4 | export * from './User';
5 | export * from './Webhook';
6 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/ChatMessageCreated.ts:
--------------------------------------------------------------------------------
1 | import { APIMessage, CHANNEL_CONTENT_TYPES, CHANNEL_TYPES } from '../common';
2 | export interface WSChatMessageCreated {
3 | channelCategoryId?: string | null;
4 | channelId: string;
5 | channelType: CHANNEL_TYPES;
6 | contentId: string;
7 | contentType: CHANNEL_CONTENT_TYPES;
8 | createdAt: string;
9 | createdBy: string;
10 | guildedClientId: string;
11 | id: string;
12 | message: Pick<
13 | APIMessage,
14 | 'id' | 'createdBy' | 'content' | 'type' | 'createdAt' | 'webhookId' | 'botId' | 'repliesTo' | 'repliesToIds'
15 | >;
16 | repliedToMessage?: APIMessage[];
17 | silenceNotification: boolean;
18 | teamId?: string;
19 | type: 'ChatMessageCreated';
20 | }
21 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/ChatMessageReactionAdded.ts:
--------------------------------------------------------------------------------
1 | import { APICustomReaction, CHANNEL_CONTENT_TYPES, CHANNEL_TYPES } from '../common';
2 |
3 | export interface WSChatMessageReactionAdded {
4 | type: 'ChatMessageReactionAdded';
5 | guildedClientId: string;
6 | channelId: string;
7 | channelCategoryId: string | null;
8 | channelType: CHANNEL_TYPES;
9 | teamId: string | null;
10 | contentType: CHANNEL_CONTENT_TYPES;
11 | reaction: {
12 | customReactionId: number;
13 | customReaction: APICustomReaction;
14 | createdBy: string;
15 | };
16 | message: {
17 | id: string;
18 | };
19 | silenceNotification: boolean;
20 | }
21 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/ChatMessageReactionDeleted.ts:
--------------------------------------------------------------------------------
1 | import { CHANNEL_CONTENT_TYPES, CHANNEL_TYPES } from '../common';
2 |
3 | export interface WSChatMessageReactionDeleted {
4 | type: 'ChatMessageReactionDeleted';
5 | guildedClientId: string;
6 | channelId: string;
7 | channelCategoryId: string | null;
8 | channelType: CHANNEL_TYPES;
9 | teamId: string | null;
10 | contentType: CHANNEL_CONTENT_TYPES;
11 | reaction: {
12 | customReactionId: number;
13 | createdBy: string;
14 | };
15 | message: {
16 | id: string;
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/ChatMessageUpdated.ts:
--------------------------------------------------------------------------------
1 | import { APIPartialMessage } from '../common';
2 |
3 | export interface WSChatMessageUpdated {
4 | channelCategoryId: string | null;
5 | channelId: string;
6 | channelType: string;
7 | contentId: string;
8 | contentType: string;
9 | guildedClientId: string;
10 | message: APIPartialMessage;
11 | silenceNotification: boolean;
12 | teamId: string;
13 | type: string;
14 | updatedBy: string;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/Ready.ts:
--------------------------------------------------------------------------------
1 | export interface WSGatewayReady {
2 | sid: string;
3 | upgrades: unknown[];
4 | pingInterval: number;
5 | pingTimeout: number;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/lib/ws/index.ts:
--------------------------------------------------------------------------------
1 | export * from './ChatMessageCreated';
2 | export * from './ChatMessageReactionAdded';
3 | export * from './ChatMessageReactionDeleted';
4 | export * from './ChatMessageUpdated';
5 | export * from './Ready';
6 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/guilded-api-typings",
3 | "version": "1.4.1-selfbot",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@guildedjs/guilded-api-typings",
9 | "version": "1.3.1-selfbot",
10 | "license": "MIT",
11 | "devDependencies": {
12 | "@types/node": "^14.14.9",
13 | "typescript": "^4.4.2"
14 | }
15 | },
16 | "node_modules/@types/node": {
17 | "version": "14.14.16",
18 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz",
19 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==",
20 | "dev": true
21 | },
22 | "node_modules/typescript": {
23 | "version": "4.4.2",
24 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
25 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
26 | "dev": true,
27 | "bin": {
28 | "tsc": "bin/tsc",
29 | "tsserver": "bin/tsserver"
30 | },
31 | "engines": {
32 | "node": ">=4.2.0"
33 | }
34 | }
35 | },
36 | "dependencies": {
37 | "@types/node": {
38 | "version": "14.14.16",
39 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz",
40 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==",
41 | "dev": true
42 | },
43 | "typescript": {
44 | "version": "4.4.2",
45 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
46 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
47 | "dev": true
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/guilded-api-typings",
3 | "version": "1.4.1-selfbot",
4 | "description": "Typings for the guilded API",
5 | "author": "zaid450 ",
6 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded-api-typings#readme",
7 | "license": "MIT",
8 | "types": "dist/index.d.ts",
9 | "main": "dist/index.js",
10 | "scripts": {
11 | "build": "tsc",
12 | "prepublishOnly": "npx rimraf dist/ && npm run build"
13 | },
14 | "devDependencies": {
15 | "@types/node": "^14.14.9",
16 | "typescript": "^4.4.2"
17 | },
18 | "directories": {
19 | "lib": "lib",
20 | "test": "__tests__"
21 | },
22 | "keywords": [
23 | "guilded",
24 | "guildedjs",
25 | "guilded.js",
26 | "guilded-api",
27 | "guilded-api-wrapper",
28 | "guilded-wrapper",
29 | "guilded-api-typings"
30 | ],
31 | "files": [
32 | "dist"
33 | ],
34 | "repository": {
35 | "type": "git",
36 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
37 | },
38 | "bugs": {
39 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
40 | },
41 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
42 | }
43 |
--------------------------------------------------------------------------------
/packages/guilded-api-typings/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "target": "ES2020",
6 | "removeComments": false
7 | },
8 | "include": [
9 | "./lib/**/*.ts"
10 | ]
11 | }
--------------------------------------------------------------------------------
/packages/guilded.js/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Zaid - Nico
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 |
23 | Includes other software related under the Apache License 2.0:
24 | - discord.js, Copyright 2015-2020, For licensing see https://github.com/discordjs/discord.js/blob/stable/LICENSE
--------------------------------------------------------------------------------
/packages/guilded.js/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Guilded.js
3 |
A Node.js library for the Guilded.gg API.
4 |
5 |
6 |
7 | 
8 |
9 |
10 |
11 | ```ts
12 | const { Client } = require("@guildedjs/guilded.js");
13 | // import { Client } from "@guildedjs/guilded.js";
14 |
15 | const client = new Client();
16 |
17 | client.on("ready", () => console.log(`Bot is successfully logged in`));
18 |
19 | client.on("messageCreate", (message) => {
20 | if (message.content === "poggers") {
21 | return message.channel.send("poggers indeed");
22 | }
23 | });
24 |
25 | client.login({
26 | email: "email",
27 | password: "password",
28 | });
29 | ```
30 |
31 | ## 📝 About
32 |
33 | `@guildedjs/guilded.js` is a library written in TypeScript usable in either TypeScript or JavaScript projects. It provides structures, abstraction, and utilities for interaction between the guilded API and your userbot.
34 |
35 | Off the bat there are very noticable similarities between this package and [`discord.js`](https://discord.js.org) structure-wise. This is intentional in order to make the migration or copying of your codebase to a Guilded bot smooth and predictable. We've adopted the same managers/cache structure that they've implemented because we find that it's what works well without complications. While our structure is **influenced** by them, there are underlying differences with how we handle things like websockets, events, and utilities. In addition to that, the library is split up into multiple packages (this being the main one) and written in TypeScript over JavaScript.
36 |
37 | ## 📥 Installation
38 |
39 |
40 |
41 | **Recommended that you use node v12+**
42 |
43 | - `npm install @guildedjs/guilded.js`
44 | - `yarn add @guildedjs/guilded.js`
45 |
46 | ## 📃 Documentation
47 |
48 | Documentation is located [here](https://zaida04.github.io/guildedjs-selfbot-docs)
49 |
50 | ## 📦 Dependencies
51 |
52 | - [`@guildedjs/guilded-api-typings`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded-api-typings) (dev dep): used for typing the REST and WS payloads
53 | - [`@guildedjs/common`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/common): Utilities between `@guildedjs` packages
54 | - [`@guildedjs/rest`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/rest): Rest structure for `@guildedjs` packages
55 | - [`@guildedjs/embeds`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/embeds): Embed builder/utility
56 | - [`@guildedjs/webhook-client`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/webhook-client): Webhook Client
57 | - `@discordjs/collection`: Map utility
58 | - `ws`: WebSocket interaction
59 |
60 | ## ✋ Contributing
61 |
62 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
63 |
64 | ## 🤝 Acknowledgements
65 |
66 | - [`Discord.js`](https://discord.js.org/#/) - Inspiration and caching strategy
67 |
68 | ## ⚖️ LICENSING
69 |
70 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
71 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/colors.js:
--------------------------------------------------------------------------------
1 | exports.COLORS = {
2 | CYAN: '\u001B[36m',
3 | GREEN: '\u001B[32m',
4 | RED: '\u001B[31m',
5 | RESET: '\u001B[0m',
6 | UNDERSCORE: '\u001B[4m',
7 | WHITE: '\u001B[37m',
8 | YELLOW: '\u001B[33m',
9 | };
10 |
11 | exports.testText = str => console.log(`\n${exports.COLORS.YELLOW} ---${str}--- ${exports.COLORS.RESET}`);
12 | exports.successText = str => console.log(`${exports.COLORS.GREEN} ${str} ${exports.COLORS.RESET}`);
13 | exports.errorText = str => console.log(`\n${exports.COLORS.RED} ${str} ${exports.COLORS.RESET}\n`);
14 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-var-requires */
2 | const { config } = require('dotenv');
3 | const { join } = require('path');
4 | const { COLORS, testText, errorText, successText } = require('./colors.js');
5 | const Guilded = require('..');
6 |
7 | config({
8 | path: join(__dirname, '..', '..', '..', '.env'),
9 | });
10 |
11 | if (!process.env.EMAIL) throw new Error('Must supply email for testing');
12 | if (!process.env.PASSWORD) throw new Error('Must supply password for testing');
13 | if (!process.env.TEAM_ID) throw new Error('Must provide a testing team ID');
14 | if (!process.env.ROLE_ID) throw new Error('Must provide a testing role ID');
15 | if (!process.env.GUINEAPIG_ID) throw new Error('Must provide a testing user ID');
16 | if (!process.env.GROUP_ID) throw new Error('Must provide a testing group ID');
17 | if (!process.env.CHANNEL_ID) throw new Error('Must provide a testing channel ID');
18 |
19 | const client = new Guilded.Client({
20 | ws: {
21 | heartbeatInterval: 15000,
22 | },
23 | });
24 | const prefix = 'gg!';
25 |
26 | // client.on('raw', console.log);
27 | // client.on('debug', console.log);
28 |
29 | client.on(Guilded.events.MESSAGE_REACTION_ADD, a => console.log(`REACTION ADDED: ${a.id}`));
30 | client.on(Guilded.events.MESSAGE_REACTION_DELETE, a => console.log(`REACTION REMOVED: ${a.id}`));
31 |
32 | /**
33 | * Testing login
34 | */
35 | client.once(Guilded.events.READY, async () => {
36 | let passed = 0;
37 | let failed = 0;
38 |
39 | console.log(
40 | `Successfully logged in as ${client.user.id}. Currently in ${client.teams.cache.size} Teams and serving ${client.users.cache.size} users with ${client.channels.cache.size} channels.`,
41 | );
42 |
43 | testText('Role adding/Removal');
44 | await require('./modules/role')(client, passed, failed, successText, errorText)
45 | .then(() => passed++)
46 | .catch(() => failed++);
47 |
48 | testText('Client Disconnection/Reconnection');
49 | try {
50 | require('./modules/connection')(client, passed, failed, successText, errorText);
51 | passed++;
52 | } catch {
53 | failed++;
54 | }
55 |
56 | testText('Message Sending/Editing/Deletion/Fetching');
57 | await require('./modules/message')(client, passed, failed, successText, errorText)
58 | .then(() => passed++)
59 | .catch(() => failed++);
60 |
61 | testText('Active WS connection');
62 | try {
63 | require('./modules/ws')(client, passed, failed, successText, errorText);
64 | passed++;
65 | } catch {
66 | failed++;
67 | }
68 |
69 | testText('Invite Creation/Deletion');
70 | await require('./modules/invite')(client, passed, failed, successText, errorText)
71 | .then(() => passed++)
72 | .catch(() => failed++);
73 |
74 | testText('Embed sending');
75 | await require('./modules/embed')(client, passed, failed, successText, errorText)
76 | .then(() => passed++)
77 | .catch(() => failed++);
78 |
79 | console.log(`\n\n${COLORS.GREEN} ${passed} tests passed.${COLORS.RED} ${failed} tests failed. ${COLORS.RESET}`);
80 | });
81 |
82 | client.on(Guilded.events.MESSAGE_CREATE, message => {
83 | if (message.teamID !== process.env.TEAM_ID) return;
84 | if (!message.content.startsWith(prefix)) return;
85 | const args = message.content.split(/ /g);
86 | const command = args.shift().slice(prefix.length);
87 |
88 | switch (command) {
89 | case 'eval': {
90 | if (message.authorID !== client.user.id) return message.channel.send('**NICE TRY**');
91 | const code = args.join(' ');
92 | const evaled = eval(`(async () => {${code}})()`);
93 | message.channel.send(`
94 | 📥 **Input**
95 | \`\`\`${code}\`\`\`
96 | 📤 **Output**
97 | \`\`\`${evaled}\`\`\`
98 | `);
99 | break;
100 | }
101 | case 'ping': {
102 | return message.channel.send('HI!');
103 | }
104 | }
105 | });
106 |
107 | client.login({
108 | email: process.env.EMAIL,
109 | password: process.env.PASSWORD,
110 | });
111 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/connection.js:
--------------------------------------------------------------------------------
1 | module.exports = (client, passed, failed, testText, errorText) => {
2 | try {
3 | client.destroy(true);
4 | testText('Successfully disconnected!');
5 | } catch (e) {
6 | errorText(`Client disconnected failed! ${e}`);
7 | throw e;
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/embed.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-var-requires
2 | const { Embed } = require('@guildedjs/embeds');
3 | const iconURL = 'https://cdn.discordapp.com/avatars/500765481788112916/0c12c135aeeae527f46e9f737e6ca937.png';
4 |
5 | module.exports = async (client, passed, failed, testText, errorText) => {
6 | try {
7 | console.log('...sending embed');
8 | message = await client.channels.sendMessage(
9 | process.env.CHANNEL_ID,
10 | new Embed()
11 | .setTitle('TESTING EMBED!')
12 | .setAuthor('Joe Mama', iconURL, 'https://google.com')
13 | .setDescription('This is a test description')
14 | .setFooter('This is a footer', iconURL)
15 | .setTimestamp(new Date().getTime())
16 | .setURL('https://google.com')
17 | .setImage(iconURL),
18 | );
19 | testText(`Successfully sent embed message with ID: ${message}!`);
20 | } catch (e) {
21 | errorText(`Message sending failed! ${e}`);
22 | throw e;
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/invite.js:
--------------------------------------------------------------------------------
1 | module.exports = async (client, passed, failed, testText, errorText) => {
2 | let invite;
3 | try {
4 | console.log('...creating Invite');
5 | invite = await client.teams.createInvite(process.env.TEAM_ID);
6 | testText(`Successfully created invite! id: ${invite.id}`);
7 | } catch (e) {
8 | errorText(`Creating invite failed! ${e}`);
9 | console.log(e);
10 | throw e;
11 | }
12 |
13 | try {
14 | console.log('...deleting Invite');
15 | const responseID = await client.teams.deleteInvite(process.env.TEAM_ID, invite.id);
16 | testText(`Successfully deleted invite! response-id ${responseID}`);
17 | } catch (e) {
18 | errorText(`Deleting invite failed! ${e}`);
19 | console.log(e);
20 | throw e;
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/message.js:
--------------------------------------------------------------------------------
1 | module.exports = async (client, passed, failed, testText, errorText) => {
2 | let message;
3 | const content = 'TESTING MESSAGE';
4 |
5 | try {
6 | console.log('...sending message');
7 | message = await client.channels.sendMessage(process.env.CHANNEL_ID, content);
8 | testText(`Successfully sent message with ID: ${message}!`);
9 | } catch (e) {
10 | errorText(`Message sending failed! ${e}`);
11 | throw e;
12 | }
13 |
14 | try {
15 | console.log('...editing message');
16 | const newMessage = await client.channels.editMessage(
17 | process.env.CHANNEL_ID,
18 | message,
19 | 'THIS IS AN EDITED TEST MESSAGE',
20 | );
21 | if (content === newMessage.content) throw new Error('Content is unchanged!');
22 | testText(`Successfully edited message ${message} with new content ${newMessage.content}`);
23 | } catch (e) {
24 | errorText(`Message editing failed! ${e}`);
25 | throw e;
26 | }
27 |
28 | try {
29 | console.log('...deleting message');
30 | await client.channels.deleteMessage(process.env.CHANNEL_ID, message);
31 | testText('Successfully deleted message!');
32 | } catch (e) {
33 | errorText(`Message deletion failed! ${e}`);
34 | throw e;
35 | }
36 |
37 | try {
38 | console.log('...fetching 5 messages');
39 | const messages = await client.channels.cache.random().messages.fetch(5);
40 | testText(`Successfully fetched messages!`);
41 | } catch (e) {
42 | errorText(`Message fetching failed! ${e}`);
43 | throw e;
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/role.js:
--------------------------------------------------------------------------------
1 | module.exports = async (client, passed, failed, testText, errorText) => {
2 | try {
3 | console.log('...adding role');
4 | await client.teams.addRoleToMember(process.env.TEAM_ID, process.env.GUINEAPIG_ID, process.env.ROLE_ID);
5 | testText('Role successfully added.');
6 | } catch (e) {
7 | errorText(`Role adding failed! ${e}`);
8 | throw e;
9 | }
10 |
11 | try {
12 | console.log('...removing role');
13 | await client.teams.removeRoleFromMember(process.env.TEAM_ID, process.env.GUINEAPIG_ID, process.env.ROLE_ID);
14 | testText('Role successfully removed.');
15 | } catch (e) {
16 | errorText(`Role removal failed! ${e}`);
17 | throw e;
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/packages/guilded.js/__tests__/modules/ws.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-var-requires
2 | const webSocket = require('ws');
3 |
4 | module.exports = (client, passed, failed, testText, errorText) => {
5 | try {
6 | console.log('...testing connection');
7 | if (client.gateway.ws.readyState !== webSocket.OPEN) throw new Error('WS NOT OPEN!');
8 | client.gateway.ws.send('2');
9 | testText('WS message sent!');
10 | } catch (e) {
11 | errorText(`WS connection failed! ${e}`);
12 | throw e;
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/index.ts:
--------------------------------------------------------------------------------
1 | export { Client } from './structures/Client';
2 | export * from './structures';
3 | export * from './typings';
4 | export * from '@guildedjs/common';
5 | export * from '@guildedjs/rest';
6 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/Base.ts:
--------------------------------------------------------------------------------
1 | import type { BaseData } from '../typings';
2 | import type { Client } from './Client';
3 |
4 | /**
5 | * The base of all structures
6 | *
7 | * @param T The minimum amount of data required to construct this structure
8 | */
9 | export abstract class Base {
10 | /**
11 | * The ID of this structure
12 | */
13 | public readonly id: string;
14 |
15 | /**
16 | * The raw API data of this structure
17 | */
18 | public readonly raw: Partial;
19 |
20 | public constructor(public readonly client: Client, data: T) {
21 | this.id = data.id.toString();
22 | this.raw = data;
23 | }
24 |
25 | /**
26 | * Update the data in this structure
27 | * @internal
28 | */
29 | public abstract patch(data: T | Partial): this;
30 |
31 | /**
32 | * Taken from https://github.com/discordjs/discord.js/blob/8e8d9b490a71de6cabe6f16375d7549a7c5c3737/src/structures/Base.js#L20
33 | * Licensed under the Apache License 2.0
34 | */
35 | public _clone(): this {
36 | return Object.assign(Object.create(this), this);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/Group.ts:
--------------------------------------------------------------------------------
1 | import type { APIGroup } from '@guildedjs/guilded-api-typings';
2 |
3 | import { Base } from './Base';
4 | import type { Client } from './Client';
5 | import { TeamGroupChannelManager } from './managers/TeamGroupChannelManager';
6 | import type { Team } from './Team';
7 |
8 | /**
9 | * A group residing within a Team that contains channels.
10 | */
11 | export class Group extends Base {
12 | /**
13 | * The channels that belong to this group.
14 | */
15 | public readonly channels: TeamGroupChannelManager;
16 |
17 | /**
18 | * The name of this group.
19 | */
20 | public name!: string;
21 |
22 | /**
23 | * The description of this group.
24 | */
25 | public description: string | null;
26 |
27 | /**
28 | * The position of this group.
29 | */
30 | public priority: string | null;
31 |
32 | /**
33 | * The type of this group.
34 | */
35 | public type: string;
36 |
37 | /**
38 | * The avatar hash of this group.
39 | */
40 | public avatar: string | null;
41 |
42 | /**
43 | * The banner hash of this group.
44 | */
45 | public banner: string | null;
46 |
47 | /**
48 | * The ID of the team this group belongs to.
49 | * @readonly
50 | */
51 | public teamID: string;
52 |
53 | /**
54 | * The ID of the game this group belongs to.
55 | */
56 | public gameID: string | null;
57 |
58 | /**
59 | * The role required to see this group.
60 | */
61 | public visibilityTeamRoleID: number;
62 |
63 | /**
64 | * The role required to be considered a member of this group.
65 | */
66 | public membershipTeamRoleID: number;
67 |
68 | /**
69 | * If this is the base group of the team this group belongs to.
70 | */
71 | public isBase!: boolean;
72 |
73 | /**
74 | * The ID of the user that created this group.
75 | */
76 | public readonly createdByID: string | null;
77 |
78 | /**
79 | * Date this group was created on.
80 | */
81 | public readonly createdAt: Date;
82 |
83 | /**
84 | * The ID of the user that last updated this group.
85 | */
86 | public updatedBy: string | null;
87 |
88 | /**
89 | * Date this group was last updated.
90 | */
91 | public updatedAt: Date | null;
92 |
93 | /**
94 | * Date this group was deleted at.
95 | */
96 | public deletedAt: Date | null;
97 |
98 | /**
99 | * ID of the custom reaction tied to this group.
100 | */
101 | public customReactionID: string | null;
102 |
103 | /**
104 | * Whether this group is public or not (can be seen without being a member).
105 | */
106 | public public!: boolean;
107 |
108 | /**
109 | * Date this group was archived at.
110 | */
111 | public archivedAt: Date | null;
112 |
113 | /**
114 | * The ID of the user that archived this group.
115 | */
116 | public archivedBy: string | null;
117 |
118 | public constructor(client: Client, data: APIGroup, public team: Team | null) {
119 | super(client, data);
120 | this.channels = new TeamGroupChannelManager(this.client, this);
121 | this.description = null;
122 | this.priority = null;
123 | this.type = data.type;
124 | this.avatar = null;
125 | this.banner = null;
126 | this.teamID = data.teamId;
127 | this.gameID = null;
128 | this.visibilityTeamRoleID = data.visibilityTeamRoleId;
129 | this.membershipTeamRoleID = data.membershipTeamRoleId;
130 | this.createdByID = data.createdBy;
131 | this.createdAt = new Date(data.createdAt);
132 | this.updatedAt = null;
133 | this.updatedBy = null;
134 | this.deletedAt = null;
135 | this.customReactionID = null;
136 | this.archivedAt = null;
137 | this.archivedBy = null;
138 |
139 | this.patch(data);
140 | }
141 |
142 | /**
143 | * Update the data in this structure
144 | * @internal
145 | */
146 | public patch(data: APIGroup | Partial): this {
147 | if ('name' in data && data.name !== undefined) this.name = data.name;
148 | if ('description' in data && data.description !== undefined) this.description = data.description;
149 | if ('priority' in data && data.priority !== undefined) this.priority = data.priority;
150 | if ('type' in data && data.type !== undefined) this.type = data.type;
151 | if ('avatar' in data && data.avatar !== undefined) this.avatar = data.avatar;
152 | if ('banner' in data && data.banner !== undefined) this.banner = data.banner;
153 | if ('updatedBy' in data && data.updatedBy !== undefined) this.updatedBy = data.updatedBy ?? null;
154 | if ('updatedAt' in data && data.updatedAt !== undefined) {
155 | this.updatedAt = data.updatedAt ? new Date(data.updatedAt) : null;
156 | }
157 | if ('deletedAt' in data && data.deletedAt !== undefined) {
158 | this.deletedAt = data.deletedAt ? new Date(data.deletedAt) : null;
159 | }
160 | if ('customReactionId' in data && data.customReactionId !== undefined) {
161 | this.customReactionID = data.customReactionId;
162 | }
163 | if ('isPublic' in data && data.isPublic !== undefined) this.public = data.isPublic;
164 | if ('archivedAt' in data && data.archivedAt !== undefined) {
165 | this.archivedAt = data.archivedAt ? new Date(data.archivedAt) : null;
166 | }
167 | if ('archivedBy' in data && data.archivedBy !== undefined) this.archivedBy = data.archivedBy ?? null;
168 | return this;
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/Member.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | APIAboutInfo,
3 | APIAlias,
4 | APIMember,
5 | APISocialLink,
6 | APIUserStatus,
7 | MembershipRole,
8 | } from '@guildedjs/guilded-api-typings';
9 |
10 | import { Base } from './Base';
11 | import type { Client } from './Client';
12 | import { TeamMemberRoleManager } from './managers/TeamMemberRoleManager';
13 | import type { Team } from './Team';
14 |
15 | /**
16 | * A member of a team
17 | */
18 | export class Member extends Base {
19 | /**
20 | * The current username of this member
21 | */
22 | public name!: string;
23 |
24 | /**
25 | * The current nickname of this member in this team
26 | */
27 | public nickname: string | null;
28 |
29 | /**
30 | * Badges belonging to this member
31 | */
32 | public badges: string[] | null;
33 |
34 | /**
35 | * The date in which this member joined
36 | */
37 | public joinDate: Date;
38 |
39 | /**
40 | * Unknown purpose
41 | */
42 | public membershipRole!: MembershipRole;
43 |
44 | /**
45 | * The last date in which this member was detected to be online
46 | */
47 | public lastOnline: Date | null;
48 |
49 | /**
50 | * The profile picture belonging to this member
51 | */
52 | public profilePicture: string | null;
53 |
54 | /**
55 | * The blurred out banner belonging to this member
56 | */
57 | public profileBannerBlur: string | null;
58 |
59 | /**
60 | * Additional info regarding this member
61 | */
62 | public aboutInfo: APIAboutInfo | null;
63 |
64 | /**
65 | * This members current detected status
66 | */
67 | public userStatus!: APIUserStatus;
68 |
69 | /**
70 | * Connections that this member has to other social media platforms
71 | */
72 | public socialLinks: APISocialLink[] | null;
73 |
74 | /**
75 | * The IDs of the roles that this member has
76 | */
77 | public roleIDs: number[] | null;
78 |
79 | /**
80 | * Unknown purpose
81 | */
82 | public subscriptionType: string | null;
83 |
84 | /**
85 | * Aliases this member may have on games
86 | */
87 | public aliases: APIAlias[];
88 |
89 | /**
90 | * Unknown purpose
91 | */
92 | public userPresenceStatus!: number;
93 |
94 | /**
95 | * The amount of XP this member has in this team
96 | */
97 | public teamXp!: number;
98 |
99 | /**
100 | * The manager in charge of managing the roles this member has
101 | */
102 | public roles: TeamMemberRoleManager;
103 | public constructor(client: Client, data: APIMember, public team: Team | null) {
104 | super(client, data);
105 | this.roles = new TeamMemberRoleManager(client, this);
106 | this.joinDate = new Date(data.joinDate);
107 | this.badges = [];
108 | this.nickname = null;
109 | this.lastOnline = null;
110 | this.profilePicture = null;
111 | this.profileBannerBlur = null;
112 | this.aboutInfo = null;
113 | this.socialLinks = [];
114 | this.roleIDs = [];
115 | this.subscriptionType = null;
116 | this.aliases = [];
117 |
118 | this.patch(data);
119 | }
120 |
121 | /**
122 | * Update the data in this structure
123 | * @internal
124 | */
125 | public patch(data: APIMember | Partial): this {
126 | if ('name' in data && data.name !== undefined) this.name = data.name;
127 | if ('nickname' in data && data.nickname !== undefined) this.nickname = data.nickname;
128 | if ('badges' in data && data.badges !== undefined) this.badges = data.badges;
129 | if ('membershipRole' in data && data.membershipRole !== undefined) this.membershipRole = data.membershipRole;
130 | if ('lastOnline' in data && data.lastOnline !== undefined) {
131 | this.lastOnline = data.lastOnline ? new Date(data.lastOnline) : null;
132 | }
133 | if ('profilePicture' in data && data.profilePicture !== undefined) this.profilePicture = data.profilePicture;
134 | if ('profileBannerBlur' in data && data.profileBannerBlur !== undefined) {
135 | this.profileBannerBlur = data.profileBannerBlur;
136 | }
137 | if ('aboutInfo' in data && data.aboutInfo !== undefined) this.aboutInfo = data.aboutInfo;
138 | if ('userStatus' in data && data.userStatus !== undefined) this.userStatus = data.userStatus;
139 | if ('socialLinks' in data && data.socialLinks !== undefined) this.socialLinks = data.socialLinks;
140 | if ('roleIds' in data && data.roleIds !== undefined) this.roleIDs = data.roleIds;
141 | if ('subscriptionType' in data && data.subscriptionType !== undefined) {
142 | this.subscriptionType = data.subscriptionType;
143 | }
144 | if ('aliases' in data && data.aliases !== undefined) this.aliases = data.aliases;
145 | if ('userPresenceStatus' in data && data.userPresenceStatus !== undefined) {
146 | this.userPresenceStatus = Number(data.userPresenceStatus);
147 | }
148 | if ('teamXp' in data && data.teamXp !== undefined) this.teamXp = data.teamXp;
149 |
150 | return this;
151 | }
152 |
153 | public kick(): Promise {
154 | return this.client.teams.kickMember(this.team!, this);
155 | }
156 |
157 | public setNickname(newNickname: string): Promise {
158 | return this.client.teams.setMemberNickname(this.team!, this, newNickname);
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/Role.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | APITeamChannelRolePermissionOverwrite,
3 | APITeamRole,
4 | RolePermissions,
5 | } from '@guildedjs/guilded-api-typings';
6 |
7 | import { retrieveTeamFromStructureCache } from '../util';
8 | import { Base } from './Base';
9 | import type { TeamChannel } from './Channel';
10 | import type { Client } from './Client';
11 | import type { Team } from './Team';
12 |
13 | /**
14 | * A role belonging to a team
15 | */
16 | export class Role extends Base {
17 | /**
18 | * Whether this role is mentionable.
19 | */
20 | public mentionable!: boolean;
21 |
22 | /**
23 | * The base permissions this role has.
24 | */
25 | public permissions!: RolePermissions;
26 |
27 | /**
28 | * Whether this role is hoisted or not.
29 | */
30 | public hoisted!: boolean;
31 |
32 | /**
33 | * Discord sync'ed role info.
34 | */
35 | public discord: { roleID: string | null; syncedAt: Date | null };
36 |
37 | /**
38 | * Whether this role is self assignable by others.
39 | */
40 | public selfAssignable!: boolean;
41 |
42 | /**
43 | * Date this role was created on.
44 | * @readonly
45 | */
46 | public readonly createdAt: Date;
47 |
48 | /**
49 | * ID of the team this role belongs to.
50 | */
51 | public readonly teamID: string;
52 |
53 | /**
54 | * Date this role was last updated on.
55 | */
56 | public updatedAt: Date | null;
57 |
58 | /**
59 | * The position of this role.
60 | */
61 | public priority!: number;
62 |
63 | /**
64 | * The color of this role.
65 | */
66 | public color!: string;
67 |
68 | /**
69 | * The name of this role.
70 | */
71 | public name!: string;
72 |
73 | public constructor(client: Client, data: APITeamRole, private _team: Team | null) {
74 | super(client, data);
75 | this.discord = { roleID: null, syncedAt: null };
76 | this.createdAt = new Date(data.createdAt);
77 | this.updatedAt = null;
78 | this.teamID = data.teamId;
79 | this.patch(data);
80 | }
81 |
82 | public get team(): Team | null {
83 | return retrieveTeamFromStructureCache({
84 | _team: this._team,
85 | client: this.client,
86 | teamID: this.teamID,
87 | });
88 | }
89 |
90 | /**
91 | * Update the data in this structure
92 | * @internal
93 | */
94 | public patch(data: APITeamRole | Partial): this {
95 | if ('permissions' in data && data.permissions) this.permissions = data.permissions;
96 | if ('isMentionable' in data && data.isMentionable) this.mentionable = data.isMentionable;
97 | if ('isDisplayedSeparately' in data && data.isDisplayedSeparately) this.hoisted = data.isDisplayedSeparately;
98 | if ('discordRoleId' in data && data.discordRoleId !== undefined) this.discord.roleID = data.discordRoleId;
99 | if ('discordSyncedAt' in data && data.discordSyncedAt !== undefined) {
100 | this.discord.syncedAt = data.discordSyncedAt ? new Date(data.discordSyncedAt) : null;
101 | }
102 | if ('isSelfAssignable' in data && data.isSelfAssignable) this.selfAssignable = data.isSelfAssignable;
103 | if ('updatedAt' in data && data.updatedAt !== undefined) {
104 | this.updatedAt = data.updatedAt ? new Date(data.updatedAt) : null;
105 | }
106 | if ('priority' in data && data.priority) this.priority = data.priority;
107 | if ('color' in data && data.color) this.color = data.color;
108 | if ('name' in data && data.name) this.name = data.name;
109 |
110 | return this;
111 | }
112 | }
113 |
114 | /**
115 | * Object representing permission overwrites for a role on a team channel.
116 | */
117 | export class RolePermissionOverwrite {
118 | /**
119 | * The ID of the team this overwrite belongs to.
120 | */
121 | public readonly teamID: string;
122 |
123 | /**
124 | * The ID of the channel this overwrite belongs to.
125 | */
126 | public readonly channelID: string;
127 |
128 | /**
129 | * Date this overwrite was created on.
130 | */
131 | public readonly createdAt: Date;
132 |
133 | /**
134 | * Date this overwrite was last updated on.
135 | */
136 | public readonly updatedAt: Date | null;
137 |
138 | /**
139 | * The ID of the role this overwrite belongs to.
140 | */
141 | public readonly teamRoleID: string;
142 |
143 | /**
144 | * The permissions this overwrite currently has denied.
145 | */
146 | public readonly denyPermissions: RolePermissions;
147 |
148 | /**
149 | * The permissions this overwrite currently has allowed.
150 | */
151 | public readonly allowPermissions: RolePermissions;
152 |
153 | public constructor(
154 | public client: Client,
155 | data: APITeamChannelRolePermissionOverwrite,
156 | public channel: TeamChannel,
157 | ) {
158 | this.teamID = data.teamId;
159 | this.channelID = data.channelId;
160 | this.createdAt = new Date(data.createdAt);
161 | this.updatedAt = data.updatedAt ? new Date(data.updatedAt) : null;
162 | this.teamRoleID = data.teamRoleId.toString();
163 | this.denyPermissions = data.denyPermissions;
164 | this.allowPermissions = data.allowPermissions;
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/Webhook.ts:
--------------------------------------------------------------------------------
1 | import type { APIWebhook } from '@guildedjs/guilded-api-typings';
2 |
3 | import {
4 | retrieveChannelFromStructureCache,
5 | retrieveCreatorFromStructureCache,
6 | retrieveTeamFromStructureCache,
7 | } from '../util';
8 | import { Base } from './Base';
9 | import type { TeamChannel } from './Channel';
10 | import type { Client } from './Client';
11 | import type { Team } from './Team';
12 | import type { User } from './User';
13 |
14 | /**
15 | * Object representing received webhook data. This object is NOT to be used to send data to webhooks. That will be WebhookClient
16 | */
17 | export class Webhook extends Base {
18 | /**
19 | * The username belonging to this webhook
20 | */
21 | public name!: string;
22 |
23 | /**
24 | * The ID of the channel this webhook belongs to
25 | */
26 | public channelID: string;
27 |
28 | /**
29 | * The ID of the team this webhook belongs to
30 | */
31 | public teamID: string;
32 |
33 | /**
34 | * The URL of the avatar belonging to this webhook
35 | */
36 | public iconURL: string | null;
37 |
38 | /**
39 | * The ID of the user who created this webhook
40 | */
41 | public createdByID: string;
42 |
43 | /**
44 | * The date in which this webhook was created
45 | */
46 | public createdAt: Date;
47 |
48 | /**
49 | * The date this webhook was deleted if it was deleted
50 | */
51 | public deletedAt: Date | null;
52 |
53 | private _team: Team | null;
54 | private _createdBy: User | null;
55 |
56 | public constructor(client: Client, data: APIWebhook, private _channel: TeamChannel | null) {
57 | super(client, data);
58 | this.createdAt = new Date(data.createdAt);
59 | this.deletedAt = null;
60 | this.iconURL = null;
61 | this.createdByID = data.createdBy;
62 | this.channelID = data.channelId;
63 | this.teamID = data.teamId;
64 | this._team = _channel?.team ?? null;
65 | this._createdBy = null;
66 | this.patch(data);
67 | }
68 |
69 | /**
70 | * The channel object this webhook belongs to if cached
71 | */
72 | public get channel(): TeamChannel | null {
73 | return retrieveChannelFromStructureCache({
74 | _channel: this._channel,
75 | channelID: this.channelID,
76 | client: this.client,
77 | }) as TeamChannel | null;
78 | }
79 |
80 | /**
81 | * The User object of the user that created this webhook if cached
82 | */
83 | public get createdBy(): User | null {
84 | return retrieveCreatorFromStructureCache({
85 | _createdBy: this._createdBy,
86 | client: this.client,
87 | createdByID: this.createdByID,
88 | });
89 | }
90 |
91 | /**
92 | * The team object this webhook belongs to if cached
93 | */
94 | public get team(): Team | null {
95 | return retrieveTeamFromStructureCache({
96 | _team: this._team,
97 | client: this.client,
98 | teamID: this.teamID,
99 | });
100 | }
101 |
102 | /**
103 | * Update the data in this structure
104 | * @internal
105 | */
106 | public patch(data: APIWebhook | Partial): this {
107 | if ('name' in data && data.name !== undefined) this.name = data.name;
108 | if ('iconUrl' in data && data.iconUrl !== undefined) this.iconURL = data.iconUrl;
109 | if ('deletedAt' in data && data.deletedAt !== undefined) {
110 | this.deletedAt = data.deletedAt ? new Date(data.deletedAt) : null;
111 | }
112 |
113 | return this;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@guildedjs/embeds';
2 | export * from '@guildedjs/webhook-client';
3 | export * from './Channel';
4 | export * from './Client';
5 | export * from './Group';
6 | export * from './Member';
7 | export * from './Message';
8 | export * from './Role';
9 | export * from './Team';
10 | export * from './User';
11 | export * from './Webhook';
12 | export * from './managers';
13 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/BaseManager.ts:
--------------------------------------------------------------------------------
1 | import { CacheCollection, CacheCollectionOptions } from '@guildedjs/common';
2 |
3 | import type { BaseData, constructable } from '../../typings';
4 | import { Base } from '../Base';
5 | import type { Client } from '../Client';
6 |
7 | /**
8 | * The manager in charge of cached objects and potential api endpoints
9 | * @param K The base amount of data required to construct object T
10 | * @param T The object that will be held in this manager
11 | */
12 | export class BaseManager> {
13 | public cache: CacheCollection = new CacheCollection(this.cacheOptions ?? {});
14 | public constructor(
15 | public readonly client: Client,
16 | public readonly holds: constructable,
17 | public readonly cacheOptions?: CacheCollectionOptions,
18 | ) {}
19 |
20 | /**
21 | * Add an object, potential data, or constructor params into this managers cache
22 | * @private
23 | */
24 | public add(data: T | K | Partial | ConstructorParameters>): T | null {
25 | if (this.isConstructorParamsOfHolds(data)) {
26 | const addition = new this.holds(...data);
27 | this.cache.set(addition.id.toString(), addition);
28 | return addition;
29 | } else if (this.isInstanceOfHolds(data)) {
30 | this.cache.set(data.id.toString(), data);
31 | return data;
32 | } else {
33 | const existing = data.id ? this.cache.get(data.id.toString()) : null;
34 | if (existing) {
35 | existing.patch(data as K | Partial);
36 | }
37 | return existing ?? null;
38 | }
39 | }
40 |
41 | private isConstructorParamsOfHolds(
42 | data: ConstructorParameters> | unknown,
43 | ): data is ConstructorParameters> {
44 | return Array.isArray(data);
45 | }
46 |
47 | private isInstanceOfHolds(data: T | K | Partial): data is T {
48 | return data instanceof this.holds;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/ChannelManager.ts:
--------------------------------------------------------------------------------
1 | import { generateMessage, parseToMessage } from '@guildedjs/common';
2 | import Embed from '@guildedjs/embeds';
3 | import type {
4 | APIGetChannelMessageResult,
5 | APIMessage,
6 | APIPostChannelMessagesResult,
7 | APITeamChannel,
8 | } from '@guildedjs/guilded-api-typings';
9 |
10 | import { DMChannel, PartialChannel, TeamChannel } from '../Channel';
11 | import type { Client } from '../Client';
12 | import { Message, PartialMessage } from '../Message';
13 | import { BaseManager } from './BaseManager';
14 | import { MessageManager } from './MessageManager';
15 |
16 | export class ChannelManager extends BaseManager {
17 | public constructor(client: Client) {
18 | super(client, PartialChannel, { maxSize: client.options?.cache?.cacheMaxSize?.channelsCache });
19 | }
20 |
21 | public static resolve(channel: string | PartialChannel): string {
22 | return channel instanceof PartialChannel ? channel.id : channel;
23 | }
24 |
25 | /**
26 | * Send a message to a channel, using either the object or channel ID.
27 | * @param channel The ID or channel object of the target channel to send this message to
28 | */
29 | public sendMessage(
30 | channel: string | PartialChannel,
31 | content: string | Embed,
32 | embed?: Embed,
33 | ): Promise {
34 | const channelID = ChannelManager.resolve(channel);
35 | const [messageID, formattedContent] = generateMessage(content, embed);
36 | return this.client.rest
37 | .post(`/channels/${channelID}/messages`, { ...formattedContent, messageId: messageID })
38 | .then(x =>
39 | 'id' in x
40 | ? new Message(
41 | this.client,
42 | x,
43 | channel instanceof PartialChannel ? channel : this.client.channels.add({ id: channel })!,
44 | )
45 | : messageID,
46 | );
47 | }
48 |
49 | /**
50 | * Fetch a message from a channel from the API
51 | * @param channel The ID or channel object of the taret channel to fetch the message from.
52 | * @param message The ID, message object, or partial message object of the message to fetch.
53 | * @param cache Whether to cache the fetched message or not.
54 | */
55 | public fetchMessage(
56 | channel: string | PartialChannel,
57 | message: string | Message | PartialMessage,
58 | ): Promise {
59 | const channelID = ChannelManager.resolve(channel);
60 | const messageID = MessageManager.resolve(message);
61 | return this.client.rest
62 | .get(`/channels/${channelID}/chat?messageId=${messageID}`)
63 | .then(x => {
64 | let targetChannel =
65 | channel instanceof PartialChannel ? channel : this.client.channels.cache.get(channelID);
66 | if (!channel) {
67 | targetChannel = new PartialChannel(this.client, { id: x.channelId }, null);
68 | this.client.channels.add(targetChannel);
69 | }
70 | const newMessage = new Message(this.client, x, targetChannel!);
71 | targetChannel!.messages!.cache.set(newMessage.id, newMessage);
72 | return newMessage;
73 | });
74 | }
75 |
76 | /**
77 | * Delete a message from a channel.
78 | * @param channel The ID or channel object of the channel to delete the message from.
79 | * @param msg The ID or message object of the message to delete.
80 | */
81 | public deleteMessage(channel: string | PartialChannel, msg: string | Message): Promise {
82 | if (!msg) throw new TypeError('Expected a string or message object for message deletion.');
83 | const channelID = ChannelManager.resolve(channel);
84 | const messageID = MessageManager.resolve(msg);
85 | return this.client.rest.delete(`/channels/${channelID}/messages/${messageID}`).then(() => {
86 | const existingChannel = this.cache.get(channelID);
87 | const existingMessage = existingChannel?.messages?.cache.get(messageID);
88 |
89 | if (existingMessage) existingMessage.deleted = true;
90 | return existingMessage ?? messageID;
91 | });
92 | }
93 |
94 | /**
95 | * Edit a message
96 | * @hidden
97 | */
98 | public editMessage(channel: string | PartialChannel, msg: string | Message, newContent: string): Promise {
99 | const channelID = ChannelManager.resolve(channel);
100 | const messageID = MessageManager.resolve(msg);
101 | return this.client.rest
102 | .put(`/channels/${channelID}/messages/${messageID}`, { content: parseToMessage(newContent) })
103 | .then(x => {
104 | const existingChannel = this.client.channels.cache.get(x.channelId);
105 | if (!existingChannel) return new Message(this.client, x, null);
106 | const existingMessage = existingChannel.messages!.cache.get(x.id);
107 | if (existingMessage) return existingMessage.patch(x);
108 | return existingChannel.messages!.add(x)!;
109 | });
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/MessageManager.ts:
--------------------------------------------------------------------------------
1 | import Collection from '@discordjs/collection';
2 | import type { APIGetChannelMessages, APIMessage } from '@guildedjs/guilded-api-typings';
3 |
4 | import { UpgradedMessageData } from '../../typings';
5 | import type { DMChannel, PartialChannel, TeamChannel } from '../Channel';
6 | import type { Client } from '../Client';
7 | import { Message, PartialMessage } from '../Message';
8 | import { BaseManager } from './BaseManager';
9 | import { ChannelManager } from './ChannelManager';
10 |
11 | export class MessageManager extends BaseManager {
12 | public constructor(client: Client, public readonly channel: TeamChannel | DMChannel | PartialChannel) {
13 | super(client, Message, { maxSize: client.options?.cache?.cacheMaxSize?.messagesCache });
14 | }
15 |
16 | public static resolve(message: string | Message | PartialMessage): string {
17 | return message instanceof Message || message instanceof PartialMessage ? message.id : message;
18 | }
19 |
20 | /**
21 | * Edit a message
22 | */
23 | public edit(msg: string | Message, newContent: string): Promise {
24 | return this.client.channels.editMessage(this.channel.id, msg, newContent);
25 | }
26 |
27 | /**
28 | * Delete a message
29 | */
30 | public delete(msg: string | Message): Promise {
31 | return this.client.channels.deleteMessage(this.channel.id, msg);
32 | }
33 |
34 | /**
35 | * Add a reaction to this message
36 | */
37 | public react(message: string | Message, channel: string | PartialChannel, emoji: string): unknown {
38 | const messageID = MessageManager.resolve(message);
39 | const channelID = ChannelManager.resolve(channel);
40 | return this.client.rest.post(`/channels/${channelID}/messages/${messageID}/reactions/${emoji}`, {});
41 | }
42 |
43 | /**
44 | * Remove a reaction from this message
45 | */
46 | public unreact(message: string | Message, channel: string | PartialChannel, emoji: string): unknown {
47 | const messageID = MessageManager.resolve(message);
48 | const channelID = ChannelManager.resolve(channel);
49 | return this.client.rest.delete(`/channels/${channelID}/messages/${messageID}/reactions/${emoji}`, {});
50 | }
51 |
52 | /**
53 | * Fetch multiple messages from the channel this manager belongs to
54 | * @param amnt The amount of messages to fetch.
55 | * @param cache Whether to cache the fetched messages or not.
56 | */
57 | public fetch(amnt: number, cache = true): Promise> {
58 | if (Number.isNaN(amnt)) throw new TypeError('Expected a number for message fetching amount!');
59 | if (amnt > 100) amnt = 100;
60 | if (amnt < 0) amnt = 1;
61 | const messages: Collection = new Collection();
62 | return this.client.rest
63 | .get(`/channels/${this.channel.id}/messages?limit=${amnt}`)
64 | .then(x => {
65 | for (const message of x.messages) {
66 | const tempMessage = this.add([this.client, message, this.channel]);
67 | messages.set(message.id, tempMessage!);
68 | if (cache) this.add(tempMessage!);
69 | }
70 | return messages;
71 | });
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamGroupChannelManager.ts:
--------------------------------------------------------------------------------
1 | import type { APITeamChannel, CHANNEL_TYPES } from '@guildedjs/guilded-api-typings';
2 |
3 | import { TeamChannel } from '../Channel';
4 | import type { Client } from '../Client';
5 | import type { Group } from '../Group';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamGroupChannelManager extends BaseManager {
9 | public constructor(client: Client, public group: Group) {
10 | super(client, TeamChannel, { maxSize: client.options?.cache?.cacheMaxSize?.channelsCache });
11 | }
12 |
13 | /**
14 | * Create a channel in the group this manager belongs to.
15 | */
16 | public create({
17 | name,
18 | parent,
19 | type,
20 | isPublic = true,
21 | }: {
22 | name: string;
23 | parent?: string;
24 | type: CHANNEL_TYPES;
25 | isPublic: boolean;
26 | }): Promise {
27 | return this.client.rest.post(`/teams/${this.group.team?.id}/groups/${this.group.id}/channels`, {
28 | channelCategoryId: parent,
29 | contentType: type,
30 | isPublic: isPublic,
31 | name,
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamGroupManager.ts:
--------------------------------------------------------------------------------
1 | import type { APIGroup } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import { Group } from '../Group';
5 | import type { Team } from '../Team';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamGroupManager extends BaseManager {
9 | public constructor(client: Client, public readonly team: Team) {
10 | super(client, Group, { maxSize: client.options?.cache?.cacheMaxSize?.groupsCache });
11 | }
12 |
13 | public static resolve(group: string | Group): string {
14 | return group instanceof Group ? group.id : group;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamManager.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | APIGetTeam,
3 | APIPartialTeam,
4 | APIPostCreateInviteResult,
5 | APITeam,
6 | CHANNEL_CONTENT_TYPES,
7 | } from '@guildedjs/guilded-api-typings';
8 |
9 | import { TeamChannel } from '../Channel';
10 | import type { Client } from '../Client';
11 | import { Group } from '../Group';
12 | import { Member } from '../Member';
13 | import { Role } from '../Role';
14 | import { Team } from '../Team';
15 | import { BaseManager } from './BaseManager';
16 | import { TeamGroupManager } from './TeamGroupManager';
17 | import { TeamMemberManager } from './TeamMemberManager';
18 |
19 | export class TeamManager extends BaseManager {
20 | public constructor(client: Client) {
21 | super(client, Team, { maxSize: client.options?.cache?.cacheMaxSize?.teamsCache });
22 | }
23 |
24 | public static resolve(team: string | Team): string {
25 | return team instanceof Team ? team.id : team;
26 | }
27 |
28 | /**
29 | * Add a role to a TeamMember
30 | * @param team The ID or team object of the Team the target member is in.
31 | * @param member The ID or member object of the Member that will have the role added to them.
32 | * @param role The ID or role object of the Role to add to the member.
33 | */
34 | public addRoleToMember(team: string | Team, member: string | Member, role: string | Role): Promise {
35 | const roleID = role instanceof Role ? role.id : role;
36 | const memberID = TeamMemberManager.resolve(member);
37 | const teamID = TeamManager.resolve(team);
38 | return this.client.rest.put(`/teams/${teamID}/roles/${roleID}/users/${memberID}`).then(() => void 0);
39 | }
40 |
41 | /**
42 | * Remove a role from a TeamMember
43 | * @param team The ID or team object of the Team the target member is in.
44 | * @param member The ID or member object of the Member that will have the role removed from them.
45 | * @param role The ID or role object of the Role to remove from the member.
46 | */
47 | public removeRoleFromMember(team: string | Team, member: string | Member, role: string | Role): Promise {
48 | const roleID = role instanceof Role ? role.id : role;
49 | const memberID = TeamMemberManager.resolve(member);
50 | const teamID = TeamManager.resolve(team);
51 | return this.client.rest.delete(`/teams/${teamID}/roles/${roleID}/users/${memberID}`).then(() => void 0);
52 | }
53 |
54 | /**
55 | * Kick a TeamMember
56 | * @param team The ID or team object of the Team the target member is in.
57 | * @param member The ID or member object of the Member that will be kicked
58 | */
59 | public kickMember(team: string | Team, member: string | Member): Promise {
60 | const memberID = TeamMemberManager.resolve(member);
61 | const teamID = TeamManager.resolve(team);
62 | return this.client.rest.delete(`/teams/${teamID}/members/${memberID}`).then(() => void 0);
63 | }
64 |
65 | /**
66 | * Set a TeamMember's name
67 | * @param team The ID or team object of the Team the target member is in.
68 | * @param member The ID or member object of the Member that will be renamed.
69 | * @param newNickname The new nickname to give to the Member.
70 | */
71 | public setMemberNickname(team: string | Team, member: string | Member, newNickname: string): Promise {
72 | if (typeof newNickname !== 'string') throw new TypeError('Nickname must be a string!');
73 | const memberID = TeamMemberManager.resolve(member);
74 | const teamID = TeamManager.resolve(team);
75 | return this.client.rest
76 | .put(`/teams/${teamID}/members/${memberID}/nickname`, { nickname: newNickname })
77 | .then(() => void 0);
78 | }
79 |
80 | /**
81 | * Creates an Invite for the Team
82 | * @param team The ID or team object of the Team.
83 | * @returns The ID of the created Invite
84 | */
85 | public createInvite(team: string | Team): Promise {
86 | const teamID = TeamManager.resolve(team);
87 | return this.client.rest.post(`/teams/${teamID}/invites`, { teamId: teamID }).then(x => x.invite);
88 | }
89 |
90 | public deleteInvite(team: string | Team, inviteID: string): Promise {
91 | if (typeof inviteID !== 'string') throw new TypeError('InviteID must be a string!');
92 | const teamID = TeamManager.resolve(team);
93 | return this.client.rest.delete(`/teams/${teamID}/invites/${inviteID}`).then(x => x.id);
94 | }
95 |
96 | /**
97 | * Creates a Teamchannel
98 | * @param team
99 | * @param group
100 | * @param name
101 | * @param contentType
102 | * @param channelCategoryId
103 | * @param isPublic
104 | * @returns
105 | */
106 |
107 | public createChannel(
108 | team: string | Team,
109 | group: string | Group,
110 | name: string,
111 | contentType: CHANNEL_CONTENT_TYPES,
112 | channelCategoryId: number | null = null,
113 | isPublic = false,
114 | ): Promise {
115 | if (typeof name !== 'string') {
116 | throw new TypeError('Name must be a string!');
117 | }
118 | const teamID = TeamManager.resolve(team);
119 | const groupID = TeamGroupManager.resolve(group);
120 | return this.client.rest.post(`/teams/${teamID}/groups/${groupID}`, {
121 | channelCategoryId,
122 | contentType,
123 | isPublic,
124 | name,
125 | });
126 | // .then(x => new TeamChannel(this.client, x, null, null));
127 | }
128 |
129 | /**
130 | * Fetch a team, will retrieve from cache if exists
131 | * @param id the ID of the team to fetch.
132 | * @param cache Whether to cache the fetched Team or not.
133 | */
134 | public fetch(id: string, cache = true): Promise {
135 | return this.client.rest.get(`/teams/${id}`).then(data => {
136 | const cachedTeam = this.client.teams.cache.get(id);
137 |
138 | if (cache && cachedTeam) {
139 | cachedTeam.patch(data.team);
140 | for (const member of data.team.members) {
141 | const existingMember = cachedTeam.members.cache.get(member.id);
142 | if (existingMember) existingMember.patch(member);
143 | else cachedTeam.members.cache.set(member.id, new Member(this.client, member, cachedTeam));
144 | }
145 | }
146 |
147 | return cachedTeam ?? new Team(this.client, data.team);
148 | });
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamMemberManager.ts:
--------------------------------------------------------------------------------
1 | import type { APIMember } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import { Member } from '../Member';
5 | import type { Team } from '../Team';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamMemberManager extends BaseManager {
9 | public constructor(client: Client, public readonly team: Team) {
10 | super(client, Member, { maxSize: client.options?.cache?.cacheMaxSize?.membersCache });
11 | }
12 |
13 | public static resolve(member: string | Member): string {
14 | return member instanceof Member ? member.id : member;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamMemberRoleManager.ts:
--------------------------------------------------------------------------------
1 | import type { APITeamRole } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import type { Member } from '../Member';
5 | import { Role } from '../Role';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamMemberRoleManager extends BaseManager {
9 | public constructor(client: Client, public readonly member: Member) {
10 | super(client, Role, { maxSize: client.options?.cache?.cacheMaxSize?.memberRolesCache });
11 | }
12 |
13 | /**
14 | * Shortcut for adding a role to a member.
15 | * @param role The ID or Role object of the role to add to the member.
16 | * @see {@link https://zaida04.github.io/guildedjs-selfbot-docs/classes/guilded_js.teammanager.html#addroletomember}
17 | */
18 | public append(role: string | Role): Promise {
19 | return this.client.teams.addRoleToMember(this.member.team!.id, this.member, role);
20 | }
21 |
22 | /**
23 | * Shortcut for removing a role from a member.
24 | * @param role The ID or Role object of the role to add to the member.
25 | * @see {@link https://zaida04.github.io/guildedjs-selfbot-docs/classes/guilded_js.teammanager.html#removerolefrommember}
26 | */
27 | public remove(role: string | Role): Promise {
28 | return this.client.teams.removeRoleFromMember(this.member.team!.id, this.member, role);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamRoleManager.ts:
--------------------------------------------------------------------------------
1 | import type { APITeamRole } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import { Role } from '../Role';
5 | import { Team } from '../Team';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamRoleManager extends BaseManager {
9 | public constructor(client: Client, public readonly team: Team) {
10 | super(client, Role, { maxSize: client.options?.cache?.cacheMaxSize?.memberRolesCache });
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/TeamWebhookManager.ts:
--------------------------------------------------------------------------------
1 | import type { APIWebhook } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import type { Team } from '../Team';
5 | import { Webhook } from '../Webhook';
6 | import { BaseManager } from './BaseManager';
7 |
8 | export class TeamWebhookManager extends BaseManager {
9 | public constructor(client: Client, public readonly team: Team) {
10 | super(client, Webhook, { maxSize: client.options?.cache?.cacheMaxSize?.teamWebhooksCache });
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/UserManager.ts:
--------------------------------------------------------------------------------
1 | import type { APIGetUser, APIUser } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../Client';
4 | import { User } from '../User';
5 | import { BaseManager } from './BaseManager';
6 |
7 | export class UserManager extends BaseManager {
8 | public constructor(client: Client) {
9 | super(client, User, { maxSize: client.options?.cache?.cacheMaxSize?.usersCache });
10 | }
11 |
12 | /**
13 | * Fetch a user, retrieves from the cache if exists
14 | */
15 | public fetch(id: string, cache = true, force = false): Promise {
16 | const existing = force ? null : this.cache.get(id);
17 | if (existing) return Promise.resolve(existing);
18 |
19 | return this.client.rest.get(`/users/${id}`).then(x => {
20 | const tempUser = new User(this.client, x.user);
21 | if (cache) this.client.users.cache.set(tempUser.id, tempUser);
22 | return tempUser;
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/structures/managers/index.ts:
--------------------------------------------------------------------------------
1 | export * from './BaseManager';
2 | export * from './ChannelManager';
3 | export * from './MessageManager';
4 | export * from './TeamGroupChannelManager';
5 | export * from './TeamGroupManager';
6 | export * from './TeamManager';
7 | export * from './TeamMemberManager';
8 | export * from './TeamMemberRoleManager';
9 | export * from './TeamWebhookManager';
10 | export * from './UserManager';
11 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/typings.ts:
--------------------------------------------------------------------------------
1 | import { APIMessage, APIPartialMessage } from '@guildedjs/guilded-api-typings';
2 |
3 | /**
4 | * The minimum amount of data that is needed to construct any structure
5 | * @internal
6 | */
7 | export interface BaseData {
8 | readonly id: string;
9 | }
10 |
11 | /**
12 | * Adapted from https://github.com/discordjs/discord.js/blob/master/typings/index.d.ts#L2051
13 | * @internal
14 | */
15 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
16 | export type constructable = new (...args: any[]) => T;
17 |
18 | export interface PartialMessageData extends APIPartialMessage {
19 | channelId: string;
20 | }
21 |
22 | export interface UpgradedMessageData extends APIMessage {
23 | teamId?: string | null;
24 | }
25 |
26 | /* eslint-disable @typescript-eslint/naming-convention */
27 | export enum websocket_events {
28 | CHAT_MESSAGE_CREATED = 'ChatMessageCreated',
29 | CHAT_MESSAGE_UPDATED = 'ChatMessageUpdated',
30 | CHAT_MESSAGE_REACTION_ADDED = 'ChatMessageReactionAdded',
31 | CHAT_MESSAGE_REACTION_DELETED = 'ChatMessageReactionDeleted',
32 | }
33 |
34 | export enum events {
35 | MESSAGE_CREATE = 'messageCreate',
36 | MESSAGE_UPDATE = 'messageUpdate',
37 | MESSAGE_REACTION_ADD = 'messageReactionAdd',
38 | MESSAGE_REACTION_DELETE = 'messageReactionDelete',
39 | READY = 'ready',
40 | }
41 |
42 | export type clientPartial = 'MEMBER' | 'MESSAGE' | 'USER' | 'CHANNEL';
43 |
44 | /**
45 | * Options you can instantiate the client with.
46 | */
47 | export interface ClientOptions {
48 | partials?: clientPartial[];
49 | cache?: {
50 | startupRestrictions?: {
51 | dropDMs?: boolean;
52 | dropTeams?: boolean;
53 | dropChannels?: boolean;
54 | };
55 | cacheMaxSize?: {
56 | teamsCache?: number;
57 | channelsCache?: number;
58 | usersCache?: number;
59 | membersCache?: number;
60 | memberRolesCache?: number;
61 | teamRolesCache?: number;
62 | teamWebhooksCache?: number;
63 | groupsCache?: number;
64 | messagesCache?: number;
65 | };
66 | disableTeam?: boolean;
67 | disableChannels?: boolean;
68 | disableUsers?: boolean;
69 | disableMembers?: boolean;
70 | disableMembersRoles?: boolean;
71 | disableTeamRoles?: boolean;
72 | disableWebhooks?: boolean;
73 | disableGroups?: boolean;
74 | disableMessages?: boolean;
75 | };
76 | ws?: {
77 | heartbeatInterval?: number;
78 | disabledEvents?: events[];
79 | disallowReconnect?: boolean;
80 | reconnectLimit?: number;
81 | blockTeamWSConnection?: boolean;
82 | };
83 | rest?: {
84 | apiURL?: string;
85 | cdnURL?: string;
86 | };
87 | }
88 |
89 | /**
90 | * Options to log the client in with
91 | */
92 | export interface LoginOptions {
93 | email: string;
94 | password: string;
95 | }
96 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/util.ts:
--------------------------------------------------------------------------------
1 | import type { Client, PartialChannel, Team, User } from './structures';
2 |
3 | export function retrieveTeamFromStructureCache({
4 | client,
5 | _team,
6 | teamID,
7 | }: {
8 | client: Client;
9 | _team: Team | null;
10 | teamID: string | null;
11 | }): Team | null {
12 | if (_team) return _team;
13 | if (!teamID) return null;
14 | const cachedTeam = client.teams.cache.get(teamID);
15 | return cachedTeam ?? null;
16 | }
17 |
18 | export function retrieveChannelFromStructureCache({
19 | client,
20 | _channel,
21 | channelID,
22 | }: {
23 | client: Client;
24 | _channel: PartialChannel | null;
25 | channelID: string | null;
26 | }): PartialChannel | null {
27 | if (_channel) return _channel;
28 | if (!channelID) return null;
29 | const cachedChannel = client.channels.cache.get(channelID);
30 | return cachedChannel ?? null;
31 | }
32 |
33 | export function retrieveCreatorFromStructureCache({
34 | client,
35 | _createdBy,
36 | createdByID,
37 | }: {
38 | client: Client;
39 | _createdBy: User | null;
40 | createdByID: string | null;
41 | }): User | null {
42 | if (_createdBy) return _createdBy;
43 | if (!createdByID) return null;
44 | const cachedUser = client.users.cache.get(createdByID);
45 | return cachedUser ?? null;
46 | }
47 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/ClientGatewayHandler.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/naming-convention */
2 | import { ROUTES } from '@guildedjs/common';
3 | import type {
4 | WSChatMessageCreated,
5 | WSChatMessageReactionAdded,
6 | WSChatMessageReactionDeleted,
7 | WSChatMessageUpdated,
8 | WSGatewayReady,
9 | } from '@guildedjs/guilded-api-typings';
10 | import WebSocket from 'ws';
11 |
12 | import type { Client } from '../structures/Client';
13 | import { events, websocket_events } from '../typings';
14 | import ChatMessageCreatedEvent from './events/ChatMessageCreated';
15 | import ChatMessageReactionAddedEvent from './events/ChatMessageReactionAdded';
16 | import ChatMessageReactionDeletedEvent from './events/ChatMessageReactionDeleted';
17 | import ChatMessageUpdatedEvent from './events/ChatMessageUpdated';
18 | import GatewayHandler from './GatewayHandler';
19 |
20 | export class ClientGatewayHandler extends GatewayHandler {
21 | public lastPing: number | null = null;
22 | private reconnectionAmnt = 0;
23 |
24 | public events = {
25 | chatMessageCreated: new ChatMessageCreatedEvent(this.client),
26 | chatMessageReactionAdded: new ChatMessageReactionAddedEvent(this.client),
27 | chatMessageReactionDeleted: new ChatMessageReactionDeletedEvent(this.client),
28 | chatMessageUpdated: new ChatMessageUpdatedEvent(this.client),
29 | };
30 | public constructor(client: Client) {
31 | super(client);
32 | }
33 |
34 | public init(): this | null {
35 | if (this.ws) return this;
36 | // eslint-disable-next-line max-len
37 | const socketURL = `wss://${ROUTES.BASE_DOMAIN}/socket.io/?jwt=undefined&guildedClientId=${this.client.rest.guildedMID}&EIO=3&transport=websocket`;
38 | this.ws = new WebSocket(socketURL, {
39 | headers: {
40 | cookie: `hmac_signed_session=${this.client.rest.token};`,
41 | },
42 | });
43 | this.ws
44 | .on('open', () => (this.connectedAt = new Date()))
45 | .on('message', (incomingData: string) => {
46 | this.client.debug('Gateway message recieved', incomingData);
47 | this.dataRecieved(incomingData);
48 | })
49 | .on('close', (...closeData: unknown[]) => {
50 | this.client.debug(`Gateway connection terminated. Related data: ${closeData}`);
51 | const shouldntReconnect =
52 | this.client.options?.ws?.disallowReconnect ||
53 | this.reconnectionAmnt >= (this.client.options?.ws?.reconnectLimit ?? Infinity);
54 | this.client.destroy(!shouldntReconnect);
55 |
56 | if (shouldntReconnect) return this.client.emit('disconnected', closeData);
57 | this.reconnectionAmnt++;
58 | this.client.emit('reconnecting', closeData);
59 | });
60 | return this;
61 | }
62 |
63 | public dataRecieved(incomingData: string): void {
64 | let data: string = incomingData;
65 | let opCode = '';
66 | for (const char of data) {
67 | if (!Number.isInteger(Number(char))) break;
68 | data = data.substring(1);
69 | opCode += char;
70 | }
71 |
72 | try {
73 | switch (Number(opCode)) {
74 | case 0: {
75 | this.client.debug('Heartbeat started...');
76 |
77 | let packet;
78 | try {
79 | packet = JSON.parse(data) as WSGatewayReady;
80 | } catch (e) {
81 | throw new Error(`malformed payload! ${data}`);
82 | }
83 |
84 | this.sessionID = packet.sid;
85 | this.heartbeater.start(packet.pingInterval);
86 | break;
87 | }
88 |
89 | case 3: {
90 | this.lastPing = Date.now();
91 | this.ping = this.lastPing - this.heartbeater.lastPingSentAt;
92 | this.client.debug('Ping returned. ');
93 | break;
94 | }
95 |
96 | case 40: {
97 | this.client.debug('Ready event recieved.');
98 | this.client.emit(events.READY);
99 | break;
100 | }
101 |
102 | case 42: {
103 | let EVENT_NAME, EVENT_DATA;
104 |
105 | try {
106 | [EVENT_NAME, EVENT_DATA] = JSON.parse(data);
107 | } catch (e) {
108 | throw new Error(`malformed payload! ${data}`);
109 | }
110 |
111 | if (this.client.options?.ws?.disabledEvents?.includes(EVENT_NAME)) return;
112 | this.client.emit('raw', EVENT_NAME, EVENT_DATA);
113 |
114 | let result: (boolean | (string | undefined))[] | undefined;
115 | switch (EVENT_NAME) {
116 | case websocket_events.CHAT_MESSAGE_CREATED: {
117 | result = this.events.chatMessageCreated.ingest(EVENT_DATA as WSChatMessageCreated);
118 | break;
119 | }
120 | case websocket_events.CHAT_MESSAGE_UPDATED: {
121 | result = this.events.chatMessageUpdated.ingest(EVENT_DATA as WSChatMessageUpdated);
122 | break;
123 | }
124 | case websocket_events.CHAT_MESSAGE_REACTION_ADDED: {
125 | result = this.events.chatMessageReactionAdded.ingest(
126 | EVENT_DATA as WSChatMessageReactionAdded,
127 | );
128 | break;
129 | }
130 | case websocket_events.CHAT_MESSAGE_REACTION_DELETED: {
131 | result = this.events.chatMessageReactionDeleted.ingest(
132 | EVENT_DATA as WSChatMessageReactionDeleted,
133 | );
134 | break;
135 | }
136 | }
137 | if (!result?.[0]) {
138 | this.client.debug(
139 | `Event ${EVENT_NAME} dropped because of ${result?.[1] ?? 'unknown reason or not handled'}`,
140 | );
141 | }
142 | break;
143 | }
144 | }
145 | } catch (e) {
146 | this.client.debug('Error parsing WS event', e);
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/GatewayHandler.ts:
--------------------------------------------------------------------------------
1 | import WebSocket from 'ws';
2 |
3 | import type { Client } from '../structures/Client';
4 | import Heartbeater from './Heartbeater';
5 |
6 | export default abstract class GatewayHandler {
7 | public ws!: WebSocket | null;
8 | public heartbeater = new Heartbeater(this);
9 | public ping = 0;
10 | public connectedAt: Date | null = null;
11 | public sessionID: string | null = null;
12 |
13 | public constructor(public readonly client: Client) {}
14 | public abstract init(): void;
15 | public destroy(intentionToReconnect: boolean): void {
16 | if (!this.ws) {
17 | throw Error("Attempting to destroy WS connection that doesn't exist!");
18 | }
19 |
20 | /**
21 | * Credits to: https://github.com/Skillz4Killz/gapi/blob/master/src/websocket/Shard.ts#L186
22 | * AUTHOR: https://github.com/Skillz4Killz
23 | * LICENSE: APACHE LICENSE 2.0 (https://github.com/Skillz4Killz/gapi/blob/master/LICENSE)
24 | */
25 | if (intentionToReconnect && this.sessionID) {
26 | if (this.ws.readyState === WebSocket.OPEN) this.ws?.close(4901, 'Reconnect with session id please');
27 | else this.ws?.terminate();
28 | } else {
29 | this.ws?.close(1000, 'Clean close with no reconnection.');
30 | }
31 |
32 | this.ws.removeAllListeners();
33 | this.ws = null;
34 | this.heartbeater.destroy();
35 |
36 | if (intentionToReconnect) this.init();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/Heartbeater.ts:
--------------------------------------------------------------------------------
1 | import GatewayHandler from './GatewayHandler';
2 |
3 | export default class Heartbeater {
4 | public interval!: NodeJS.Timeout;
5 | public lastPingSentAt = 0;
6 | public active = false;
7 |
8 | public constructor(public gateway: GatewayHandler) {}
9 | public start(interval?: number): void {
10 | this.gateway.client.debug('Heartbeating...');
11 | this.active = true;
12 | this.interval = setInterval(
13 | this.sendHB.bind(this),
14 | interval ?? this.gateway.client.options?.ws?.heartbeatInterval ?? 15000,
15 | );
16 | }
17 |
18 | public destroy(): void {
19 | clearInterval(this.interval);
20 | this.active = false;
21 | }
22 |
23 | public sendHB(): void {
24 | if (!this.gateway.ws) return;
25 | if (this.gateway.ws.readyState !== 1) return;
26 | this.lastPingSentAt = Date.now();
27 | this.gateway.ws.send('2');
28 | this.gateway.client.rest.put('/users/me/ping');
29 | this.gateway.client.debug('heartbeat sent');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/events/ChatMessageCreated.ts:
--------------------------------------------------------------------------------
1 | import { WSChatMessageCreated } from '@guildedjs/guilded-api-typings';
2 |
3 | import { PartialChannel } from '../../structures';
4 | import type { Client } from '../../structures/Client';
5 | import { Message } from '../../structures/Message';
6 | import { events } from '../../typings';
7 | import Event from './Event';
8 |
9 | export default class ChatMessageCreatedEvent extends Event {
10 | public constructor(client: Client) {
11 | super(client);
12 | }
13 | public ingest(data: WSChatMessageCreated): (boolean | (string | undefined))[] {
14 | if (data) {
15 | let channel = this.client.channels.cache.get(data.channelId);
16 | const team = (data.teamId ? this.client.teams.cache.get(data.teamId) : null) ?? null;
17 |
18 | if (!channel) {
19 | channel = new PartialChannel(
20 | this.client,
21 | {
22 | contentType: data.contentType,
23 | createdAt: data.createdAt,
24 | createdBy: data.createdBy,
25 | id: data.channelId,
26 | type: data.channelType,
27 | },
28 | team,
29 | );
30 | this.client.channels.cache.set(channel.id, channel);
31 | }
32 |
33 | const newMessage = new Message(
34 | this.client,
35 | { channelId: data.channelId, teamId: data.teamId, ...data.message },
36 | channel,
37 | )!;
38 | channel.messages!.cache.set(newMessage.id, newMessage);
39 | this.client.emit(events.MESSAGE_CREATE, newMessage);
40 | return [true];
41 | }
42 | return [false, 'passthrough'];
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/events/ChatMessageReactionAdded.ts:
--------------------------------------------------------------------------------
1 | import { WSChatMessageReactionAdded } from '@guildedjs/guilded-api-typings';
2 |
3 | import { MessageReaction } from '../../structures';
4 | import type { Client } from '../../structures/Client';
5 | import { events } from '../../typings';
6 | import Event from './Event';
7 |
8 | export default class ChatMessageReactionAddedEvent extends Event {
9 | public constructor(client: Client) {
10 | super(client);
11 | }
12 | public ingest(data: WSChatMessageReactionAdded): (boolean | (string | undefined))[] {
13 | if (data) {
14 | const reacter = this.client.users.cache.get(data.reaction.createdBy);
15 |
16 | let channel = this.client.channels.cache.get(data.channelId);
17 | if (!channel) {
18 | if (!this.client.options?.partials?.includes('CHANNEL')) return [false, 'Uncached channel'];
19 | channel = this.client.channels.add({
20 | contentType: data.contentType,
21 | id: data.channelId,
22 | teamId: data.teamId ?? undefined,
23 | type: data.channelType,
24 | })!;
25 | }
26 |
27 | const message = channel?.messages?.cache.get(data.message.id);
28 | if (!message && !this.client.options?.partials?.includes('MESSAGE')) return [false, 'Uncached message'];
29 |
30 | let messageReaction = message?.reactions.get(data.reaction.customReactionId.toString());
31 | if (!messageReaction) {
32 | const newMessageReaction = new MessageReaction(this.client, {
33 | ...data.reaction,
34 | createdAt: new Date().toISOString(),
35 | users: [{ botId: null, id: data.reaction.createdBy, webhookId: null }],
36 | });
37 | message?.reactions.set(newMessageReaction.id, newMessageReaction);
38 | messageReaction = newMessageReaction;
39 | }
40 | messageReaction.users.set(
41 | data.reaction.createdBy,
42 | this.client.users.cache.get(data.reaction.createdBy) ?? { id: data.reaction.createdBy },
43 | );
44 |
45 | this.client.emit(events.MESSAGE_REACTION_ADD, messageReaction, reacter ?? data.reaction.createdBy);
46 | return [true];
47 | }
48 |
49 | return [false, 'passthrough'];
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/events/ChatMessageReactionDeleted.ts:
--------------------------------------------------------------------------------
1 | import { WSChatMessageReactionDeleted } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../../structures/Client';
4 | import { events } from '../../typings';
5 | import Event from './Event';
6 |
7 | export default class ChatMessageReactionDeletedEvent extends Event {
8 | public constructor(client: Client) {
9 | super(client);
10 | }
11 | public ingest(data: WSChatMessageReactionDeleted): (boolean | (string | undefined))[] {
12 | if (data) {
13 | const reactionID = data.reaction.customReactionId.toString();
14 | const reacter = this.client.users.cache.get(data.reaction.createdBy);
15 |
16 | let channel = this.client.channels.cache.get(data.channelId);
17 | if (!channel) {
18 | if (!this.client.options?.partials?.includes('CHANNEL')) return [false, 'Uncached channel'];
19 | channel = this.client.channels.add({
20 | contentType: data.contentType,
21 | id: data.channelId,
22 | teamId: data.teamId ?? undefined,
23 | type: data.channelType,
24 | })!;
25 | }
26 |
27 | const message = channel?.messages?.cache.get(data.message.id);
28 | if (!message && !this.client.options?.partials?.includes('MESSAGE')) return [false, 'Uncached message'];
29 |
30 | const messageReaction = message?.reactions.get(reactionID);
31 | messageReaction?.users.delete(data.reaction.createdBy);
32 | if (!messageReaction?.users.size) message?.reactions.delete(reactionID);
33 |
34 | this.client.emit(
35 | events.MESSAGE_REACTION_DELETE,
36 | messageReaction ?? reactionID,
37 | reacter ?? data.reaction.createdBy,
38 | );
39 | return [true];
40 | }
41 |
42 | return [false, 'passthrough'];
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/events/ChatMessageUpdated.ts:
--------------------------------------------------------------------------------
1 | import { WSChatMessageUpdated } from '@guildedjs/guilded-api-typings';
2 |
3 | import type { Client } from '../../structures/Client';
4 | import { PartialMessage } from '../../structures/Message';
5 | import { events } from '../../typings';
6 | import Event from './Event';
7 |
8 | export default class ChatMessageUpdatedEvent extends Event {
9 | public constructor(client: Client) {
10 | super(client);
11 | }
12 | public ingest(data: WSChatMessageUpdated): (boolean | (string | undefined))[] {
13 | if (data) {
14 | const channel = this.client.channels.cache.get(data.channelId);
15 | const oldMessage = channel?.messages?.cache.get(data.message.id);
16 | if (!oldMessage && !this.client.options?.partials?.includes('MESSAGE')) {
17 | return [false, 'Old message not cached!'];
18 | }
19 | const newMessage =
20 | oldMessage?._clone().patch(data.message) ??
21 | new PartialMessage(this.client, { ...data.message, channelId: data.channelId });
22 | this.client.emit(events.MESSAGE_UPDATE, oldMessage, newMessage);
23 | }
24 |
25 | return [false, 'passthrough'];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/guilded.js/lib/ws/events/Event.ts:
--------------------------------------------------------------------------------
1 | import type { Client } from '../../structures/Client';
2 |
3 | export default abstract class Event {
4 | public constructor(public client: Client) {}
5 | public abstract ingest(data: unknown): (boolean | (string | undefined))[];
6 | public partialEnabled(): boolean {
7 | return !!this.client.options?.partials?.length;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/guilded.js/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/guilded.js",
3 | "version": "2.3.1-selfbot",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@guildedjs/guilded.js",
9 | "version": "2.2.1-selfbot",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@discordjs/collection": "^0.1.6",
13 | "ws": "^7.4.0"
14 | },
15 | "devDependencies": {
16 | "@types/node": "^14.14.9",
17 | "@types/ws": "^7.4.0",
18 | "typescript": "^4.4.2"
19 | }
20 | },
21 | "node_modules/@discordjs/collection": {
22 | "version": "0.1.6",
23 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
24 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ=="
25 | },
26 | "node_modules/@types/node": {
27 | "version": "14.14.16",
28 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz",
29 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==",
30 | "dev": true
31 | },
32 | "node_modules/@types/ws": {
33 | "version": "7.4.0",
34 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz",
35 | "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==",
36 | "dev": true,
37 | "dependencies": {
38 | "@types/node": "*"
39 | }
40 | },
41 | "node_modules/typescript": {
42 | "version": "4.4.2",
43 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
44 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
45 | "dev": true,
46 | "bin": {
47 | "tsc": "bin/tsc",
48 | "tsserver": "bin/tsserver"
49 | },
50 | "engines": {
51 | "node": ">=4.2.0"
52 | }
53 | },
54 | "node_modules/ws": {
55 | "version": "7.4.6",
56 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
57 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
58 | "engines": {
59 | "node": ">=8.3.0"
60 | },
61 | "peerDependencies": {
62 | "bufferutil": "^4.0.1",
63 | "utf-8-validate": "^5.0.2"
64 | },
65 | "peerDependenciesMeta": {
66 | "bufferutil": {
67 | "optional": true
68 | },
69 | "utf-8-validate": {
70 | "optional": true
71 | }
72 | }
73 | }
74 | },
75 | "dependencies": {
76 | "@discordjs/collection": {
77 | "version": "0.1.6",
78 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
79 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ=="
80 | },
81 | "@types/node": {
82 | "version": "14.14.16",
83 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz",
84 | "integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==",
85 | "dev": true
86 | },
87 | "@types/ws": {
88 | "version": "7.4.0",
89 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz",
90 | "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==",
91 | "dev": true,
92 | "requires": {
93 | "@types/node": "*"
94 | }
95 | },
96 | "typescript": {
97 | "version": "4.4.2",
98 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
99 | "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
100 | "dev": true
101 | },
102 | "ws": {
103 | "version": "7.4.6",
104 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
105 | "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
106 | "requires": {}
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/packages/guilded.js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/guilded.js",
3 | "version": "2.3.1-selfbot",
4 | "description": "A Node.js library for the Guilded.gg (https://www.guilded.gg/) API written in TypeScript, usable in either JavaScript or TypeScript projects.",
5 | "types": "types/index.d.ts",
6 | "main": "dist/index.js",
7 | "author": "zaid450 ",
8 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded.js#readme",
9 | "license": "MIT",
10 | "scripts": {
11 | "test": "cd ../../ && npm run build && cd packages/guilded.js && node ./__tests__/index.js",
12 | "test:local": "npm run build && cd __tests__ && node index.js",
13 | "build": "tsc",
14 | "prepublishOnly": "npx rimraf dist/ && npx rimraf types/ && npm run build"
15 | },
16 | "devDependencies": {
17 | "@guildedjs/guilded-api-typings": "^1.4.1-selfbot",
18 | "@types/node": "^14.14.9",
19 | "@types/ws": "^7.4.0",
20 | "typescript": "^4.4.2"
21 | },
22 | "dependencies": {
23 | "@discordjs/collection": "^0.1.6",
24 | "@guildedjs/common": "^1.0.5-selfbot",
25 | "@guildedjs/embeds": "^1.0.5-selfbot",
26 | "@guildedjs/rest": "^1.0.6-selfbot",
27 | "@guildedjs/webhook-client": "^1.0.6-selfbot",
28 | "ws": "^7.4.0"
29 | },
30 | "files": [
31 | "dist",
32 | "types"
33 | ],
34 | "keywords": [
35 | "guildedjs",
36 | "guilded.js",
37 | "guilded.gg",
38 | "guilded-api",
39 | "guilded"
40 | ],
41 | "directories": {
42 | "lib": "lib",
43 | "test": "__tests__"
44 | },
45 | "repository": {
46 | "type": "git",
47 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
48 | },
49 | "bugs": {
50 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
51 | },
52 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
53 | }
54 |
--------------------------------------------------------------------------------
/packages/guilded.js/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declarationDir": "./types"
6 | },
7 | "include": [ "./lib/**/*.ts" ],
8 | "exclude": [ "*.test.ts"]
9 | }
--------------------------------------------------------------------------------
/packages/rest/README.md:
--------------------------------------------------------------------------------
1 | # `@guildedjs/rest`
2 |
3 | [](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
4 | [](https://www.npmjs.com/package/@guildedjs/rest)
5 | [](https://github.com/zaida04/guilded.js-selfbot/actions/workflows/ci.yml)
6 |
7 | Rest utility for [`@guildedjs/guilded.js`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/guilded.js) and [`@guildedjs/webhook-client`](https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/webhook-client).
8 |
9 | > ⚠️ If you intend to use `@guildedjs/guilded.js` you won't need to install this, as it's already a dependency of that package.
10 |
11 | ## Installation
12 |
13 | You can install this package from [NPM](https://www.npmjs.com/package/@guildedjs/rest)
14 |
15 | - `npm install @guildedjs/rest`
16 | - `yarn add @guildedjs/rest`
17 |
18 | ## Contributing
19 |
20 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
21 |
22 | ## LICENSE
23 |
24 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
25 |
--------------------------------------------------------------------------------
/packages/rest/lib/GuildedAPIError.ts:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 |
3 | export class GuildedAPIError extends Error {
4 | public constructor(msg: string, method: string, path: string, code: number | string) {
5 | super(`[GuildedAPIError:${code}:${method.toUpperCase()}] ${path} - ${msg}`);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/packages/rest/lib/RestManager.ts:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 |
3 | import fetch, { Response } from 'node-fetch';
4 |
5 | import { GuildedAPIError } from './GuildedAPIError';
6 |
7 | export class RestManager {
8 | public apiURL: string;
9 | public token?: string;
10 | public cookieJar?: string;
11 | public guildedMID?: string;
12 |
13 | public constructor(public config?: RestManagerOptions) {
14 | this.apiURL = `https://${config?.apiURL ?? 'www.guilded.gg/api'}`;
15 | }
16 |
17 | public async make(
18 | data: MakeOptions,
19 | authenticated = true,
20 | retryCount = 0,
21 | ): Promise<[Response, Promise]> {
22 | const headers: HeadersInit = {};
23 | if (authenticated) headers.cookie = `hmac_signed_session=${this.token};`;
24 | const requestOptions = {
25 | body: data.body ? JSON.stringify(data.body) : undefined,
26 | headers: {
27 | 'content-type': 'application/json',
28 | ...headers,
29 | },
30 | method: data.method,
31 | };
32 |
33 | let request;
34 | try {
35 | request = await fetch(this.apiURL + data.path, requestOptions);
36 | } catch (e: any) {
37 | throw new Error(`Error while making API call, ${e.message.toString()}`);
38 | }
39 |
40 | if (!request.ok) {
41 | if (request.status === 429) {
42 | if (retryCount >= (this.config?.maxRatelimitRetryLimit ?? 3)) {
43 | throw new Error('MAX REQUEST RATELIMIT RETRY LIMIT REACHED.');
44 | }
45 | await sleep(this.config?.restOffset ?? 3500);
46 | return this.make(data, authenticated, retryCount++);
47 | }
48 |
49 | const parsedRequest = await request.json().catch(() => ({ message: 'Cannot parse JSON Error Response.' }));
50 | throw new GuildedAPIError(parsedRequest.message, data.method, data.path, request.status);
51 | }
52 |
53 | return [request, request.json().catch(() => ({})) as Promise];
54 | }
55 |
56 | public get(path: string, authenticated = true): Promise {
57 | return this.make(
58 | {
59 | method: 'GET',
60 | path,
61 | },
62 | authenticated,
63 | ).then(x => x[1]);
64 | }
65 |
66 | public post(path: string, body?: B, authenticated = true): Promise {
67 | return this.make(
68 | {
69 | body,
70 | method: 'POST',
71 | path,
72 | },
73 | authenticated,
74 | ).then(x => x[1]);
75 | }
76 |
77 | public delete(path: string, body?: B, authenticated = true): Promise {
78 | return this.make(
79 | {
80 | body,
81 | method: 'DELETE',
82 | path,
83 | },
84 | authenticated,
85 | ).then(x => x[1]);
86 | }
87 |
88 | public patch(path: string, body: B, authenticated = true): Promise {
89 | return this.make(
90 | {
91 | body,
92 | method: 'PATCH',
93 | path,
94 | },
95 | authenticated,
96 | ).then(x => x[1]);
97 | }
98 |
99 | public put(path: string, body?: B, authenticated = true): Promise {
100 | return this.make(
101 | {
102 | body,
103 | method: 'PUT',
104 | path,
105 | },
106 | authenticated,
107 | ).then(x => x[1]);
108 | }
109 |
110 | public setAuth(cookieJar: string): void {
111 | this.cookieJar = cookieJar;
112 | const setCookies = cookieJar.split(' ');
113 | this.token = extractFromCookieJar(setCookies, 0);
114 | this.guildedMID = extractFromCookieJar(setCookies, 11);
115 | }
116 |
117 | public destroy(): void {
118 | this.cookieJar = undefined;
119 | this.token = undefined;
120 | }
121 | }
122 |
123 | export interface RestManagerOptions {
124 | apiURL?: string;
125 | restOffset?: number;
126 | maxRatelimitRetryLimit?: number;
127 | }
128 | export interface MakeOptions {
129 | method: string;
130 | path: string;
131 | body?: Record;
132 | }
133 | export type JSONB = Record;
134 | export type RequestBodyObject = JSONB | undefined;
135 | export interface LoginData {
136 | email: string;
137 | password: string;
138 | }
139 |
140 | const extractFromCookieJar = (decodedCookieJar: string[], i: number) => decodedCookieJar[i].split('=')[1].split(';')[0];
141 | const sleep = (ms: number): Promise => new Promise(r => setTimeout(r, ms));
142 |
--------------------------------------------------------------------------------
/packages/rest/lib/index.ts:
--------------------------------------------------------------------------------
1 | export * from './GuildedAPIError';
2 | export * from './RestManager';
3 |
--------------------------------------------------------------------------------
/packages/rest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/rest",
3 | "version": "1.0.6-selfbot",
4 | "description": "Rest structure for @guildedjs/guilded.js",
5 | "author": "Zaid \"Nico\" ",
6 | "license": "MIT",
7 | "main": "dist/index.js",
8 | "types": "types/index.d.ts",
9 | "scripts": {
10 | "test": "npm run build && node ./__tests__/index.js",
11 | "build": "tsc",
12 | "prepublishOnly": "npx rimraf dist/ && npx rimraf types/ && npm run build"
13 | },
14 | "devDependencies": {
15 | "@types/node": "^14.14.9",
16 | "@types/node-fetch": "^2.5.8",
17 | "typescript": "^4.4.2"
18 | },
19 | "dependencies": {
20 | "node-fetch": "^2.6.1"
21 | },
22 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/rest#readme",
23 | "files": [
24 | "dist",
25 | "types"
26 | ],
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/guildedjs/guilded.js.git"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/guildedjs/guilded.js/issues"
33 | },
34 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
35 | }
36 |
--------------------------------------------------------------------------------
/packages/rest/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declarationDir": "./types"
6 | },
7 | "include": [ "./lib/**/*.ts" ],
8 | "exclude": [ "*.test.ts"]
9 | }
--------------------------------------------------------------------------------
/packages/webhook-client/README.md:
--------------------------------------------------------------------------------
1 | # `@guildedjs/webhook-client`
2 |
3 | [](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
4 | [](https://www.npmjs.com/package/@guildedjs/webhook-client)
5 | [](https://github.com/zaida04/guilded.js-selfbot/actions/workflows/ci.yml)
6 |
7 | Library-agnostic webhook client and utility
8 |
9 | > ⚠️ If you intend to use `@guildedjs/guilded.js` you won't need to install this, as it's already a dependency of that package.
10 |
11 | ## Installation
12 |
13 | You can install this package from [NPM](https://www.npmjs.com/package/@guildedjs/webhook-client)
14 |
15 | - `npm install @guildedjs/webhook-client`
16 | - `yarn add @guildedjs/webhook-client`
17 |
18 | ## Contributing
19 |
20 | Please see the main [README.md](https://github.com/zaida04/guilded.js-selfbot) for info on how to contribute to this package or the other `@guildedjs` packages.
21 |
22 | ## LICENSE
23 |
24 | Licensed under the [MIT License](https://github.com/zaida04/guilded.js-selfbot/blob/main/LICENSE)
25 |
--------------------------------------------------------------------------------
/packages/webhook-client/__tests__/Webhook.test.ts:
--------------------------------------------------------------------------------
1 | import { WebhookClient } from '..';
2 | const id = 'THISISARANDOMID';
3 | const token = 'THISISARANDOMTOKEN';
4 | const url = `https://media.guilded.gg/webhooks/${id}/${token}`;
5 |
6 | test('Pass URL as connection string', () => {
7 | const webhook = new WebhookClient(url);
8 | expect(webhook.id).toStrictEqual(id);
9 | expect(webhook.token).toStrictEqual(token);
10 | expect(webhook.URL).toStrictEqual(url);
11 | });
12 |
13 | test('Pass id and token as connection string', () => {
14 | const webhook = new WebhookClient({ id, token });
15 | expect(webhook.id).toStrictEqual(id);
16 | expect(webhook.token).toStrictEqual(token);
17 | expect(webhook.URL).toStrictEqual(url);
18 | });
19 |
20 | test('Get error when passing bad url', () => {
21 | expect(() => new WebhookClient('thisisnotagoodurl')).toThrow(
22 | new Error('Not a proper guilded webhook URL! Alternatively, you can provide an ID/token'),
23 | );
24 | });
25 |
26 | test('Get error when not passing anything in constructor', () => {
27 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
28 | // @ts-expect-error
29 | expect(() => new WebhookClient()).toThrow(
30 | new Error('Must provide Webhook connection info in either string or object. Received undefined.'),
31 | );
32 | });
33 |
34 | test('Pass only partial constructable info', () => {
35 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
36 | // @ts-expect-error
37 | expect(() => new WebhookClient({ id: 'aiuhdfius' })).toThrow(
38 | new Error(
39 | 'You must provide either a webhook URL or a webhook ID & token in an object when constructing the Webhook Client',
40 | ),
41 | );
42 | });
43 |
--------------------------------------------------------------------------------
/packages/webhook-client/lib/Webhook.ts:
--------------------------------------------------------------------------------
1 | import { parsedMessage, parseMessage, ROUTES } from '@guildedjs/common';
2 | import Embed from '@guildedjs/embeds';
3 | import { APIContent, APIPostWebhookResult } from '@guildedjs/guilded-api-typings';
4 | import { RestManager } from '@guildedjs/rest';
5 |
6 | export class WebhookClient {
7 | private api = new RestManager({ apiURL: ROUTES.MEDIA_DOMAIN });
8 | public URL: string;
9 | public id: string;
10 | public token: string;
11 |
12 | public constructor(webhookConnection: string | { id: string; token: string }) {
13 | if (!webhookConnection) {
14 | throw new TypeError(
15 | `Must provide Webhook connection info in either string or object. Received ${webhookConnection}.`,
16 | );
17 | }
18 | if (typeof webhookConnection === 'string') {
19 | const destructuredWebhookURL = webhookConnection.match(/guilded.gg\/webhooks\/([^/]+)\/([^/]+)/);
20 | if (!destructuredWebhookURL?.length) {
21 | throw new Error('Not a proper guilded webhook URL! Alternatively, you can provide an ID/token');
22 | }
23 | this.id = destructuredWebhookURL[1];
24 | this.token = destructuredWebhookURL[2];
25 | } else if (webhookConnection.id && webhookConnection.token) {
26 | this.id = webhookConnection.id;
27 | this.token = webhookConnection.token;
28 | } else {
29 | throw new TypeError(
30 | 'You must provide either a webhook URL or a webhook ID & token in an object when constructing the Webhook Client',
31 | );
32 | }
33 | this.URL = `https://${ROUTES.MEDIA_DOMAIN}/webhooks/${this.id}/${this.token}`;
34 | }
35 |
36 | /* istanbul ignore next */
37 | public send(content: string, embeds?: Embed[]): Promise {
38 | return this.api
39 | .post(`/webhooks/${this.id}/${this.token}`, {
40 | content,
41 | embeds,
42 | })
43 | .then(data => {
44 | const parsedContent = parseMessage(data.content);
45 | return {
46 | ...data,
47 | content: parsedContent.parsedText,
48 | parsedContent,
49 | rawContent: data.content,
50 | } as WebhookExecuteResponse;
51 | });
52 | }
53 | }
54 |
55 | export interface WebhookExecuteResponse extends Omit {
56 | content: string;
57 | parsedContent: parsedMessage;
58 | rawContent: APIContent;
59 | }
60 |
61 | export default WebhookClient;
62 |
--------------------------------------------------------------------------------
/packages/webhook-client/lib/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Webhook';
2 | export * from '@guildedjs/common';
3 |
--------------------------------------------------------------------------------
/packages/webhook-client/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/webhook-client",
3 | "version": "1.0.6-selfbot",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@guildedjs/webhook-client",
9 | "version": "1.0.4-selfbot",
10 | "license": "MIT",
11 | "dependencies": {
12 | "node-fetch": "^2.6.1"
13 | },
14 | "devDependencies": {
15 | "@types/node-fetch": "^2.5.10"
16 | }
17 | },
18 | "node_modules/@types/node": {
19 | "version": "15.12.2",
20 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
21 | "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==",
22 | "dev": true
23 | },
24 | "node_modules/@types/node-fetch": {
25 | "version": "2.5.10",
26 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz",
27 | "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==",
28 | "dev": true,
29 | "dependencies": {
30 | "@types/node": "*",
31 | "form-data": "^3.0.0"
32 | }
33 | },
34 | "node_modules/asynckit": {
35 | "version": "0.4.0",
36 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
37 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
38 | "dev": true
39 | },
40 | "node_modules/combined-stream": {
41 | "version": "1.0.8",
42 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
43 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
44 | "dev": true,
45 | "dependencies": {
46 | "delayed-stream": "~1.0.0"
47 | },
48 | "engines": {
49 | "node": ">= 0.8"
50 | }
51 | },
52 | "node_modules/delayed-stream": {
53 | "version": "1.0.0",
54 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
55 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
56 | "dev": true,
57 | "engines": {
58 | "node": ">=0.4.0"
59 | }
60 | },
61 | "node_modules/form-data": {
62 | "version": "3.0.1",
63 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
64 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
65 | "dev": true,
66 | "dependencies": {
67 | "asynckit": "^0.4.0",
68 | "combined-stream": "^1.0.8",
69 | "mime-types": "^2.1.12"
70 | },
71 | "engines": {
72 | "node": ">= 6"
73 | }
74 | },
75 | "node_modules/mime-db": {
76 | "version": "1.48.0",
77 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
78 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
79 | "dev": true,
80 | "engines": {
81 | "node": ">= 0.6"
82 | }
83 | },
84 | "node_modules/mime-types": {
85 | "version": "2.1.31",
86 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
87 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
88 | "dev": true,
89 | "dependencies": {
90 | "mime-db": "1.48.0"
91 | },
92 | "engines": {
93 | "node": ">= 0.6"
94 | }
95 | },
96 | "node_modules/node-fetch": {
97 | "version": "2.6.1",
98 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
99 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
100 | "engines": {
101 | "node": "4.x || >=6.0.0"
102 | }
103 | }
104 | },
105 | "dependencies": {
106 | "@types/node": {
107 | "version": "15.12.2",
108 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
109 | "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==",
110 | "dev": true
111 | },
112 | "@types/node-fetch": {
113 | "version": "2.5.10",
114 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz",
115 | "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==",
116 | "dev": true,
117 | "requires": {
118 | "@types/node": "*",
119 | "form-data": "^3.0.0"
120 | }
121 | },
122 | "asynckit": {
123 | "version": "0.4.0",
124 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
125 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
126 | "dev": true
127 | },
128 | "combined-stream": {
129 | "version": "1.0.8",
130 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
131 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
132 | "dev": true,
133 | "requires": {
134 | "delayed-stream": "~1.0.0"
135 | }
136 | },
137 | "delayed-stream": {
138 | "version": "1.0.0",
139 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
140 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
141 | "dev": true
142 | },
143 | "form-data": {
144 | "version": "3.0.1",
145 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
146 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
147 | "dev": true,
148 | "requires": {
149 | "asynckit": "^0.4.0",
150 | "combined-stream": "^1.0.8",
151 | "mime-types": "^2.1.12"
152 | }
153 | },
154 | "mime-db": {
155 | "version": "1.48.0",
156 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
157 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
158 | "dev": true
159 | },
160 | "mime-types": {
161 | "version": "2.1.31",
162 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
163 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
164 | "dev": true,
165 | "requires": {
166 | "mime-db": "1.48.0"
167 | }
168 | },
169 | "node-fetch": {
170 | "version": "2.6.1",
171 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
172 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/packages/webhook-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guildedjs/webhook-client",
3 | "version": "1.0.6-selfbot",
4 | "description": "Library-agnostic webhook client for the guilded.gg API",
5 | "author": "Zaid \"Nico\" ",
6 | "homepage": "https://github.com/zaida04/guilded.js-selfbot/tree/main/packages/webhook-client#readme",
7 | "license": "MIT",
8 | "types": "types/index.d.ts",
9 | "main": "dist/index.js",
10 | "scripts": {
11 | "build": "tsc",
12 | "test": "npm run build && npx jest",
13 | "prepublishOnly": "npx rimraf dist/ && npx rimraf types/ && npm run build"
14 | },
15 | "devDependencies": {
16 | "@guildedjs/guilded-api-typings": "^1.4.1-selfbot",
17 | "@types/node-fetch": "^2.5.10"
18 | },
19 | "dependencies": {
20 | "@guildedjs/common": "^1.0.5-selfbot",
21 | "@guildedjs/embeds": "^1.0.5-selfbot",
22 | "@guildedjs/rest": "^1.0.6-selfbot",
23 | "node-fetch": "^2.6.1"
24 | },
25 | "keywords": [
26 | "guilded-gg",
27 | "guilded-api",
28 | "guilded-webhook"
29 | ],
30 | "directories": {
31 | "lib": "lib",
32 | "test": "__tests__"
33 | },
34 | "files": [
35 | "dist",
36 | "types"
37 | ],
38 | "publishConfig": {
39 | "access": "public"
40 | },
41 | "repository": {
42 | "type": "git",
43 | "url": "git+https://github.com/zaida04/guilded.js-selfbot.git"
44 | },
45 | "bugs": {
46 | "url": "https://github.com/zaida04/guilded.js-selfbot/issues"
47 | },
48 | "gitHead": "0719b880becce0aa4bccaf5eb5b210ecb08b0547"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/webhook-client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declarationDir": "./types"
6 | },
7 | "include": [ "./lib/**/*.ts" ],
8 | "exclude": [ "*.test.ts"]
9 | }
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | endOfLine: 'auto',
3 | printWidth: 150,
4 | semi: true,
5 | tabWidth: 4,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/scripts/jest.js:
--------------------------------------------------------------------------------
1 | const { access } = require('fs/promises');
2 | const { join } = require('path');
3 | const ENV_PATH = join(__dirname, '..', '.env');
4 |
5 | (async () => {
6 | if (process.env.CI) return;
7 | try {
8 | await access(ENV_PATH);
9 | } catch (e) {
10 | throw new Error(
11 | 'An .env file is required at the root of this project to run tests. Please make sure it exists and is readable.',
12 | );
13 | }
14 | })();
15 |
--------------------------------------------------------------------------------
/scripts/post-docs.js:
--------------------------------------------------------------------------------
1 | const { writeFile } = require('fs/promises');
2 | const { join } = require('path');
3 |
4 | (async () => {
5 | await writeFile(join(__dirname, '..', 'docs', 'CNAME'), 'zaida04.github.io/guildedjs-selfbot-docs');
6 | console.log('CREATED CNAME');
7 | })();
8 |
--------------------------------------------------------------------------------
/scripts/refresh.js:
--------------------------------------------------------------------------------
1 | require('./reset');
2 | require('./setup');
3 |
--------------------------------------------------------------------------------
/scripts/reset.js:
--------------------------------------------------------------------------------
1 | const rimraf = require('rimraf');
2 | const { join } = require('path');
3 | const BASE_DIR = join(__dirname, '..');
4 | const packages = ['common', 'embeds', 'guilded-api-typings', 'guilded.js', 'webhook-client', 'rest'];
5 | const subDirs = ['node_modules', 'dist', 'types'];
6 |
7 | rimraf.sync(join(BASE_DIR, 'node_modules'));
8 | console.log('Deleting root node_modules');
9 | packages.forEach(package => {
10 | subDirs.forEach(dir => {
11 | rimraf.sync(join(BASE_DIR, 'packages', package, dir));
12 | console.log(`Deleting package ${package} ${dir}`);
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/scripts/setup.js:
--------------------------------------------------------------------------------
1 | const { execSync } = require('child_process');
2 | const { join } = require('path');
3 |
4 | const commands = ['npm i', 'npm run bootstrap', 'npm run build'];
5 | commands.forEach(command => execSync(command, { cwd: join(__dirname, '..') }));
6 |
--------------------------------------------------------------------------------
/static/guilded-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaida04/g.js-self/98d0b3736a11f6b7c543d0f363f7c68afe1846ca/static/guilded-icon.png
--------------------------------------------------------------------------------
/static/itami-transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaida04/g.js-self/98d0b3736a11f6b7c543d0f363f7c68afe1846ca/static/itami-transparent.png
--------------------------------------------------------------------------------
/static/readme-header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zaida04/g.js-self/98d0b3736a11f6b7c543d0f363f7c68afe1846ca/static/readme-header.png
--------------------------------------------------------------------------------
/testing.env.example:
--------------------------------------------------------------------------------
1 | EMAIL=
2 | PASSWORD=
3 | ROLE_ID=
4 | TEAM_ID=
5 | GUINEAPIG_ID=
6 | CHANNEL_ID=
7 | GROUP_ID=
8 | WEBHOOK_URL=
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "alwaysStrict": true,
5 | "moduleResolution": "node",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "pretty": true,
9 | "module": "CommonJS",
10 | "target": "ES6",
11 | "lib": [
12 | "ESNext",
13 | "DOM"
14 | ],
15 | "typeRoots": [
16 | "node_modules/@types"
17 | ],
18 | "types": [
19 | "node",
20 | "jest"
21 | ],
22 | "sourceMap": true,
23 | "incremental": true,
24 | "esModuleInterop": true,
25 | "skipLibCheck": true,
26 | "allowSyntheticDefaultImports": true,
27 | "resolveJsonModule": true
28 | },
29 | "exclude": [
30 | "dist/**"
31 | ]
32 | }
--------------------------------------------------------------------------------
/typedoc.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | exclude: ['**/node_modules/**', '**/dist/**', '**/types/**', '**/@types/**'],
3 | excludeExternals: true,
4 | excludeNotExported: true,
5 | 'external-modulemap': '.*packages/([^/]+)/.*',
6 | ignoreCompilerErrors: true,
7 | media: 'media',
8 | mode: 'modules',
9 | name: 'Guilded.JS',
10 | out: 'docs',
11 | preserveConstEnums: true,
12 | readme: 'README.md',
13 | stripInternal: true,
14 | theme: 'minimal',
15 | tsconfig: 'tsconfig.base.json',
16 | };
17 |
--------------------------------------------------------------------------------