Added Intents.None, partial support for selfbot, required changes
This commit is contained in:
		
							parent
							
								
									4228cd8f52
								
							
						
					
					
						commit
						3a3af635c6
					
				
					 8 changed files with 137 additions and 33 deletions
				
			
		|  | @ -1,5 +1,7 @@ | ||||||
| # discord-deno | # discord-deno | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
| [](https://github.com/RichardLitt/standard-readme) | [](https://github.com/RichardLitt/standard-readme) | ||||||
| 
 | 
 | ||||||
| **An easy to use Discord API Library for Deno.** | **An easy to use Discord API Library for Deno.** | ||||||
|  | @ -36,16 +38,19 @@ import { Client, Message, Intents } from 'https://raw.githubusercontent.com/disc | ||||||
| 
 | 
 | ||||||
| const client = new Client() | const client = new Client() | ||||||
| 
 | 
 | ||||||
|  | // Listen for event when client is ready (Identified through gateway / Resumed) | ||||||
| client.on('ready', () => { | client.on('ready', () => { | ||||||
|   console.log(`Ready! User: ${client.user?.tag}`) |   console.log(`Ready! User: ${client.user?.tag}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | // Listen for event whenever a Message is sent | ||||||
| client.on('messageCreate', (msg: Message): void => { | client.on('messageCreate', (msg: Message): void => { | ||||||
|   if (msg.content === '!ping') { |   if (msg.content === '!ping') { | ||||||
|     msg.channel.send(`Pong! WS Ping: ${client.ping}`) |     msg.channel.send(`Pong! WS Ping: ${client.ping}`) | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | // Connect to gateway | ||||||
| // Replace with your bot's token and intents (Intents.All, Intents.Presence, Intents.GuildMembers) | // Replace with your bot's token and intents (Intents.All, Intents.Presence, Intents.GuildMembers) | ||||||
| client.connect('super secret token comes here', Intents.All) | client.connect('super secret token comes here', Intents.All) | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | @ -21,8 +21,8 @@ if(!token) { | ||||||
|     Deno.exit(); |     Deno.exit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const intents = prompt("Input Intents (0 = All, 1 = Presence, 2 = Server Members):"); | const intents = prompt("Input Intents (0 = All, 1 = Presence, 2 = Server Members, 3 = None):"); | ||||||
| if(!intents || !["0", "1", "2"].includes(intents)) { | if(!intents || !["0", "1", "2", "3"].includes(intents)) { | ||||||
|     console.log("No intents provided"); |     console.log("No intents provided"); | ||||||
|     Deno.exit(); |     Deno.exit(); | ||||||
| } | } | ||||||
|  | @ -32,8 +32,10 @@ if(intents == "0") { | ||||||
|     ints = Intents.All; |     ints = Intents.All; | ||||||
| } else if(intents == "1") { | } else if(intents == "1") { | ||||||
|     ints = Intents.Presence; |     ints = Intents.Presence; | ||||||
| } else { | } else if(intents == "2") { | ||||||
|     ints = Intents.GuildMembers; |     ints = Intents.GuildMembers; | ||||||
|  | } else { | ||||||
|  |     ints = Intents.None; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| client.connect(token, ints); | client.connect(token, ints); | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { unzlib } from 'https://deno.land/x/denoflate/mod.ts' | import { unzlib } from 'https://deno.land/x/denoflate@1.1/mod.ts' | ||||||
| import { Client } from '../models/client.ts' | import { Client } from '../models/client.ts' | ||||||
| import { | import { | ||||||
|   DISCORD_GATEWAY_URL, |   DISCORD_GATEWAY_URL, | ||||||
|  | @ -190,6 +190,7 @@ class Gateway { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private async sendIdentify(forceNewSession?: boolean): Promise<void> { |   private async sendIdentify(forceNewSession?: boolean): Promise<void> { | ||||||
|  |     if (this.client.bot === true) { | ||||||
|       this.debug('Fetching /gateway/bot...') |       this.debug('Fetching /gateway/bot...') | ||||||
|       const info = await this.client.rest.get(GATEWAY_BOT()) |       const info = await this.client.rest.get(GATEWAY_BOT()) | ||||||
|       if (info.session_start_limit.remaining === 0) |       if (info.session_start_limit.remaining === 0) | ||||||
|  | @ -210,7 +211,9 @@ class Gateway { | ||||||
|           return await this.sendResume() |           return await this.sendResume() | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     this.send({ |     } | ||||||
|  | 
 | ||||||
|  |     let payload: any = { | ||||||
|       op: GatewayOpcodes.IDENTIFY, |       op: GatewayOpcodes.IDENTIFY, | ||||||
|       d: { |       d: { | ||||||
|         token: this.token, |         token: this.token, | ||||||
|  | @ -227,7 +230,24 @@ class Gateway { | ||||||
|         ), |         ), | ||||||
|         presence: this.client.presence.create() |         presence: this.client.presence.create() | ||||||
|       } |       } | ||||||
|     }) |     } | ||||||
|  | 
 | ||||||
|  |     if(this.client.bot === false) { | ||||||
|  |       // TODO: Complete Selfbot support
 | ||||||
|  |       this.debug("Modify Identify Payload for Self-bot..") | ||||||
|  |       // delete payload.d['intents']
 | ||||||
|  |       // payload.d.intents = Intents.None
 | ||||||
|  |       payload.d.presence = null | ||||||
|  |       payload.d.properties = { | ||||||
|  |         $os: "Windows", | ||||||
|  |         $browser: "Firefox", | ||||||
|  |         $device: "" | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       this.debug("Warn: Support for selfbots is incomplete") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.send(payload) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private async sendResume(): Promise<void> { |   private async sendResume(): Promise<void> { | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ export interface ClientOptions { | ||||||
|   cache?: ICacheAdapter, |   cache?: ICacheAdapter, | ||||||
|   forceNewSession?: boolean, |   forceNewSession?: boolean, | ||||||
|   presence?: ClientPresence | ClientActivity | ActivityGame |   presence?: ClientPresence | ClientActivity | ActivityGame | ||||||
|  |   bot?: boolean | ||||||
|  |   canary?: boolean | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  | @ -37,6 +39,8 @@ export class Client extends EventEmitter { | ||||||
|   channels: ChannelsManager = new ChannelsManager(this) |   channels: ChannelsManager = new ChannelsManager(this) | ||||||
|   messages: MessagesManager = new MessagesManager(this) |   messages: MessagesManager = new MessagesManager(this) | ||||||
|   emojis: EmojisManager = new EmojisManager(this) |   emojis: EmojisManager = new EmojisManager(this) | ||||||
|  |   bot: boolean = true | ||||||
|  |   canary: boolean = false | ||||||
| 
 | 
 | ||||||
|   presence: ClientPresence = new ClientPresence() |   presence: ClientPresence = new ClientPresence() | ||||||
| 
 | 
 | ||||||
|  | @ -47,6 +51,8 @@ export class Client extends EventEmitter { | ||||||
|     this.forceNewSession = options.forceNewSession |     this.forceNewSession = options.forceNewSession | ||||||
|     if (options.cache !== undefined) this.cache = options.cache |     if (options.cache !== undefined) this.cache = options.cache | ||||||
|     if (options.presence !== undefined) this.presence = options.presence instanceof ClientPresence ? options.presence : new ClientPresence(options.presence) |     if (options.presence !== undefined) this.presence = options.presence instanceof ClientPresence ? options.presence : new ClientPresence(options.presence) | ||||||
|  |     if (options.bot === false) this.bot = false | ||||||
|  |     if (options.canary === true) this.canary = true | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   setAdapter (adapter: ICacheAdapter): Client { |   setAdapter (adapter: ICacheAdapter): Client { | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import { delay } from '../utils/index.ts' | import { delay } from '../utils/index.ts' | ||||||
| import * as baseEndpoints from '../consts/urlsAndVersions.ts' | import * as baseEndpoints from '../consts/urlsAndVersions.ts' | ||||||
| import { Client } from './client.ts' | import { Client } from './client.ts' | ||||||
|  | import { getBuildInfo } from "../utils/buildInfo.ts" | ||||||
| 
 | 
 | ||||||
| export enum HttpResponseCode { | export enum HttpResponseCode { | ||||||
|   Ok = 200, |   Ok = 200, | ||||||
|  | @ -175,11 +176,29 @@ export class RESTManager { | ||||||
|       headers['Content-Type'] = 'application/json' |       headers['Content-Type'] = 'application/json' | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return { |     let data: { [name: string]: any } = { | ||||||
|       headers, |       headers, | ||||||
|       body: body?.file ?? JSON.stringify(body), |       body: body?.file ?? JSON.stringify(body), | ||||||
|       method: method.toUpperCase() |       method: method.toUpperCase() | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if(this.client.bot === false) { | ||||||
|  |       // This is a selfbot. Use requests similar to Discord Client
 | ||||||
|  |       data.headers['authorization'] = this.client.token as string | ||||||
|  |       data.headers['accept-language'] = 'en-US' | ||||||
|  |       data.headers['accept'] = '*/*' | ||||||
|  |       data.headers['sec-fetch-dest'] = 'empty' | ||||||
|  |       data.headers['sec-fetch-mode'] = 'cors' | ||||||
|  |       data.headers['sec-fetch-site'] = 'same-origin' | ||||||
|  |       data.headers['x-super-properties'] = btoa(JSON.stringify(getBuildInfo(this.client))) | ||||||
|  |       delete data.headers['User-Agent'] | ||||||
|  |       delete data.headers['Authorization'] | ||||||
|  |       headers['credentials'] = 'include' | ||||||
|  |       headers['mode'] = 'cors' | ||||||
|  |       headers['referrerPolicy'] = 'no-referrer-when-downgrade' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return data | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async checkRatelimits (url: string): Promise<number | false> { |   async checkRatelimits (url: string): Promise<number | false> { | ||||||
|  | @ -230,9 +249,14 @@ export class RESTManager { | ||||||
|                   ) |                   ) | ||||||
|                   .join('&') |                   .join('&') | ||||||
|               : '' |               : '' | ||||||
|           const urlToUse = |           let urlToUse = | ||||||
|             method === 'get' && query !== '' ? `${url}?${query}` : url |             method === 'get' && query !== '' ? `${url}?${query}` : url | ||||||
| 
 | 
 | ||||||
|  |           if(this.client.canary) { | ||||||
|  |             let split = urlToUse.split('//') | ||||||
|  |             urlToUse = split[0] + '//canary.' + split[1] | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|           const requestData = this.createRequestBody(body, method) |           const requestData = this.createRequestBody(body, method) | ||||||
| 
 | 
 | ||||||
|           const response = await fetch( |           const response = await fetch( | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| import { Client, GuildTextChannel, Message, RedisCacheAdapter, ClientPresence, Member, Role, GuildChannel, TextChannel, Embed, Guild } from '../../mod.ts'; | import { Client, Intents, GuildTextChannel, Message, ClientPresence, Member, Role, GuildChannel, Embed, Guild } from '../../mod.ts'; | ||||||
| import { Intents } from "../utils/intents.ts"; |  | ||||||
| import { TOKEN } from './config.ts' | import { TOKEN } from './config.ts' | ||||||
| 
 | 
 | ||||||
| const client = new Client({ | const client = new Client({ | ||||||
|  | @ -7,6 +6,7 @@ const client = new Client({ | ||||||
|       name: 'Pokémon Sword', |       name: 'Pokémon Sword', | ||||||
|       type: 'COMPETING' |       type: 'COMPETING' | ||||||
|   }), |   }), | ||||||
|  |   // bot: false,
 | ||||||
|   // cache: new RedisCacheAdapter({
 |   // cache: new RedisCacheAdapter({
 | ||||||
|   //   hostname: '127.0.0.1',
 |   //   hostname: '127.0.0.1',
 | ||||||
|   //   port: 6379
 |   //   port: 6379
 | ||||||
|  | @ -30,6 +30,7 @@ client.on('channelUpdate', (before: GuildTextChannel, after: GuildTextChannel) = | ||||||
| 
 | 
 | ||||||
| client.on('messageCreate', async (msg: Message) => { | client.on('messageCreate', async (msg: Message) => { | ||||||
|   if (msg.author.bot === true) return |   if (msg.author.bot === true) return | ||||||
|  |   console.log(`${msg.author.tag}: ${msg.content}`) | ||||||
|   if (msg.content === '!ping') { |   if (msg.content === '!ping') { | ||||||
|     msg.reply(`Pong! Ping: ${client.ping}ms`) |     msg.reply(`Pong! Ping: ${client.ping}ms`) | ||||||
|   } else if (msg.content === '!members') { |   } else if (msg.content === '!members') { | ||||||
|  | @ -58,4 +59,4 @@ client.on('messageCreate', async (msg: Message) => { | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.connect(TOKEN, Intents.All) | client.connect(TOKEN, Intents.None) | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								src/utils/buildInfo.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/utils/buildInfo.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | import { Client } from "../models/client.ts"; | ||||||
|  | 
 | ||||||
|  | export const getBuildInfo = (client: Client) => { | ||||||
|  |     let os = 'Windows' | ||||||
|  |     let os_version = '10' | ||||||
|  |     let client_build_number = 71073 | ||||||
|  |     let client_event_source = null | ||||||
|  |     let release_channel = 'stable' | ||||||
|  |     if (client.canary) { | ||||||
|  |         release_channel = 'canary' | ||||||
|  |         client_build_number = 71076 | ||||||
|  |     } | ||||||
|  |     let browser = 'Firefox' | ||||||
|  |     let browser_version = '83.0' | ||||||
|  |     let browser_user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 ' + browser + '/' + browser_version | ||||||
|  |     // TODO: Use current OS properties, but also browser_user_agent accordingly
 | ||||||
|  |     // if(Deno.build.os === 'darwin') os = 'MacOS'
 | ||||||
|  |     // else if(Deno.build.os === 'linux') os = 'Ubuntu'
 | ||||||
|  | 
 | ||||||
|  |     return { | ||||||
|  |         os, | ||||||
|  |         os_version, | ||||||
|  |         browser, | ||||||
|  |         browser_version, | ||||||
|  |         browser_user_agent, | ||||||
|  |         client_build_number, | ||||||
|  |         client_event_source, | ||||||
|  |         release_channel, | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | @ -52,4 +52,20 @@ export class Intents { | ||||||
|     GatewayIntents.GUILD_VOICE_STATES, |     GatewayIntents.GUILD_VOICE_STATES, | ||||||
|     GatewayIntents.GUILD_WEBHOOKS |     GatewayIntents.GUILD_WEBHOOKS | ||||||
|   ]; |   ]; | ||||||
|  | 
 | ||||||
|  |   static None: number[] = [ | ||||||
|  |     GatewayIntents.GUILD_MESSAGES, | ||||||
|  |     GatewayIntents.DIRECT_MESSAGES, | ||||||
|  |     GatewayIntents.DIRECT_MESSAGE_REACTIONS, | ||||||
|  |     GatewayIntents.DIRECT_MESSAGE_TYPING, | ||||||
|  |     GatewayIntents.GUILDS, | ||||||
|  |     GatewayIntents.GUILD_BANS, | ||||||
|  |     GatewayIntents.GUILD_EMOJIS, | ||||||
|  |     GatewayIntents.GUILD_INTEGRATIONS, | ||||||
|  |     GatewayIntents.GUILD_INVITES, | ||||||
|  |     GatewayIntents.GUILD_MESSAGE_REACTIONS, | ||||||
|  |     GatewayIntents.GUILD_MESSAGE_TYPING, | ||||||
|  |     GatewayIntents.GUILD_VOICE_STATES, | ||||||
|  |     GatewayIntents.GUILD_WEBHOOKS | ||||||
|  |   ] | ||||||
| } | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue