bad_coder
bad_coder

Reputation: 201

Why is my python discord bot rate limited?

So I made a discord bot two years ago which filters certain channels and deletes messages which don‘t start with %z in one channel and %v in the other. It worked well for like 1 and a half years, but now it always states to be rate limited. This is the error I‘ve been consistently getting:

Traceback (most recent call last):
  File "main.py", line 196, in <module>
    bot.run(os.getenv("TOKEN"))
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 723, in run
    return future.result()
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 702, in runner
    await self.start(*args, **kwargs)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 665, in start
    await self.login(*args, bot=bot)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 511, in login
    await self.http.static_login(token.strip(), bot=bot)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/http.py", line 300, in static_login
    data = await self.request(Route('GET', '/users/@me'))
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/http.py", line 216, in request
    raise HTTPException(r, data)
discord.errors.HTTPException: 429 Too Many Requests (error code: 0): <!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" lang="en-US"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" lang="en-US"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-US"> <!--<![endif]-->
<head>
<title>Access denied | discord.com used Cloudflare to restrict access</title>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" id="cf_styles-css" href="/cdn-cgi/styles/main.css" />


<script>
(function(){if(document.addEventListener&&window.XMLHttpRequest&&JSON&&JSON.stringify){var e=function(a){var c=document.getElementById("error-feedback-survey"),d=document.getElementById("error-feedback-success"),b=new XMLHttpRequest;a={event:"feedback clicked",properties:{errorCode:1015,helpful:a,version:1}};b.open("POST","https://sparrow.cloudflare.com/api/v1/event");b.setRequestHeader("Content-Type","application/json");b.setRequestHeader("Sparrow-Source-Key","c771f0e4b54944bebf4261d44bd79a1e");
b.send(JSON.stringify(a));c.classList.add("feedback-hidden");d.classList.remove("feedback-hidden")};document.addEventListener("DOMContentLoaded",function(){var a=document.getElementById("error-feedback"),c=document.getElementById("feedback-button-yes"),d=document.getElementById("feedback-button-no");"classList"in a&&(a.classList.remove("feedback-hidden"),c.addEventListener("click",function(){e(!0)}),d.addEventListener("click",function(){e(!1)}))})}})();
</script>

<script defer src="https://performance.radar.cloudflare.com/beacon.js"></script>
</head>
<body>
  <div id="cf-wrapper">
    <div class="cf-alert cf-alert-error cf-cookie-error hidden" id="cookie-alert" data-translate="enable_cookies">Please enable cookies.</div>
    <div id="cf-error-details" class="p-0">
      <header class="mx-auto pt-10 lg:pt-6 lg:px-8 w-240 lg:w-full mb-15 antialiased">
         <h1 class="inline-block md:block mr-2 md:mb-2 font-light text-60 md:text-3xl text-black-dark leading-tight">
           <span data-translate="error">Error</span>
           <span>1015</span>
         </h1>
         <span class="inline-block md:block heading-ray-id font-mono text-15 lg:text-sm lg:leading-relaxed">Ray ID: 76714c325ede2a1e &bull;</span>
         <span class="inline-block md:block heading-ray-id font-mono text-15 lg:text-sm lg:leading-relaxed">2022-11-08 21:10:49 UTC</span>
        <h2 class="text-gray-600 leading-1.3 text-3xl lg:text-2xl font-light">You are being rate limited</h2>
      </header>

      <section class="w-240 lg:w-full mx-auto mb-8 lg:px-8">
          <div id="what-happened-section" class="w-1/2 md:w-full">
            <h2 class="text-3xl leading-tight font-normal mb-4 text-black-dark antialiased" data-translate="what_happened">What happened?</h2>
            <p>The owner of this website (discord.com) has banned you temporarily from accessing this website.</p>
            
          </div>

          
      </section>

      <div class="feedback-hidden py-8 text-center" id="error-feedback">
    <div id="error-feedback-survey" class="footer-line-wrapper">
        Was this page helpful?
        <button class="border border-solid bg-white cf-button cursor-pointer ml-4 px-4 py-2 rounded" id="feedback-button-yes" type="button">Yes</button>
        <button class="border border-solid bg-white cf-button cursor-pointer ml-4 px-4 py-2 rounded" id="feedback-button-no" type="button">No</button>
    </div>
    <div class="feedback-success feedback-hidden" id="error-feedback-success">
        Thank you for your feedback!
    </div>
