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 | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| [](https://github.com/RichardLitt/standard-readme) | ||||
| 
 | ||||
| **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() | ||||
| 
 | ||||
| // Listen for event when client is ready (Identified through gateway / Resumed) | ||||
| client.on('ready', () => { | ||||
|   console.log(`Ready! User: ${client.user?.tag}`) | ||||
| }) | ||||
| 
 | ||||
| // Listen for event whenever a Message is sent | ||||
| client.on('messageCreate', (msg: Message): void => { | ||||
|   if (msg.content === '!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) | ||||
| client.connect('super secret token comes here', Intents.All) | ||||
| ``` | ||||
|  |  | |||
|  | @ -21,8 +21,8 @@ if(!token) { | |||
|     Deno.exit(); | ||||
| } | ||||
| 
 | ||||
| const intents = prompt("Input Intents (0 = All, 1 = Presence, 2 = Server Members):"); | ||||
| if(!intents || !["0", "1", "2"].includes(intents)) { | ||||
| const intents = prompt("Input Intents (0 = All, 1 = Presence, 2 = Server Members, 3 = None):"); | ||||
| if(!intents || !["0", "1", "2", "3"].includes(intents)) { | ||||
|     console.log("No intents provided"); | ||||
|     Deno.exit(); | ||||
| } | ||||
|  | @ -32,8 +32,10 @@ if(intents == "0") { | |||
|     ints = Intents.All; | ||||
| } else if(intents == "1") { | ||||
|     ints = Intents.Presence; | ||||
| } else { | ||||
| } else if(intents == "2") { | ||||
|     ints = Intents.GuildMembers; | ||||
| } else { | ||||
|     ints = Intents.None; | ||||
| } | ||||
| 
 | ||||
| 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 { | ||||
|   DISCORD_GATEWAY_URL, | ||||
|  | @ -140,7 +140,7 @@ class Gateway { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   private onclose (event: CloseEvent): void { | ||||
|   private onclose(event: CloseEvent): void { | ||||
|     this.debug(`Connection Closed with code: ${event.code}`) | ||||
| 
 | ||||
|     if (event.code === GatewayCloseCodes.UNKNOWN_ERROR) { | ||||
|  | @ -189,7 +189,8 @@ class Gateway { | |||
|     console.log(eventError) | ||||
|   } | ||||
| 
 | ||||
|   private async sendIdentify (forceNewSession?: boolean): Promise<void> { | ||||
|   private async sendIdentify(forceNewSession?: boolean): Promise<void> { | ||||
|     if (this.client.bot === true) { | ||||
|       this.debug('Fetching /gateway/bot...') | ||||
|       const info = await this.client.rest.get(GATEWAY_BOT()) | ||||
|       if (info.session_start_limit.remaining === 0) | ||||
|  | @ -210,7 +211,9 @@ class Gateway { | |||
|           return await this.sendResume() | ||||
|         } | ||||
|       } | ||||
|     this.send({ | ||||
|     } | ||||
| 
 | ||||
|     let payload: any = { | ||||
|       op: GatewayOpcodes.IDENTIFY, | ||||
|       d: { | ||||
|         token: this.token, | ||||
|  | @ -227,7 +230,24 @@ class Gateway { | |||
|         ), | ||||
|         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> { | ||||
|  | @ -248,11 +268,11 @@ class Gateway { | |||
|     this.send(resumePayload) | ||||
|   } | ||||
| 
 | ||||
|   debug (msg: string): void { | ||||
|   debug(msg: string): void { | ||||
|     this.client.debug('Gateway', msg) | ||||
|   } | ||||
| 
 | ||||
|   async reconnect (forceNew?: boolean): Promise<void> { | ||||
|   async reconnect(forceNew?: boolean): Promise<void> { | ||||
|     clearInterval(this.heartbeatIntervalID) | ||||
|     if (forceNew === undefined || !forceNew) | ||||
|       await this.cache.delete('session_id') | ||||
|  |  | |||
|  | @ -18,6 +18,8 @@ export interface ClientOptions { | |||
|   cache?: ICacheAdapter, | ||||
|   forceNewSession?: boolean, | ||||
|   presence?: ClientPresence | ClientActivity | ActivityGame | ||||
|   bot?: boolean | ||||
|   canary?: boolean | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -37,6 +39,8 @@ export class Client extends EventEmitter { | |||
|   channels: ChannelsManager = new ChannelsManager(this) | ||||
|   messages: MessagesManager = new MessagesManager(this) | ||||
|   emojis: EmojisManager = new EmojisManager(this) | ||||
|   bot: boolean = true | ||||
|   canary: boolean = false | ||||
| 
 | ||||
|   presence: ClientPresence = new ClientPresence() | ||||
| 
 | ||||
|  | @ -47,6 +51,8 @@ export class Client extends EventEmitter { | |||
|     this.forceNewSession = options.forceNewSession | ||||
|     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.bot === false) this.bot = false | ||||
|     if (options.canary === true) this.canary = true | ||||
|   } | ||||
| 
 | ||||
|   setAdapter (adapter: ICacheAdapter): Client { | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import { delay } from '../utils/index.ts' | ||||
| import * as baseEndpoints from '../consts/urlsAndVersions.ts' | ||||
| import { Client } from './client.ts' | ||||
| import { getBuildInfo } from "../utils/buildInfo.ts" | ||||
| 
 | ||||
| export enum HttpResponseCode { | ||||
|   Ok = 200, | ||||
|  | @ -175,11 +176,29 @@ export class RESTManager { | |||
|       headers['Content-Type'] = 'application/json' | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|     let data: { [name: string]: any } = { | ||||
|       headers, | ||||
|       body: body?.file ?? JSON.stringify(body), | ||||
|       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> { | ||||
|  | @ -230,9 +249,14 @@ export class RESTManager { | |||
|                   ) | ||||
|                   .join('&') | ||||
|               : '' | ||||
|           const urlToUse = | ||||
|           let urlToUse = | ||||
|             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 response = await fetch( | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| import { Client, GuildTextChannel, Message, RedisCacheAdapter, ClientPresence, Member, Role, GuildChannel, TextChannel, Embed, Guild } from '../../mod.ts'; | ||||
| import { Intents } from "../utils/intents.ts"; | ||||
| import { Client, Intents, GuildTextChannel, Message, ClientPresence, Member, Role, GuildChannel, Embed, Guild } from '../../mod.ts'; | ||||
| import { TOKEN } from './config.ts' | ||||
| 
 | ||||
| const client = new Client({ | ||||
|  | @ -7,6 +6,7 @@ const client = new Client({ | |||
|       name: 'Pokémon Sword', | ||||
|       type: 'COMPETING' | ||||
|   }), | ||||
|   // bot: false,
 | ||||
|   // cache: new RedisCacheAdapter({
 | ||||
|   //   hostname: '127.0.0.1',
 | ||||
|   //   port: 6379
 | ||||
|  | @ -30,6 +30,7 @@ client.on('channelUpdate', (before: GuildTextChannel, after: GuildTextChannel) = | |||
| 
 | ||||
| client.on('messageCreate', async (msg: Message) => { | ||||
|   if (msg.author.bot === true) return | ||||
|   console.log(`${msg.author.tag}: ${msg.content}`) | ||||
|   if (msg.content === '!ping') { | ||||
|     msg.reply(`Pong! Ping: ${client.ping}ms`) | ||||
|   } 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_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