【问题标题】:My discord.py bot running on heroku keeps stopping我在 heroku 上运行的 discord.py 机器人不断停止
【发布时间】:2020-08-07 17:20:48
【问题描述】:

我在 heroku 上托管了一个非常基本的 discord.py 机器人。它的唯一功能是每 24 小时从可能的消息列表中发送一条消息。它总是发送第一条消息然后停止。我在代码中找不到任何错误,当我降低时间并测试它在我的计算机上运行和在 heroku 中运行时,它工作正常。

这一切都在一个 python 文件中,其中包含几个 Heroku 所需的文件和两个用于消息的文本文档。

这里是主要脚本:

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')

是的,我知道代码可能是垃圾格式,但据我所知,它应该可以正常工作,但事实并非如此。我什至不确定这是否是代码错误,也可能是 Heroku 问题,但我不知道。

如果有人有任何可能提供帮助的东西,将不胜感激!

【问题讨论】:

  • 你的 Heroku 日志是怎么说的?
  • 你也在定时器中循环。但随后计时器调用 ph。哪个呼叫计时器。因此,即使这段代码正常工作,它也会非常糟糕。
  • 早上会检查日志并更新。至于 ph() 调用 timer(),是的,我很愚蠢,哈哈。我确定我之前实际上并没有那个,然后由于某种原因看到我没有它并认为我需要它,可能忘记了计时器是一个循环什么的。

标签: python heroku discord.py


【解决方案1】:

我推荐你使用BotCog 类,效率会更高,它们在discord.py 中提供,并且有装饰器来定义循环函数。它们位于模块的 discord.ext.commands 部分。你可以这样做:

from discord.ext import commands, tasks

我刚刚在另一篇文章中回答了一个 cog 和循环函数的例子,你会发现它here。这是适用于您的情况的相同结构:

# 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)

我建议你去看一些教程。对Bot 使用Client 类不是正确的方法,如果您继续使用Client,您将不得不对Bot 中已有的所有内容进行编程。

您将找到用于BotCogtasks 的 API 文档 here

关于 heroku很遗憾,它会每 24 小时重新启动一次您的机器人,除非您选择包含 24/7 运行时间的付费专业服务。如果在 30 分钟内没有收到任何请求,它也会让您的程序进入睡眠模式。

【讨论】:

  • 是否会有一个每分钟左右运行一次的循环,阻止机器人进入睡眠状态?
  • @AryanGarg 因为如果机器人没有收到外部请求,它就会进入睡眠状态,内部循环不会改变任何事情。但是,您可能会创建另一个机器人,它会定期向您尝试保持清醒的机器人发送请求,但这需要一些测试才能找到这样做的好方法。
猜你喜欢
  • 1970-01-01
  • 2019-02-14
  • 2020-11-10
  • 1970-01-01
  • 2021-05-28
  • 2014-04-07
  • 2021-12-27
  • 2018-07-30
  • 2017-07-26
相关资源
最近更新 更多