Why are commands not working for my discord.py bot? - discord

`
import os
import discord
from dotenv import load_dotenv
from discord.ext import commands
from discord import FFmpegPCMAudio
load_dotenv(".env")
TOKEN = os.getenv("DISCORD_TOKEN")
client = commands.Bot(command_prefix='$')
#client.command()
async def unvc(ctx):
await ctx.guild.voice_client.disconnect()
#client.command()
async def vc(ctx):
if ctx.author.voice:
channel = ctx.author.voice.channel
await channel.connect()
source = FFmpegPCMAudio('music.mp3')
player = voice.play(source)
#client.event
async def on_ready():
print('{0.user} has connected toDiscord!'.format(client))
return await client.change_presence(
activity=discord.Activity(type=discord.ActivityType.playing, name="anime waifu simulator VR"))
client.run(TOKEN)
`
I am trying to use commands with my discord bot and it does nothing when I type them. It is still able to delete messages, so it isn't an issue with the connection to Discord.

Seems like you‘re using the olde 1.7.3 version of discord.py that is outdated at this time due to new required intents.
check your version with pip show discord.py and should upgrade to 2.x
then you also have to use the message intent if you‘re using the message command framework of discord.py
for that, go to the discord developer dashboard and activate the privileged intent „message“. after that, add the following to your code above your bot definition:
intents = discord.Intents()
intents.message_content = True
then pass the intents to the bot constructor with
intents=intents
(also, normally in discord.py programming, we do name Bot instances bot and only Client instances client)

You have to make the bot listen to both, commands and messages. If you send a message, it will be read as a message and not like a command. For fixing that add:
#client.event
async def on_message(ctx:Context):
await client.process_commands(ctx)
Add this:
intents = discord.Intents.all()
client = commands.Bot(command_prefix='$', intents=intents)
This will add the intents to the bot. I've tried it out. That should work for you. You also have to enable intents in the bot settings in your discord developer portal.

Related

Why won't my React app send HTTP-only cookies in WebSocket upgrade requests in production?

I'm currently building a full-stack TypeScript live chat app with React + Vite on the frontend and Node on the backend. I have two separate servers running: one is a REST API and OAuth2 auth server built with Express and Passport.js and the other one is a WebSockets server built with the ws package. They run independently (no interprocess communication whatsoever) and use stateless auth in the form of JWTs.
Here's how my current flow works: users first log in with either their Google or GitHub account, and once the first server has verified their identity, it sends an HTTP-only cookie down to the client. This cookie is send back to the server on all subsequent requests and I have some middleware that runs on the REST API to parse and verify the JWTs on protected routes. Once it has the cookie, the client then initiates a WS connection with the second server, which also checks for the JWT cookie in the incoming HTTP Upgrade request and verifies its signature before allowing the new client to continue exchanging messages:
import { WebSocket, WebSocketServer } from "ws";
import { baseDataSchema } from "./zod/schemas";
import prisma from "./prisma";
import { asyncJWTverify } from "./misc/jwt";
import { UserJwtReceived } from "../types/jwt";
import { handleJoinGroup } from "./websockets-handlers/join-group";
// Websockets server setup
const wss = new WebSocketServer({ port: Number(process.env.WS_PORT) });
const userSocketMap = new Map<string, WebSocket>();
wss.on("listening", () => {
console.log(`WebSockets server started on port ${process.env.WS_PORT}`);
});
wss.on("connection", async function connection(ws, req) {
// authenticate incoming websocket connection
const cookies = req.headers.cookie;
if (!cookies) return ws.close();
let currentUser: UserJwtReceived = { id: "", iat: 0 };
try {
// Decode auth JWT
const token = cookies.split("=")[1];
currentUser = (await asyncJWTverify(
token,
process.env.JWT_SECRET as string
)) as UserJwtReceived;
} catch (err) {
console.error(err);
return ws.close();
}
// check for JWT expiry
const expiryTime = Number(process.env.JWT_EXPIRY);
if (Math.round(Date.now() / 1000) - currentUser.iat > expiryTime) {
return ws.close();
}
// Bind user ID to WebSocket, add it to map
// TypeScript doesn't complain about this because I've extended ws's WebSocket interface
ws.userId = currentUser.id;
userSocketMap.set(currentUser.id, ws);
console.log(`User ID ${ws.userId} connected`);
ws.on("message", async function message(rawData) => {
// ... actual app logic goes here
})
ws.on("close", function () {
if (!ws.userId) return;
console.log(`User ID ${ws.userId} has disconnected`);
userSocketMap.delete(ws.userId);
});
})
Both servers and the React frontend app run on different URLs, both on local dev and prod, so all requests are cross-origin, but CORS is enabled on the REST API/auth server and as far as I know the WebSockets protocol doesn't implement any CORS policies...
The problem I'm currently facing is that in my local dev environment, the cookie that contains the JWT is sent along with Upgrade request no problem, but after deploying my app to AWS Lightsail (it's a VPS service similar to EC2) and setting up NGINX, my React frontend is no longer able to include the cookie with the upgrade request.
After spending literally the whole day debugging, I've been able to rule out a faulty NGINX config as the root of the problem, since I can use wscat to connect (and most importantly, successfully authenticate) to my production WS server by manually including the Cookie header.
I still have no idea why my React app won't properly send the HTTP-only auth cookie to my WS server. Does anyone have any clue as to why this is happening?
I expected the HTTP-only cookie containing the JWT to be sent along with the HTTP Upgrade request, just like I've been able to do in my local dev environment, but no luck.

