Auto message sender

Send messages in channels at different intervals
 avatar
unknown
python
6 days ago
3.4 kB
8
Indexable
"""Edit these!"""
TOKEN = "Replace with actual token"

dict_to_send = {
#   channelid: ["content to send in that chanelid", cooldown]
    0: ["content", 300],
    1: ["content2", 12]
}
"""."""

import discord
import time
import asyncio
import random
from discord.ext import tasks
client = discord.Client()
cmd_tracker = []
cooldown = 0

def find_least_gap(list_to_check):
    """
    Finds the minimum cooldown to loop through!
    """
    if len(list_to_check) < 2:
        return None

    final_result = {
        "min": list_to_check[0],
        "max": list_to_check[1],
        "diff": abs(list_to_check[1] - list_to_check[0])
    }

    for i in range(len(list_to_check) - 1):
        curr = list_to_check[i]
        next_item = list_to_check[i + 1]
        diff = abs(next_item - curr)

        if diff < final_result["diff"]:
            final_result["min"] = curr
            final_result["max"] = next_item
            final_result["diff"] = diff if diff > 0 else 1

    return final_result

def approximate_minimum_cooldown():
    """
    A wrapper for the function `find_least_gap`
    Ensures a cooldown do exist.
    """
    cooldowns_list = [
        item[1]
        for item in dict_to_send.values()
    ]

    if not cooldowns_list:
        # just in case
        return 1

    # Sort in ascending order
    cooldowns_list = sorted(cooldowns_list) 
    result = find_least_gap(cooldowns_list)

    if result:
        return min(result["diff"], min(cooldowns_list))
    else:
        return cooldowns_list[0]
    
def fetch_last_ran_diff(last_ran, cooldown):
    # Checks if command can be ran or not.
    if last_ran != 0:
        cd = (time.monotonic() - last_ran)
        return cd > cooldown
    else:
        return True
    

    
def populate_items():
    global dict_to_send, cmd_tracker
    for key, val in dict_to_send.items():
        # I am lazy...
        # Since this is a small code and nothing major, this should work just fine~
        cmd_tracker.append(
            {
                "command_id": f"{key}-{val[0]}-{val[1]}",
                "last_ran": 0
            }
        )

def fetch_last_ran(key, val):
    global cmd_tracker
    for item in cmd_tracker:
        if item["command_id"] == f"{key}-{val[0]}-{val[1]}":
            return item["last_ran"]
    return 0

def update_last_ran(key, val):
    global cmd_tracker
    for idx, item in enumerate(cmd_tracker):
        if item["command_id"] == f"{key}-{val[0]}-{val[1]}":
            cmd_tracker[idx]["last_ran"] = time.monotonic()

@tasks.loop()
async def command_handler():
    global cooldown

    for key, val in dict_to_send.items():
        req = fetch_last_ran_diff(fetch_last_ran(key, val), val[1])
        if req:
            await sender(key, val[0])
            update_last_ran(key, val)


    await asyncio.sleep(cooldown)


@client.event
async def on_ready():
    print(f"Logged in as {client.user}")
    global cooldown
    cooldown = approximate_minimum_cooldown()
    populate_items()
    print("starting command handler!")
    command_handler.start()


async def sender(channel_id, content):
    channel = await client.fetch_channel(channel_id)
    if channel:
        await channel.send(content)
    else:
        print(f"whoops, failed to send in channel with id: {channel_id}\nAre you sure the channel id is valid?")

client.run(TOKEN)

Editor is loading...
Leave a Comment