Python how to forward messages from server - python-3.x

Hello i have a old discord server which we don't using now. and we created a new server and moved all members there but still some members r there in old server. So is there a option to forward all messages from server A to server B to specific channel.
Update:
I mean like when ever server A gets a message it should be sended to server B to a specific channel. bot is in both server so with that i can forward all incoming message exactly.
Bot Code
token = "xxxxxxxxxxxxx"
prefix = "!"
import discord
from discord.ext import commands
from discord.ext.commands import Bot
bot = commands.Bot(command_prefix=prefix)
bot.remove_command("help")
#bot.event
async def on_ready():
print('\nLogged in as')
print("Bot Name: " + bot.user.name)
print("Bot User ID: " + bot.user.id)
old_server = bot.get_server('xxxxxxxxxxxxx')
new_channel = bot.get_channel('xxxxxxxxxxxxx')
#bot.event
async def on_message(message):
message.content = message.content.lower()
if message.server == old_server:
await bot.send_message(new_channel, message.content)
await bot.process_commands(message)
bot.run(token)

You can use the on_message event to check when messages are sent to the old server and have the bot post the message to the new server.
Below is example code where the bot will check when the old server gets a message, then posts the same message to a specified channel on the new server.
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_message(message):
old_server = client.get_server('old_server_id')
new_channel = client.get_channel('new_channel_id')
if message.server == old_server:
await client.send_message(new_channel, message.content + ' - ' + message.author.nick)
client.run('token')

Related

Discord bot stickers

Is there a way that I can get my discord bot to send stickers after somebody says a certain thing, I got normal messages and emojis to work while it replies but there is not much learning material to find out how to get stickers to work with discord.py.
This is my code :
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='.nerd ', description = 'nerd eyes')
#bot.event
async def on_ready():
guild_count = 0
for guild in bot.guilds:
print(f"- {guild.id} (name: {guild.name})")
guild_count = guild_count + 1
print('Nerdeyes has awoken in ' + str(guild_count) + " servers")
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content.startswith('nerd'):
msg = 'eyes'
await message.channel.send(msg)
if message.content.startswith('guy'):
msg = '<:guysusthink:873066296558882847>'
await message.channel.send(msg)
bot.run("TOKEN")
Stickers are a new Discord feature and haven't been added yet in Discord.py. You're gonna have to wait a bit until they release the new version.

Discord.py grabbing twitch URL without an API

I have a discord bot.
What I want it to do is when the bot detects a user is streaming, print the URL of their stream into chat.
I'm having a problem trying to find out how to get the user's twitch channel url...
this is what I have
#client.event
async def on_member_update(before, after):
aname = after.display_name
aactivity = after.activity.type
mactivity = str(after.activities)
role = after.guild.get_role(736271867836498031)
channel = client.get_channel(736269005651836985)
memberinfo = after.activities.streaming.url
print(memberinfo)
if "Streaming name" in mactivity:
await after.add_roles(role)
await channel.send('{} has started streaming!'.format(after.display_name))
print(aname + " is streaming!")
else:
await after.remove_roles(role)
streamchannel = discord.Profile
await channel.send('{} is not streaming!'.format(after.display_name))
print(aname + " is not streaming.")
print('member updated status')
Is there something I'm missing? I don't know how at all to either find the URL of the streamer, or get it from their connect accounts.
Member objects have a Activity attribute. You can check if before.activity or after.activity is an instance of the Streaming class.
If so, the user either stopped or started streaming and we can send a message in channel:
from discord import Streaming
from discord.utils import get
#client.event
async def on_member_update(before, after):
if not before.activity.type == after.activity.type:
return
role = get(after.guild.roles, id=736271867836498031)
channel = get(after.guild.channels, id=736269005651836985)
if isinstance(after.activity, Streaming):
await after.add_roles(role)
await channel.send(f"{before.mention} is streaming on {activity.platform}: {activity.name}.\nJoin here: {activity.url}")
elif isinstance(before.activity, Streaming):
await after.remove_roles(role)
await channel.send(f'{after.mention} is no longer streaming!')
else:
return
Reference: discord.py documentation

How to call async code from sync code in another thread?