</div>


      <div class="cf-error-footer cf-wrapper w-240 lg:w-full py-10 sm:py-4 sm:px-8 mx-auto text-center sm:text-left border-solid border-0 border-t border-gray-300">
  <p class="text-13">
    <span class="cf-footer-item sm:block sm:mb-1">Cloudflare Ray ID: <strong class="font-semibold">76714c325ede2a1e</strong></span>
    <span class="cf-footer-separator sm:hidden">&bull;</span>
    <span id="cf-footer-item-ip" class="cf-footer-item hidden sm:block sm:mb-1">
      Your IP:
      <button type="button" id="cf-footer-ip-reveal" class="cf-footer-ip-reveal-btn">Click to reveal</button>
      <span class="hidden" id="cf-footer-ip">104.154.103.35</span>
      <span class="cf-footer-separator sm:hidden">&bull;</span>
    </span>
    <span class="cf-footer-item sm:block sm:mb-1"><span>Performance &amp; security by</span> <a rel="noopener noreferrer" href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" target="_blank">Cloudflare</a></span>
    
  </p>
  <script>(function(){function d(){var b=a.getElementById("cf-footer-item-ip"),c=a.getElementById("cf-footer-ip-reveal");b&&"classList"in b&&(b.classList.remove("hidden"),c.addEventListener("click",function(){c.classList.add("hidden");a.getElementById("cf-footer-ip").classList.remove("hidden")}))}var a=document;document.addEventListener&&a.addEventListener("DOMContentLoaded",d)})();</script>
</div><!-- /.error-footer -->


    </div><!-- /#cf-error-details -->
  </div><!-- /#cf-wrapper -->

  <script>
  window._cf_translation = {};
  
  
</script>

<script>(function(){var js = "window['__CF$cv$params']={r:'76714c325ede2a1e',m:'znoAfytQLt8J9sKfY0I4_mTRBYFAl7dOuM8euJLqYDk-1667941849-0-AYSw2hSTYzbV97cXj5ih+If1W8kA87gei4YiN0U2gOJd5hz8D33GSYMHdzrzrZ0WNmGnttu8YcNUTcDIcRjoPpeUexP/4YyoCeZWj4As/JMm1ouGctUf9BwJOxkezKKJ/ldACNi1bMLPuHwzjhEETBM=',s:[0x69d76d5342,0x91aba9eed1],u:'/cdn-cgi/challenge-platform/h/b'};var now=Date.now()/1000,offset=14400,ts=''+(Math.floor(now)-Math.floor(now%offset)),_cpo=document.createElement('script');_cpo.nonce='',_cpo.src='/cdn-cgi/challenge-platform/h/b/scripts/alpha/invisible.js?ts='+ts,document.getElementsByTagName('head')[0].appendChild(_cpo);";var _0xh = document.createElement('iframe');_0xh.height = 1;_0xh.width = 1;_0xh.style.position = 'absolute';_0xh.style.top = 0;_0xh.style.left = 0;_0xh.style.border = 'none';_0xh.style.visibility = 'hidden';document.body.appendChild(_0xh);function handler() {var _0xi = _0xh.contentDocument || _0xh.contentWindow.document;if (_0xi) {var _0xj = _0xi.createElement('script');_0xj.nonce = '';_0xj.innerHTML = js;_0xi.getElementsByTagName('head')[0].appendChild(_0xj);}}if (document.readyState !== 'loading') {handler();} else if (window.addEventListener) {document.addEventListener('DOMContentLoaded', handler);} else {var prev = document.onreadystatechange || function () {};document.onreadystatechange = function (e) {prev(e);if (document.readyState !== 'loading') {document.onreadystatechange = prev;handler();}};}})();</script></body>
</html>

And here is my code:

import os
from keep_alive import keep_alive
import discord
import asyncio
from discord.ext import commands, tasks
from datetime import *
import pytz
import re

client = discord.Client()
intents = discord.Intents().all()

bot = commands.Bot(command_prefix="%", intents=intents, help_command=None)

msg_counter = 0


@bot.command(help="...")
async def help(ctx):
    await ctx.send("Please add %z before your message in the one channel, otherwise the message will be deleted after 24 hours. Same goes with %v for the other channel...")


@bot.event
async def on_ready():
    print(f"{bot.user} is now online")
    await bot.change_presence(activity=discord.Game(name="%help"))


@bot.event
async def on_message(ctx):
    global forbidden_words
    if is_name(ctx.content, forbidden_words):
        await ctx.delete()
    elif not ctx.author.bot:
        await bot.process_commands(ctx)


