mossonzdod
mossonzdod

Reputation: 5

Python Discord Bot - VPS Reboot Behaviors?

With a friend of mine we created a simple discord bot in python, first let me explain how it works :

We created 366 different usernames, one for each day of the year. Each day at 0:01AM the bot should automatically post a message with :

Here is the code we made :

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import discord
from discord.ext import commands
from dotenv import load_dotenv
from datetime import datetime
load_dotenv()

TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')

client = discord.Client()
channel = client.get_channel(CHANNELID)

bissextileSpec = datetime.today().strftime('%m-%d') # To handle bissextile years

nickFile = open("nicknames.txt", "r")
nickList = nickFile.readlines()
dayNumber = datetime.now().timetuple().tm_yday

# We also made special dates

if bissextileSpec == '06-01' :
    nickOfTheDay = 'SpecialNick1'
elif bissextileSpec == '07-14' :
    nickOfTheDay = 'SpecialNick2'
elif bissextileSpec == '30-12' :
    nickOfTheDay = 'SpecialNick3'
elif bissextileSpec == '17-06' :
    nickOfTheDay = 'SpecialNick4'
elif bissextileSpec == '05-04' :
    nickOfTheDay = 'SpecialNick5'
else :
    nickOfTheDay = nickList[dayNumber - 1]

await channel.send('MSG CONTENT', nickOfTheDay, 'MSG CONTENT')
await client.user.edit(username=nickOfTheDay)

We know our way a bit around python but we don't really know how discord bots works :

We are not quite sure how to instruct it to auto-post at midnight each day : We thought of a While loop with a sleep(50) on its end BUT : How is it going to handle the hazardous VPS reboots ? If the vps reboot mid sleep is it going to reset it and shift the next post time further than 0:00 ?

On the other end, if we don't use a While loop, but if we use the CRON system in Linux to check and start the script everyday at midnight, does it mean the bot will be shown offline 23h59/24 on Discord and stay online just to post the message ? => We want to add a few more features later so we need the bot to run 24/24

Aswell, do not hesitate to point it if we did something wrong in the code ( ͡° ͜ʖ ͡°)

Upvotes: 0

Views: 263

Answers (2)

Łukasz Kwieciński
Łukasz Kwieciński

Reputation: 15728

You can make a loop that iterates every 24h and change the nickname of the bot, you can get the seconds till midnight with some simple math and sleep for those seconds

import asyncio
from discord.ext import tasks
from datetime import datetime

@tasks.loop(hours=24)
async def change_nickname(guild):
    """Loops every 24 hours and changes the bots nick"""
    nick = "" # Get the nick of the corresponding day
    await guild.me.edit(nick=nick)


@change_nickname.before_loop
async def before_change_nickname(guild):
    """Delays the `change_nickname` loop to start at 00:00"""
    hour, minute = 0, 0
    
    now = datetime.now()
    future = datetime(now.year, now.month, now.day + 1, now.month, now.day, hour, minute)

    delta = (future - now).seconds
    await asyncio.sleep(delta)

To start it you need to pass a discord.Guild instance (the main guild where the nickname should be changed)

change_nickname.start(guild) # You can start it in the `on_ready` event or some command or in the global scope, don't forget to pass the guild instance

No matter what hour the bot started the loop will change the bots nick at 00:00 everyday

Reference:

Upvotes: 1

Mokhtar
Mokhtar

Reputation: 36

Łukasz's code has a tiny flaw, the future variable is wrongly initialized but everything else is working accordingly! This should do the trick:

import asyncio
from discord.ext import tasks
from datetime import datetime

@tasks.loop(hours=24)
async def change_nickname(guild):
    nick = ""
    await guild.me.edit(nick=nick)

@change_nickname.before_loop
async def before_change_nickname():
    hour, minute = 0, 0
    now = datetime.now()
    future = datetime(now.year, now.month, now.day + 1, hour, minute)
    delta = (future - now).seconds
    await asyncio.sleep(delta)

Upvotes: 0

Related Questions