I'm making a Discord bot which send PM when it receive a Github hook.
It use Discord.py and BottlePy, the last one run in a dedicated thread.
Because both frameworks have a blocking main loop.
In BottlePy callback, I call some Discord.py async code.
I wasn't knowing what is Python async, this appear to be complicated when mixed with synchronous code...
Here's the full source code :
import discord
import bottle
import threading
import asyncio
client = discord.Client()
server = bottle.Bottle()
async def dm_on_github_async(userid,request):
print("Fire Discord dm to "+str(userid))
global client
user = client.get_user(userid)
if (user==None):
abort(500, "User lookup failed");
dm_channel = user.dm_channel
if (dm_channel==None):
dm_channel = await user.create_dm()
if (dm_channel==None):
abort(500, "Fail to create DM channel");
print("DM channel is "+str(asyncio.wait(dm_channel.id)))
await dm_channel.send("There's a Github shot !")
await dm_channel.send(str(request.body))
return
#server.post("/dm_on_github/<userid:int>")
def dm_on_github(userid):
return asyncio.run(dm_on_github_async(userid,bottle.request))
#client.event
async def on_ready():
print('We have logged in as {0.user} '.format(client))
##client.event
#async def on_message(message):
# if message.author == client.user:
# return
#
# if message.content.startswith('$hello'):
# await message.channel.send('Hello!')
# # This sample was working very well
class HTTPThread(threading.Thread):
def run(self):
global server
server.run(port=8080)
server_thread = HTTPThread()
print("Starting HTTP server")
server_thread.start()
print("Starting Discord client")
client.run('super secret key')
print("Client terminated")
server.close()
print("Asked server to terminate")
server_thread.join()
print("Server thread successful join")
I want that my Python bot send the body of the HTTP request as PM.
I get a RuntimeError: Timeout context manager should be used inside a task at return asyncio.run(dm_on_github_async(userid,bottle.request)).
I think I'm not doing this mix in the right way...
After a night, I found the way.
To call async code from sync code in another thread, we ask the loop (here this one from Discord.py) to run the callback with asyncio.run_coroutine_threadsafe(), this return a Task() and we wait for his result with result().
The callback will be run in the loop thread, in my case I need to copy() the Bottle request.
Here's a working program (as long you don't mind to stop it...) :
import discord
import bottle
import threading
import asyncio
client = discord.Client()
server = bottle.Bottle()
class HTTPThread(threading.Thread):
def run(self):
global server
server.run(port=8080)
async def dm_on_github_async(userid,request):
user = client.get_user(userid)
if (user==None):
abort(500, "User lookup failed");
dm_channel = user.dm_channel
if (dm_channel==None):
dm_channel = await user.create_dm()
if (dm_channel==None):
abort(500, "Fail to create DM channel");
# Handle the request
event = request.get_header("X-GitHub-Event")
await dm_channel.send("Got event "+str(event))
#await dm_channel.send(str(request.body)) # Doesn't work well...
return
#server.post("/dm_on_github/<userid:int>")
def dm_on_github(userid):
request = bottle.request
asyncio.run_coroutine_threadsafe(dm_on_github_async(userid,request.copy()),client.loop).result()
#client.event
async def on_ready():
print('We have logged in as {0.user} '.format(client))
# Wait for the old HTTP server
if hasattr(client,"server_thread"):
server.close()
client.server_thread.join()
client.server_thread = HTTPThread()
client.server_thread.start()
##client.event
#async def on_message(message):
# if message.author == client.user:
# return
#
# if message.content.startswith('$hello'):
# await message.channel.send('Hello!')
print("Starting Discord client")
client.run('super secret key')
print("Client terminated")
server.close()
print("Asked server to terminate")
server_thread.join()
print("Server thread successful join")

How to make my bot leave others server

I tried below code but it leaves any random 2 server if i run my bot. So if i re-run it quits 2 more random server it keeps quitting 2 server randomly if i try to re-run.
i want to make it quit only selected server so i changed ('server id') to ('451765543236566556') but still it quits 2 random server.
import discord
client = discord.Client()
my_server = client.get_server('server id')
#client.event
async def on_ready():
for server in client.servers:
if server != my_server:
await client.leave_server(server)
#client.event
async def on_server_join(server):
if server != my_server:
await client.leave_server(server)
This bot leaves every server except for one. Just leave the server you don't want the bot to be on.
import discord
client = discord.Client()
#client.event
async def on_ready():
my_server = client.get_server('server id')
await client.leave_server(my_server)

in discord.py how do i make it so the bot only works in one server

in discord.py, how do I make it so the bot only works on one? so is there a way do this
x = (channel id.)
if x == (12454431344645423) #this is the channel id
print ('hi')
The easiest way is to just not add it to any other servers. You can also just leave all the servers but one in your on_ready event, and then leave other servers as you join them.
import discord
client = discord.Client()
my_server = client.get_server('server id')
#client.event
async def on_ready():
for server in client.servers:
if server != my_server:
await client.leave_server(server)
#client.event
async def on_server_join(server):
if server != my_server:
await client.leave_server(server)

Resources