Merge pull request #193 from TheDevYellowy/main
feat(Client) Fix & add auto nitro redeeming
This commit is contained in:
commit
0df013b2dc
@ -9,6 +9,7 @@ new Client({
|
|||||||
checkUpdate: true, // Check Package Update (Bot Ready) [Enable Default]
|
checkUpdate: true, // Check Package Update (Bot Ready) [Enable Default]
|
||||||
readyStatus: false, // Set Custom Status sync from Account (Bot Ready) [Disable Default]
|
readyStatus: false, // Set Custom Status sync from Account (Bot Ready) [Disable Default]
|
||||||
autoCookie: true, // Auto added Cookie and Fingerprint [Enable Default](https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/DOCUMENT.md#http-options)
|
autoCookie: true, // Auto added Cookie and Fingerprint [Enable Default](https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/DOCUMENT.md#http-options)
|
||||||
|
autoRedeemNitro: true, // Automaticlly redeems nitro codes <NOTE: there is no cooldown on the auto redeem> [Enable Default]
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
2
package-lock.json
generated
2
package-lock.json
generated
@ -6,7 +6,7 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "discord.js-selfbot-v13",
|
"name": "discord.js-selfbot-v13",
|
||||||
"version": "2.3.64",
|
"version": "2.3.66",
|
||||||
"license": "GNU General Public License v3.0",
|
"license": "GNU General Public License v3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aikochan2k6/qrcode-terminal": "^0.12.0",
|
"@aikochan2k6/qrcode-terminal": "^0.12.0",
|
||||||
|
@ -21,6 +21,7 @@ const ClientPresence = require('../structures/ClientPresence');
|
|||||||
const GuildPreview = require('../structures/GuildPreview');
|
const GuildPreview = require('../structures/GuildPreview');
|
||||||
const GuildTemplate = require('../structures/GuildTemplate');
|
const GuildTemplate = require('../structures/GuildTemplate');
|
||||||
const Invite = require('../structures/Invite');
|
const Invite = require('../structures/Invite');
|
||||||
|
const { Message } = require('../structures/Message');
|
||||||
const { CustomStatus } = require('../structures/RichPresence');
|
const { CustomStatus } = require('../structures/RichPresence');
|
||||||
const { Sticker } = require('../structures/Sticker');
|
const { Sticker } = require('../structures/Sticker');
|
||||||
const StickerPack = require('../structures/StickerPack');
|
const StickerPack = require('../structures/StickerPack');
|
||||||
@ -150,7 +151,7 @@ class Client extends BaseClient {
|
|||||||
this.guilds = new GuildManager(this);
|
this.guilds = new GuildManager(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All of the {@link Channel}s that the client is currently handling, mapped by their ids -
|
* All of the Channels that the client is currently handling, mapped by their ids -
|
||||||
* as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
|
* as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
|
||||||
* is a member of. Note that DM channels will not be initially cached, and thus not be present
|
* is a member of. Note that DM channels will not be initially cached, and thus not be present
|
||||||
* in the Manager without their explicit fetching or use.
|
* in the Manager without their explicit fetching or use.
|
||||||
@ -209,6 +210,12 @@ class Client extends BaseClient {
|
|||||||
*/
|
*/
|
||||||
this.password = null;
|
this.password = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nitro cache
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
this.usedCodes = [];
|
||||||
|
|
||||||
if (this.options.messageSweepInterval > 0) {
|
if (this.options.messageSweepInterval > 0) {
|
||||||
process.emitWarning(
|
process.emitWarning(
|
||||||
'The message sweeping client options are deprecated, use the global sweepers instead.',
|
'The message sweeping client options are deprecated, use the global sweepers instead.',
|
||||||
@ -426,19 +433,53 @@ class Client extends BaseClient {
|
|||||||
});
|
});
|
||||||
return new Invite(this, data);
|
return new Invite(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Nitro
|
* Automatically Redeem Nitro from raw message
|
||||||
* @param {string<NitroCode>} nitro Nitro Code
|
* @param {Message} message Discord Message
|
||||||
* discordapp.com/gifts/code | discord.gift/code
|
* @param {Channel} channel Message Channel
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
*/
|
||||||
async redeemNitro(nitro) {
|
async autoRedeemNitro(message, channel) {
|
||||||
|
if (typeof message !== Message) return;
|
||||||
|
await this.redeemNitro(message.content)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redeem nitro from code or url
|
||||||
|
* @param {string<NitroCode>} nitro Nitro url or code
|
||||||
|
* @param {Channel} channel Channel that the code was sent in
|
||||||
|
*/
|
||||||
|
async redeemNitro(nitro, channel) {
|
||||||
if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
|
if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
|
||||||
const regexNitro = /discord(?:(?:app)?\.com\/gifts|\.gift)\/([\w-]{2,255})/gi;
|
const regex = {
|
||||||
const code = DataResolver.resolveCode(nitro, regexNitro);
|
gift: /(discord.gift|discord.com|discordapp.com\/gifts)\/\w{16,25}/gim,
|
||||||
// https://discord.com/api/v9/entitlements/gift-codes/{code}/redeem
|
url: /(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)/gim,
|
||||||
const data = await this.api.entitlements['gift-codes'](code).redeem.post({ data: {} });
|
};
|
||||||
return data;
|
if (nitro.match(regex.gift) !== null) {
|
||||||
|
let codes = nitro.match(regex.gift);
|
||||||
|
for (let code of codes) {
|
||||||
|
code = code.replace(regex.url, '');
|
||||||
|
if (this.usedCodes.indexOf(code) > -1) return;
|
||||||
|
|
||||||
|
await this.api.entitlements['gift-codes'](code).redeem.post({
|
||||||
|
auth: true,
|
||||||
|
data: { channel_id: channel ? channel.id : null, payment_source_id: null },
|
||||||
|
});
|
||||||
|
|
||||||
|
this.usedCodes.push(code);
|
||||||
|
}
|
||||||
|
} else if ([16, 25].includes(nitro.length)) {
|
||||||
|
if (this.usedCodes.indexOf(nitro) > -1) return;
|
||||||
|
|
||||||
|
await this.api.entitlements['gift-codes'](nitro).redeem.post({
|
||||||
|
auth: true,
|
||||||
|
data: { channel_id: channel ? channel.id : null, payment_source_id: null },
|
||||||
|
});
|
||||||
|
|
||||||
|
this.usedCodes.push(nitro);
|
||||||
|
} else {
|
||||||
|
throw new Error('INVALID_NITRO');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,6 +18,10 @@ class MessageCreateAction extends Action {
|
|||||||
const message = channel.messages._add(data);
|
const message = channel.messages._add(data);
|
||||||
channel.lastMessageId = data.id;
|
channel.lastMessageId = data.id;
|
||||||
|
|
||||||
|
if (client.options.autoRedeemNitro) {
|
||||||
|
client.autoRedeemNitro(message, channel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever a message is created.
|
* Emitted whenever a message is created.
|
||||||
* @event Client#messageCreate
|
* @event Client#messageCreate
|
||||||
|
@ -346,7 +346,11 @@ class RequestHandler {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new HTTPError(err.message, err.constructor.name, err.status, request);
|
throw new HTTPError(err.message, err.constructor.name, err.status, request);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* If the response code is 10038 or UNKNOWN_GIFT_CODE then return the data object instead of throwing the error. *continues on next line*
|
||||||
|
* [].includes() adds better scaleability instead of stacking if statements (Yellowy)
|
||||||
|
*/
|
||||||
|
if ([10038].includes(data.code)) return data;
|
||||||
throw new DiscordAPIError(data, res.status, request);
|
throw new DiscordAPIError(data, res.status, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ class Options extends null {
|
|||||||
checkUpdate: true,
|
checkUpdate: true,
|
||||||
readyStatus: true,
|
readyStatus: true,
|
||||||
autoCookie: true,
|
autoCookie: true,
|
||||||
|
autoRedeemNitro: true,
|
||||||
patchVoice: true,
|
patchVoice: true,
|
||||||
waitGuildTimeout: 15_000,
|
waitGuildTimeout: 15_000,
|
||||||
shardCount: 1,
|
shardCount: 1,
|
||||||
|
9
typings/index.d.ts
vendored
9
typings/index.d.ts
vendored
@ -689,6 +689,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
|||||||
private presence: ClientPresence;
|
private presence: ClientPresence;
|
||||||
private _eval(script: string): unknown;
|
private _eval(script: string): unknown;
|
||||||
private _validateOptions(options: ClientOptions): void;
|
private _validateOptions(options: ClientOptions): void;
|
||||||
|
private autoRedeemNitro(message: Message, channel: Channel): object;
|
||||||
|
|
||||||
public application: If<Ready, ClientApplication>;
|
public application: If<Ready, ClientApplication>;
|
||||||
// Added
|
// Added
|
||||||
@ -721,7 +722,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
|||||||
public fetchPremiumStickerPacks(): Promise<Collection<Snowflake, StickerPack>>;
|
public fetchPremiumStickerPacks(): Promise<Collection<Snowflake, StickerPack>>;
|
||||||
public fetchWebhook(id: Snowflake, token?: string): Promise<Webhook>;
|
public fetchWebhook(id: Snowflake, token?: string): Promise<Webhook>;
|
||||||
public fetchGuildWidget(guild: GuildResolvable): Promise<Widget>;
|
public fetchGuildWidget(guild: GuildResolvable): Promise<Widget>;
|
||||||
public redeemNitro(code: string): Promise<void>;
|
public redeemNitro(code: string, channel?: Channel): object;
|
||||||
public generateInvite(options?: InviteGenerationOptions): string;
|
public generateInvite(options?: InviteGenerationOptions): string;
|
||||||
public login(token?: string): Promise<string>;
|
public login(token?: string): Promise<string>;
|
||||||
public QRLogin(debug?: boolean): DiscordAuthWebsocket;
|
public QRLogin(debug?: boolean): DiscordAuthWebsocket;
|
||||||
@ -3885,10 +3886,7 @@ export interface WebhookFields extends PartialWebhookFields {
|
|||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Typedefs
|
//#region Typedefs
|
||||||
export type PurchasedFlagsString =
|
export type PurchasedFlagsString = 'NITRO_CLASSIC' | 'NITRO' | 'GUILD_BOOST';
|
||||||
| 'NITRO_CLASSIC'
|
|
||||||
| 'NITRO'
|
|
||||||
| 'GUILD_BOOST';
|
|
||||||
|
|
||||||
export type ActivityFlagsString =
|
export type ActivityFlagsString =
|
||||||
| 'INSTANCE'
|
| 'INSTANCE'
|
||||||
@ -4389,6 +4387,7 @@ export interface ClientOptions {
|
|||||||
checkUpdate?: boolean;
|
checkUpdate?: boolean;
|
||||||
readyStatus?: boolean;
|
readyStatus?: boolean;
|
||||||
autoCookie?: boolean;
|
autoCookie?: boolean;
|
||||||
|
autoRedeemNitro?: boolean;
|
||||||
patchVoice?: boolean;
|
patchVoice?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user