async def automatic_clear(channel, prefix):
    print("Started clearing %s" % channel.name)
    async for message in channel.history(limit=250, oldest_first=False):
        now = datetime.now(tz)
        msg_sended = message.created_at.astimezone(tz)
        difference = now - msg_sended
        difference_in_s = difference.total_seconds()
        bot_start = {
        "zitate": datetime.strptime("10.05.2021", "%d.%m.%Y").astimezone(tz),
        "vorstellungsrunde": datetime.strptime("12.11.2021", "%d.%m.%Y").astimezone(tz)
    }
        if not msg_sended < bot_start[str(channel.name)]:
            if difference_in_s > 86400:
                if not message.content.startswith(prefix):
                    print(f"\t\tDeleting: {str(message.author)}: {message.content}")
                    txt_print(f"{str(message.author)}: {message.content[:20]}")
                    await message.delete()
                    await asyncio.sleep(1)  # to avoid rate limits?!
                else:
                    print(f"\t\tSkipped: {str(message.author)}: {message.content[:20]}")
            else:
                print("\tzu aktuell (vor %i Sekunden)" % difference_in_s)
        else:
            print("\t\t\t" + message.content[:20] + str(msg_sended))
            break


@tasks.loop(hours=1)
async def clear_channel():
    global tz
    tz = pytz.timezone("Europe/Berlin")
    now = datetime.now(tz).strftime("%d.%m.%Y %H:%M:%S")
    print(f"{now}: DOING TASK!!!")
    channel1 = bot.get_channel(CHANNEL_NUMBER1)
    channel2 = bot.get_channel(CHANNEL_NUMBER2)
    try:
        await automatic_clear(channel1, "%z")
        await automatic_clear(channel2, "%v")
    except AttributeError:
        print("AttributeError (normal at the start of the bot)")
    print("Finished Task")

def txt_print(t):
    f = open("console.txt", "a")
    f.write(t + "\n")
    f.close()

forbidden_words = [
SOME SPAM WORDS
]


def is_name(s, fw):
    s = s.lower()
    for e in fw:
        if e in s:
            return False
    s = s.replace(" ", "")
    for letter in s:
        if letter not in "abcdefghijklmnopqrstuvwxyzäöüß":
            s = s.replace(letter, "")
    final_word = re.sub(r'(.)\1+', r'\1', s)
    print(final_word)
    for e in fw:
        if e in final_word:
            return True
    return False

@bot.event
async def on_message_edit(before, after):
    global forbidden_words
    if is_name(after.content, forbidden_words):
        await after.delete()
    else:
        await bot.process_commands(after)

async def keep_alive_msg(): #don‘t know if that actually helps, but at first I thought the bot would always be offline because it doesn‘t have to do anything, although I‘m using UptimeRobot and it says the bot was never down the last half year
    while True:
        try:
            keep_alive_channel = bot.get_channel(CHANNEL_NUMBER)
        await keep_alive_channel.send(str(random.randint(1, 100)))
    except AttributeError:
        print("Bot has just started")
    await asyncio.sleep(600)


keep_alive() #should keep the bot alive by creating kind of a website or something? idk it always worked
clear_channel.start() # start loop

bot.run(os.getenv("TOKEN")

I‘ve been pondering for days now but I cannot solve it. I even had to create a new discord application because discord deleted the first version of this bot after some time due to rate limits...

Upvotes: 1

Views: 965

Answers (1)

goose.mp4
goose.mp4

Reputation: 272

There is many reasons why you can get rate-limited from the Discord API. The official info is listed here.

From your comments, you said you were using replit. Replit is actually not all that good for hosting bots (but of course its easy, cheap/free, and friendly for beginners). This is for multiple reasons, including: Source code for your bot is public, relies on website being up (which goes down semi-frequently), and the biggest is you share an IP with other replit users. < This is most likely your problem. Your replit IP is banned from the Discord API, not necessarily your bot.

No worries, the fix for this is extremely simple. On the right-hand side (or bottom depending on the layout), you'll see another tab named shell (see image). Go to here, and enter in the command kill 1. That's it. Just do that, and it should just kill your current IP and replace it with a new one from replit.

The reason why this happens is because other replit users might also being hosting on a bot on the same IP and calling to the Discord API, which counts towards the amount of requests available before you're blocked.

enter image description here

Upvotes: 3

Related Questions