mail@pastecode.io avatar
3 years ago
8.5 kB
import discord
import asyncio
from discord.ext import commands, tasks
import motor.motor_asyncio
from random import choice as randchoice

channel_dict = {}
message_dict = {}

messages_list = []

CHANNEL = 854168037501435918

# for each_message in ad_messages:
#     message =

class Ad_Loop_Message(commands.Cog):

    def __init__(self, bot):
        self.bot = bot
        self.channel_tasks = {}

# Allow people to change the channels where the main ad is sent and to change the main ad loop duration time.

    async def on_ready(self): ### on_ready event for the bot.
        await self.bot.loop.create_task(self.get_interval_message_data())
        ad_messages_2 = self.bot.db.Ad_Messages.find()
        async for each_message in ad_messages_2:
            message_dict[each_message["ad_name"]] = each_message["ad_message"]

    async def on_command_error(self, ctx, error):
        await ctx.message.delete()
        if isinstance(error, commands.CommandOnCooldown):
            await ctx.channel.send('This command can only be used 1 time every 60 seconds.')

    @commands.cooldown(1, 60, commands.BucketType.guild)
    async def setup(self, ctx):
        db_document = self.bot.db.Guilds.find({"guild_id" : ctx.guild.id}).limit(1)
        async for i in db_document:
            if i["main_ad_on_or_off"] == False:
                await ctx.message.channel.send("Ping the names (ex. '#general, #announcements, #partners' or, if you want only one channel, ping just that channel, such as: '#giveaways') of the channels that you want the main message ad to run in. Seperate each channel with a comma.")
                def check(m):
                    return m.channel_mentions and m.channel.id == ctx.message.channel.id
                dict = {
                    "main_ad_channels" : {

                response_1 = await self.bot.wait_for('message', timeout = 30, check = check)
                for x in response_1.channel_mentions:
                    dict["main_ad_channels"]["channel_" + x.name] = x.id
                insert_update = self.bot.db.Guilds.update_one({"guild_id": ctx.guild.id}, { "$set" : dict})

                await ctx.message.channel.send("Channels have been set!")

                print("done 1")

                await ctx.message.channel.send("Set the duration you want each message ad to be sent in minutes. Minimum is 5 minutes, and maximum is 1440 minutes. No decimals or fractions, it must be a whole number. (ex. '5', or '60', or '1440')")

                def check(m_2):
                    return m_2.content.isdigit() and m_2.channel == ctx.message.channel and int(m_2.content) in range(5,1441)

                response_2 = await self.bot.wait_for('message', check = check)
                insert_update_2 = self.bot.db.Guilds.update_one({"guild_id": ctx.guild.id}, { "$set" : {"main_ad_loop_duration_time" : int(response_2.content)}})

                await ctx.channel.send("The bot is currently running ads. In order to change the setup functionality (channels and time intervals) please use the (command_prefix)stopad (ex. >stopad) command first.")

    # Give owner options about which ad they want to run on the server.
    # Ask a prompt for the Channels that it will be displayed in.
    # Ask a prompt for the time set_duration.
    # Ask anything else here.
    # Add timeout and then try: and except: the timeout after 60 seconds to check for when people forget to write anything.
    # Add an X emoji that people can select to stop the process.

    async def set_duration(self, ctx, time): ### Adds the duration that the main ad loop time will be as an integer. Adds it into the database to be used by the loop task as a way to know how long the server owner wanted each main advertisement to be sent.
        dict = {
            "main_ad_loop_duration_time" : int(time)
        x = self.bot.db.Guilds.update_one({"guild_id": ctx.guild.id}, { "$set": dict}) ### Adds the time given by the user as the 'time' parameter into the database.
    # Display error message. Display error message if 'time' parameter is not an integer.
    # Send message saying that the time has been set to x MINUTES. Specify that it is minutes.
    # Make minutes limited to a minimum of 5 minutes and a maximum of the product of 60x24 or just 60 minutes.

    async def startad(self, ctx): ### Adds the True value to the guild's document and begins sending the ads.
        insert_one = self.bot.db.Guilds.update_one({"guild_id" : ctx.guild.id}, {"$set" : {"main_ad_on_or_off" : True}})
        ctx.send("Ads started.")

    async def stopad(self, ctx):
        insert_one = self.bot.db.Guilds.update_one({"guild_id" : ctx.guild.id}, {"$set" : {"main_ad_on_or_off" : False}})
        ctx.send("Ads stoped.")

    async def get_interval_message_data(self): ### This takes the information about the time duration and channels where the main ad will be displayed, which are set by the server owner, from the database. Then, this loop task sends the message in the specific channels ever x given minutes.
        await self.bot.wait_until_ready()
        all_documents = self.bot.db.Guilds.find()
        async for each_document in all_documents:
            interval = each_document["main_ad_loop_duration_time"]
            for each_channel in each_document["main_ad_channels"].values():
                got_channel = self.bot.get_channel(each_channel)
                channel_dict[got_channel.id] = {"channel_id": int(each_channel), "interval": int(interval)}

    async def sender(self, timetosleep, channeltosend):
        while not self.bot.is_closed():
            channeltosend_2 = self.bot.get_channel(channeltosend)
            async for message in channetosend_2.history():
                if message.author.id == self.bot.user.id:
                    break #return so you won't have to keep iterating. Once the first message by the bot in the history function is found it stops the for loop.
            await asyncio.sleep(timetosleep)
            random_message = randchoice(list(message_dict.values()))
            await channeltosend_2.send(random_message)

            # Don't send the same ad more than twice in a row unless there is only one ad in the database.
            # Make time interval into minutes and not seconds.
            # Only usable by people with admin perms.

            # Add the phone features.
            # Make sure there are no errors.
            # Make it pretty.
            # Picture ads.

    async def db_loop_and_task_create(self):
        while not self.bot.is_closed():
            for each_channel_2 in channel_dict:
                c = channel_dict[each_channel_2]["channel_id"]
                db_document = await self.bot.db.Guilds.find({"guild_id" : self.bot.get_channel(each_channel_2).guild.id}).to_list(length=1)
                for i in db_document:
                    if i["main_ad_on_or_off"] == True:
                        if channel_dict[each_channel_2]["channel_id"] in self.channel_tasks:
                            if c in self.channel_tasks and not self.channel_tasks[c].cancelled():
                        time_interval = channel_dict[each_channel_2]["interval"]
                        channel_to_send = channel_dict[each_channel_2]["channel_id"]
                        task_sender = self.bot.loop.create_task(self.sender(time_interval, channel_to_send))
                        self.channel_tasks[channel_dict[each_channel_2]["channel_id"]] = task_sender
                        if c in self.channel_tasks and not self.channel_tasks[c].cancelled():

def setup(bot):