Reputation: 51
I have a very basic discord.py bot hosted on heroku. Its only function is to send a message from a list of possible messages every 24 hours. It always sends the first message and then stops. I can't find any errors in the code, and when I lower the timings and test it both running on my computer and running in heroku, it works fine.
It's all on one python file, with a few required files for heroku and the two text documents for messages.
Here is the main script:
import discord
import time
import random as rng
clnt = discord.Client()
ch = 0 #channel id
cnt = 0 #amount of minutes on timer
lp = True #i think this is just a leftover variable from another version, i can't find anywhere i used it
@clnt.event
async def on_ready():
print('ready')
async def ph(): #function to send message
global ch
global lp
qts = open('quotes.txt') #get messages
qtz = qts.read().splitlines() #put messages in a list
qts.close() #close file
#if message file is empty, get the list from a backup file and put them into the first file, reseting the messages
if not qtz:
qts2 = open('quoteslog.txt')
qtz2 = qts2.read().splitlines()
qts2.close()
with open('quotes.txt', 'w') as f:
for i in qtz2:
f.write("%s\n" % i)
f.close()
qts = open('quotes.txt')
qtz = qts.read().splitlines()
qts.close()
#get random message from list
x = rng.randint(1, len(qtz))
x2 = x - 1
y = qtz[x2]
qtz.pop(x2)
open('quotes.txt', 'w').close() #clear the list
#rewrite the same file without the message sent
with open('quotes.txt', 'w') as f:
for i in qtz:
f.write("%s\n" % i)
f.close()
#used for messages with new lines
if y == 'ph1':
await ch.send("this is for one of the messages, it has new lines so it can't be re-inserted into a txt file")
await timer()
elif y == 'ph2':
await ch.send('same here')
await timer()
else:
#send message to channel and restart the timer
await ch.send(y)
await timer()
@clnt.event
async def on_message(m):
if m.author == clnt.user:
return
global ch
if m.content.startswith('send here'):
ch = clnt.get_channel(m.channel.id)
await m.channel.send('ok')
elif m.content.startswith('start'):
await timer()
async def timer(): #loops every 60 seconds, 1440 times, or 24hrs
global lp
while lp:
global cnt
time.sleep(60)
cnt += 1
if cnt == 1440:
cnt = 0 #reset timer and send message
await ph()
clnt.run('the discord bot id')
Yes, I know the code is probably garbage formatting-wise, but as far as I can tell it should be working and it isn't. I'm not even sure if it's a code error, could also be a heroku problem, but I have no idea.
If anyone has anything that could possibly help that would be greatly appreciated!
Upvotes: 0
Views: 580
Reputation: 661
I recommend you use the Bot
and Cog
classes, it will be much more efficient, they are provided in discord.py, and have decorators to define a looping function. They are in the discord.ext.commands
part of the module. You can do:
from discord.ext import commands, tasks
I just answered on another post with an example of a cog and a looping function, you'll find it here. Here is the same structure adapted to your case:
# LoopCog.py
from discord.ext import commands, tasks
import random
class LoopCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.test_loop.change_interval(minutes = self.bot.cnt)
@commands.Cog.listener("on_ready")
async def on_ready(self):
self.test_loop.start()
@tasks.loop(hours=24)
async def test_loop(self):
# insert your ph function contents here
# access the channel id via self.bot.ch
def setup(bot):
bot.add_cog(LoopCog(bot))
# main.py
from discord.ext import commands
bot = commands.Bot(command_prefix = "!")
bot.ch = 0
bot.cnt = 0
bot.load_extension("LoopCog")
@bot.event
async def on_ready():
print("ready")
bot.run(token, reconnect = True)
I suggest you go watch some tutorials. Using the Client
class for a Bot
is not the right way to go, you will have to program everything that is already in Bot
if you keep going with Client
.
You'll find the API documentation here for Bot, Cog, and tasks
Concerning heroku, it will unfortunately restart your bot every 24h, unless you go for a paying professional offer which includes 24/7 runtime. It will also put your program in sleep mode if it doesn't get any request within 30 min.
Upvotes: 3