ReactJS backend requests and proxy

I have a couple of questions regarding how ReactJS should work in development and production. My ReactJS application was built starting from creare-react-app boilerplate. I have a SpringBoot backend listening on port 8080. The first thing I noticed is that if I set a code like this to make requests the code hang:
async componentDidMount() {
...
const response = await fetch('http://localhost:8080/api/compliance');
I need to convert it into:
async componentDidMount() {
...
const response = await fetch('/api/compliance');
and then add the line:
"proxy": "http://localhost:8080",
and this works fine. The problem is that when I put this in a pre-production environment (or integration environment) where I have a URL like http://www.mywebsite.com I got:
Invalid Host Header
Looking on the web I noticed that probably this could be to:
1. proxy that checks. the HTTP Header host and verify it to avoid security attacks
2. webpack package
I would like to understand:
1. Is proxy really necessary to let ReactJS app talk with its backend?
2. If no, how I can solve the issue (currently solution on the web didn't solve my problem)?
Generally proxy is not meant for production. Your app should provide both app and api on same port, on one server. https://stackoverflow.com/a/46771744/8522881

Error pops up on startup: 'Incorrect login details were provided'

I'm following the guide. I've run node index.js into Windows PowerShell, but it's not giving intended output
It's copy and pasted from the discord.js guide. I've run it many times and every time it has the same exact error.
// require the discord.js module
const Discord = require('discord.js');
// create a new Discord client
const client = new Discord.Client();
// when the client is ready, run this code
// this event will only trigger one time after logging in
client.once('ready', () => {
console.log('Ready!');
});
// login to Discord with your app's token
client.login('your-token-goes-here');
expected: Ready!
actual:
(node:800) UnhandledPromiseRejectionWarning: Error: Incorrect login details were provided.
at WebSocketConnection.client.ws.connection.once.event (C:\Users\mort3\Desktop\Sakabato\node_modules\discord.js\src\client\ClientManager.js:48:41)
at Object.onceWrapper (events.js:276:13)
at WebSocketConnection.emit (events.js:188:13)
at WebSocketConnection.onClose (C:\Users\mort3\Desktop\Sakabato\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:390:10)
at WebSocket.onClose (C:\Users\mort3\Desktop\Sakabato\node_modules\ws\lib\event-target.js:124:16)
at WebSocket.emit (events.js:188:13)
at _receiver.cleanup (C:\Users\mort3\Desktop\Sakabato\node_modules\ws\lib\websocket.js:220:12)
at Receiver.cleanup (C:\Users\mort3\Desktop\Sakabato\node_modules\ws\lib\receiver.js:535:15)
at WebSocket.finalize (C:\Users\mort3\Desktop\Sakabato\node_modules\ws\lib\websocket.js:206:20)
at TLSSocket.emit (events.js:193:15)
(node:800) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:800) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Double check if you have copied the token from the Bot tab, not from General Information tab.
The discord API and discord.js (which is a wrapper for the discord api) require an authentication token. You supply this token on login:
client.login(<insert your token here>)
You are not replacing the filler text your-token-goes-here with your actual authentication token, one that you receive by making an application on discord (See https://discordjs.guide/#/preparations/setting-up-a-bot-application)
To see how I got here, look at the stack trace, the error message:
Error: Incorrect login details were provided.
It's pretty self-evident what the error is; in this case, you didn't supply any login details.
It says
Error: Incorrect login details were provided
You need to get a bot token via the Discord Developer Dashboard, create an application there, convert it to a Bot account and from there you can get the needed token to use in the client.loginmethod.
Make sure to never show anyone this token.
you need to create a token for the bot to connect with the Discord API

Voice channel userlimit discord js

I'm trying to create a voice channel with Discord Bot
. This is my code simply (I'm using discord.js)
message.channel.createChannel('General', "voice").then(chan => {
chan.userLimit("5");
})
But the console log is like that
(node:13080) UnhandledPromiseRejectionWarning: TypeError: message.channel.createChannel is not a function
How can I handle of this?
You can not use the .createChannel method on a channel, you need to use it on a guild.
This would be correct:
discord.js v11
message.guild.createChannel();
discord.js v12
message.guild.channels.create();

How do I use Google API to add custom domain mapping in App Engine?

I am trying to add a custom domain mapping to my App Engine app using the Google API (not through console). However, I keep getting 403 forbidden error when the http request is made with the Discovery API Client. I have obtained a credentials json file from App Engine with owner permissions and I point to that with the GOOGLE_APPLICATION_CREDENTIALS env variable. Since I have full permissions, I'm guessing the problem is I'm not using the API correctly but haven't been able to see what is missing.
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = os.path.dirname(__file__) + str('/json_cred_file')
apps_client = googleapiclient.discovery.build('appengine', 'v1beta')
response = apps_client.apps().domainMappings().create(
appsId='apps/myappname', body=json.loads(
'{"id": "newsubdomain.mydomain.com","sslSettings": '
'{"sslManagementType": "AUTOMATIC" }}')).execute()
Here is the error:
WARNING 2018-07-06 23:51:09,331 http.py:119] Encountered 403 Forbidden with reason "forbidden"
I contacted Google support and the issue is when using the domain mapping function, the service account needs to be added to the search console as an owner. This is the search console: https://www.google.com/webmasters/tools/home
They have a special page in their docs for using this library on app engine: https://developers.google.com/api-client-library/python/guide/google_app_engine
This is how I use the googleapiclient library. One difference I see is this line:
credentials = GoogleCredentials.get_application_default()
from oauth2client.client import GoogleCredentials
from lib.googleapiclient import discovery
class DataFlowJobsListHandler(AdminResourceHandler):
def get(self, resource_id=None):
"""
Wrapper to this:
https://cloud.google.com/dataflow/docs/reference/rest/v1b3/projects.jobs/list
"""
if resource_id:
self.abort(405)
else:
credentials = GoogleCredentials.get_application_default()
service = discovery.build('dataflow', 'v1b3', credentials=credentials)
project_id = app_identity.get_application_id()
_filter = self.request.GET.pop('filter', 'UNKNOWN').upper()
jobs_list_request = service.projects().jobs().list(
projectId=project_id,
filter=_filter) #'ACTIVE'
jobs_list = jobs_list_request.execute()
return {
'$cursor': None,
'results': jobs_list.get('jobs', []),
}

Resources