I've got a problem with sending a message to multiple channels. When I do the command, it sends just to the channel I wrote from for 8 times. Here is my code:
import discord
import config
client = discord.Client()
#client.event
async def on_message(message):
id = client.get_guild(config.ID)
channels = [647074685535649802, 636901028478058497, 690272147050070158, 694196995887202375, 690276595578962177, 654662320735387648, 650381379892412426, 641704849196711976]
valid_users = ["Resadesker#1103"]
if str(message.author) in valid_users:
for channelo in channels:
if message.content.find("$spam") != -1:
print(channelo)
channel = client.get_channel(channelo)
print(channel)
await message.channel.send(message.content[message.content.find(' '):])
client.run(config.TOKEN)
It looks like you are sending your response to the channel from message, try this:
#client.event
async def on_message(message):
id = client.get_guild(config.ID)
channels = [
647074685535649802,
636901028478058497,
690272147050070158,
694196995887202375,
690276595578962177,
654662320735387648,
650381379892412426,
641704849196711976,
]
valid_users = ["Resadesker#1103"]
if str(message.author) in valid_users:
for channelo in channels:
if message.content.find("$spam") != -1:
print(channelo)
channel = client.get_channel(channelo)
print(channel)
await channel.send(message.content[message.content.find(' '):])
Related
I tried to write a Discord bot that forwards messages from one server to another. But I get a warning that disconnects my connection to the discord gateway. I read that it is possible because of tyme.slep(), but without it, the connection is always interrupted. As I understand it, DDOS protection is activated due to a large number of requests.
import asyncio
import websocket
import json
from threading import Thread
import discord
import requests
from io import BytesIO
import time
from discord.ext import tasks
# Bot
bot_token = "anything"
user_token = "anything"
client = discord.Client(intents=discord.Intents.default())
# Channels list
f = open('channels.txt', 'r')
channels_file = f.read()
channels_array = channels_file.strip().split('\n')
# Connect func
def send_json_request(ws, request):
ws.send(json.dumps(request))
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
#WebSoket
def on_closed(ws):
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
ws = websocket.WebSocket(on_close=on_closed)
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
def get_attachment_media(media):
media_array = []
for i in media:
response = requests.get(i['url'])
im = BytesIO(response.content)
print(im)
media_array.append(discord.File(im))
return media_array
def get_channel(id):
for i in channels_array:
if i == id:
return True
return False
#Heartbeat
def heartbeat(interval):
print("Heartbeat begin")
while True:
time.sleep(interval)
heartbeatJSON = {
"op": 1,
"d": "null"
}
send_json_request(ws, heartbeatJSON)
print("Heartbeat sent")
#tasks.loop(seconds=0.5)
async def main():
channel = client.get_channel(anything)
event = receive_json_response(ws)
try:
if event['d']['author']['id'] == 'anything':
return
id_channel = event['d']['channel_id']
id_guild = event['d']['guild_id']
if get_channel(id_channel):
content = event['d']['content']
attachment_media = get_attachment_media(event['d']['attachments'])
await channel.send(content, files=attachment_media)
op_code = event('op')
if op_code == 11:
print('Heartbeat recieved')
except:
pass
#client.event
async def on_ready():
event = receive_json_response(ws)
heartbeat_interval = event['d']['heartbeat_interval'] / 1000
send_json_request(ws, {
"op": 2,
"d": {
"token": user_token,
"properties": {
"$os": 'linux',
"$browser": 'chrome',
"$device": 'pc'
}
}
})
main.start()
asyncio.run(heartbeat(heartbeat_interval))
client.run(bot_token)
I recommend you to check this answer and adjust it to your code.
However, if you are just trying to make your bot copy the contenet of the messages sent in one server and sending to another one, you can do it in a easier way using the on_message() event. This is the entire code, which should also prevent any warning (unless the bot tries to send too many messages in a short period of time):
import discord
intents = discord.Intents.default()
intents.message_content = True # You are missing the message_content intent! (needed to read the content of the guild's messages)
client = discord.Client(intents=intents)
TOKEN = "Your Token"
guild_id = 123456789 # The guild you want your bot to send the messages to
channel_id = 987654321 # The channel of the guild you want your bot to send the messages to
guild = None
channel = None
#client.event
async def on_ready():
global guild, channel, guild_id, channel_id
await client.wait_until_ready()
guild = client.get_guild(guild_id)
channel = guild.get_channel(channel_id)
print("Logged")
#client.event
async def on_message(message : discord.Message):
if message.author == client.user: # You don't want to send the own bot messages
return
if message.guild.id == guild_id: # You don't want to send the messages from the own guild your bot is sending the messages to
return
await channel.send(f"{message.author}: {message.content}") # Add attachments if you want
client.run(TOKEN)
I created a channel with "guild.create_text_channel" but I couldn't find how to send a message to the channel I created. I'm using discord.py
async def on_raw_reaction_add(payload):
messageID = <myMessageID>
channell = bot.get_channel(payload.channel_id)
message = await channell.fetch_message(payload.message_id)
if messageID == payload.message_id:
member = payload.member
guild = member.guild
emoji = payload.emoji.name
overwrites = {
guild.default_role: discord.PermissionOverwrite(view_channel = False),
guild.me: discord.PermissionOverwrite(view_channel=True),
guild.get_role(<myRoleID>): discord.PermissionOverwrite(view_channel = True)
}
if emoji == '✅':
channel = guild.create_text_channel(str(member)+"-ticket", overwrites=overwrites,)
await channel
await message.remove_reaction('✅', member)
You can send a message in a channel using TextChannel.send.
PS. Guild.create_text_channel is a coroutine so you should await it.
I'm creating a discord bot and I need to get the guild categories list, so I can create a new channel under a specific category that already has the permissions I want.
This is my code:
import discord
client = discord.Client()
#client.event
async def on_ready():
group = await client.fetch_guild('Guild ID')
categories_list = group.categories
# print so I can see the categories_list
print(categories_list)
# more stuff...
This is the result:
[ ]
I am new to both Python and Stack Exchange. When using this code, I receive the error, "Using variable 'status' before assignment [30,96]." It says that the variable status is unassigned in the await command in the loop, even though I assigned it above. If anyone could solve this, I would appreciate it. If any other info is needed, just ask and I can reply with it. Thanks.
import requests
from discord.ext import commands
from discord.ext import tasks
from itertools import cycle
client = commands.Bot(command_prefix = '.')
status = cycle(['Starting.', 'Starting..'])
serverOnePlayerCount = 0
serverTwoPlayerCount = 0
serverOneOnline = 'Offline'
serverTwoOnline = 'Offline'
#client.event
async def on_ready():
change_status.start()
print('Bot is ready.')
#client.command()
async def ping(ctx):
await ctx.send(f'Pong! {round(client.latency * 1000)}ms')
#tasks.loop(seconds=5)
async def change_status():
await client.change_presence(status=discord.Status.online, activity=discord.Game(name=next(status), type=3))
r1 = requests.get('https://api.minehut.com/server/5f0de3303c826f0051e583b1/')
json_data_1 = r1.json()
serverOneOnline = str(json_data_1["server"]["online"])
serverOnePlayerCount = str(json_data_1["server"]["playerCount"])
serverOneStatusMessage = 'Minecraft ----- Server 1 is {} ({}/10 players)'.format(serverOneOnline, serverOnePlayerCount)
r2 = requests.get('https://api.minehut.com/server/5f8242b2d74dc1006100293b/')
json_data_2 = r2.json()
serverTwoOnline = str(json_data_2["server"]["online"])
serverTwoPlayerCount = str(json_data_2["server"]["playerCount"])
serverTwoStatusMessage = 'Minecraft ----- Server 2 is {} ({}/10 players)'.format(serverTwoOnline, serverTwoPlayerCount)
status = cycle([serverOneStatusMessage, serverTwoStatusMessage])
client.run('token')
I am making a discord.Client. I have a DM command that sends a DM to a specific user, but no message is sent to the user when the command is run, but a message is sent on the Context.channel.
Here is my code:
import discord, asyncio
app = discord.Client()
#app.event
async def on_message(message):
if message.content.startswith('!DM'):
usernotsending = []
content = message.content
msg = await message.channel.send('메시지를 보내고 있습니다!')
i = app.user
# 봇의 모든 유저를 for문으로 적용
for i in app.user:
try:
if i == app.user:
return
# 해당 유저의 DM을 염
await i.create_dm()
# 내용전송
await app.dmchannel.send(content)
# DiscordAPI 에서 오류가 발생했을경우
except discord.HTTPException:
# DM을 보내지 못한 유저 태그 list에 저장
usernotsending.append(f'{i.name}#{i.discriminator}')
messageing = """
아래 유저들에게 메시지를 전송하지 못했습니다!
직접 보내주시거나, 따로 전달을 해드려야됩니다!
"""
for msg in usernotsending:
# message 에 유저 태그 추가
messageing += msg
# 메시지 전송
await msg.edit(content=messageing)
Context is only part of a commands.Bot instance. Your code and your explanation don't seem to match. Assuming you want to DM the author:
import discord
app = discord.Client()
#app.event
async def on_message(message):
if message.content.startswith('!DM'):
try:
await message.author.send(...)
except discord.HTTPException:
...
If you want to DM everyone the bot can see:
import discord
app = discord.Client()
#app.event
async def on_message(message):
if message.content.startswith('!DM'):
for user in app.users:
try:
await user.send(...)
except discord.HTTPException:
...