[PYTHON] Just migrate the Discord.py 0.X echobot to 1.X

Background

The program I made to make Voiceroid read Discord messages using Python 3.6 was not usable after Python 3.7. (From a year ago) Also, the version of Discord.py was so old that I wanted to update it. (It was discovered that it did not work after updating)

I wanted to use Python for the first time in a long time, so let's fix it!

environment

The environment assumed this time is as follows. -Python 3.7.4 ・ Discord.py 1.2.4 ・ Windows 10

Please refer to other pages for Python environment settings. Please use your favorite editor etc.

Echobot refurbishment

I would like to make a simple echo bot. I made it the last time Discord.py 0.x, so I couldn't use it now.

EchoBot.py


# Discord.py 0.x
import discord
client = discord.Client()

@client.event
async def on_ready():
    print("-"*35)
    print("user name:", client.user.name)
    print("user id:", client.user.id)
    print("-"*35)

@client.event
async def on_message(message):
        #Don't react to your own message
    if client.user != message.author:
        #Write a message
        m= message.author.name +"The message sent by"+message.content+"is"
        #Send a message to the channel to which the message was sent
        await client.send_message(message.channel, m)


client.run("BOT token")

It's as simple as sending back a message from someone other than a bot. We will modify this to match 1.X. This time, it is in ʻon_message` that needs to be modified.

EchoBot_after.py


@client.event
async def on_message(message):
    if message.author.bot:  #Ignore if the message sender is a bot
        return
    #Send to the posted channel
    await message.channel.send(f"{message.author.name}Message from{message.content}is")

Since it is an echo bot, this kind of modification is enough, but it seems to be difficult for a multifunctional application.

Repair while fixing

Here is a lot of rewrites

EchoBot.py


import discord
import re
client = discord.Client()
CHANNEL_ID = "ID of the main channel"


@client.event
async def on_ready():  #Show ID and name on console at startup
    print("-"*50)
    print(client.user.name)  # User Name
    print(str(client.user.id))  # User ID
    print(""*50)
    print("Bot invitation URL")
    strURL = "https://discordapp.com/oauth2/authorize?&client_id="
    strURL += str(client.user.id) + "&scope=bot&permissions=0"
    print(strURL)
    print("-"*50)
    print(f"client : {client}")
    print(f"client.user : {client.user}")
    print("-"*50)
    channel = client.get_channel(CHANNEL_ID)
    await channel.send("It has started.")  #Notify when started


@client.event
async def on_message(message):  #Processing that operates when receiving a message
    if message.author.bot:  #Ignore if the message sender is a bot
        return

    if client.user in message.mentions:  #I will reply when a reply comes
        await message.channel.send( f"{message.author.mention}called?")  #Send a reply message
        return

    Msg = message.content
    if re.search(r"http(.*)", Msg):
        Msg = re.sub(r"http(.*)", ", URL below", Msg)  #URL omitted
    await message.channel.send(f"{message.author.name}Message from{Msg}is")


client.run("BOT token")

This completes the echo bot. You can get the person's guild nickname by replacing the message.author.name part with message.author.nick.

bonus

This is an assortment of client functions (functions that I think I will use personally) that I made to check various things while updating.

DiscordTest.py


import discord
import re
import datetime
import sys
from inspect import currentframe

client = discord.Client()
CHANNEL_ID = "Channel ID"


@client.event
async def on_ready():  #Show ID and name on console at startup
    now = datetime.datetime.now()
    print(now.strftime('%Y/%m/%d %H:%M:%S'))
    print("-"*50)
    print(client.user.name)  # User Name
    print(str(client.user.id))  # User ID
    print(""*50)
    print("Bot invitation URL")
    strURL = "https://discordapp.com/oauth2/authorize?&client_id="
    strURL += str(client.user.id) + "&scope=bot&permissions=0"
    print(strURL)
    print("-"*50)
    print(f"client : {client}")
    print(f"client.user : {client.user}")
    print("-"*50)
    channel = client.get_channel(CHANNEL_ID)
    await channel.send("It has started.")  #Notify when started


@client.event
async def on_typing(channel, user, when):  #Someone is trying to write a message
    printDate(sys._getframe().f_code.co_name, channel, user, when)


@client.event
async def on_message(message):  #Processing that operates when receiving a message
    printDate(sys._getframe().f_code.co_name, message)
    if message.author.bot:  #Ignore if the message sender is a bot
        return
    if client.user in message.mentions:  #I will reply when a reply comes
        reply = f"{message.author.mention}called?"  #Reply content
        await message.channel.send(reply)  #Send a reply message
        return

    if re.search(r"Cutting board", message.content):  #Determine if the command is included
        e = discord.Embed(title='KOROSUZO☆')
        await message.channel.send('Did you say anything', embed=e)  #
        return
    Msg = message.content
    if re.search(r"http(.*)", Msg):
        Msg = re.sub(r"http(.*)", ", URL below", Msg)  #URL omitted
    await message.channel.send(f"{message.author.nick}Message from{Msg}is")


@client.event
async def on_guild_role_create(role):  #What happens when a guild rule is created
    printDate(sys._getframe().f_code.co_name, role)
    channel = client.get_channel(CHANNEL_ID)
    await channel.send(f"{role}Was created")


@client.event
async def on_user_update(before, after):
    printDate(sys._getframe().f_code.co_name, before, after)


@client.event
async def on_member_update(before, after):  #Processing to be executed when member information changes
    printDate(sys._getframe().f_code.co_name, before, after)


@client.event
async def on_guild_role_delete(role):
    printDate(sys._getframe().f_code.co_name, role)
    channel = client.get_channel(CHANNEL_ID)
    await channel.send(f"{role}Has been deleted")


@client.event
async def on_voice_state_update(member, before, after):
    channel = client.get_channel(CHANNEL_ID)
    printDate(sys._getframe().f_code.co_name, member, before, after)
    #Leave the voice channel
    if after.channel is None:
        await channel.send(f"{member}But{before.channel.name}I left the room from")
        return
    #Join the voice channel
    if before.channel is None and after.channel is not None:
        await channel.send(f"{member}But{after.channel.name}I participated in")
        return
    #Move voice channel
    if before.channel != after.channel:
        await channel.send(f"{member}But{after.channel.name}Moved to")
        return


@client.event
async def on_guild_update(before, after):  #What to do when a guild is updated
    channel = client.get_channel(CHANNEL_ID)
    printDate(sys._getframe().f_code.co_name, before, after)
    await channel.send(f" {before}But{after}Changed to")


@client.event
async def on_guild_channel_delete(channel):  #When a channel is deleted
    printDate(sys._getframe().f_code.co_name, channel)


@client.event
async def on_guild_channel_create(channel):  #The channel was created
    printDate(sys._getframe().f_code.co_name, channel)


@client.event
async def on_guild_channel_pins_update(channel, lastPin):  #When a message is pinned or unpinned
    print(sys._getframe().f_code.co_name)
    chkprint(channel, lastPin)
    if lastPin is not None:
        print(f"lastPin +9h : {lastPin + datetime.timedelta(hours=9)}")  #Corrected to Japan time
    print("-"*50)


def printDate(name, *args):
    print(name)
    now = datetime.datetime.now()
    print(now.strftime('%Y/%m/%d %H:%M:%S'))
    chkprint(*args)
    print("-"*50)


def chkprint(*args):
    names = {id(v): k for k, v in currentframe().f_back.f_locals.items()}
    print(', '.join(names.get(id(arg), '???') + ' = ' + repr(arg) for arg in args))


client.run('BOT token')

There was a function to change its own status, change the name and rules of the guild, and react in various ways, but I collected the parts that I could use.

Reference site

** How to get the name of a function from within a [Python] function ** https://qiita.com/abeken0713/items/77420c8c05e53628199a

** Ideal for print debugging! Implemented a function to convert variable names to strings in python and print at the same time as the values inside ** https://qiita.com/AnchorBlues/items/f7725ba87ce349cb0382

Discord.py https://discordpy.readthedocs.io/ja/latest/migrating.html#

Recommended Posts

Just migrate the Discord.py 0.X echobot to 1.X
Terms closely related to the X Window System
Just add the python array to the json data
Excel X Python The fastest way to work
[Algorithm x Python] How to use the list
Introduction to discord.py (2)
How to Learn Kaldi with the JUST Corpus
Introduction to discord.py
Just add the driver to the shape key with blender
The road to Pythonista
The road to Djangoist