Skip to content

Instantly share code, notes, and snippets.

@0xdeepmehta
Created February 21, 2021 09:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xdeepmehta/c44c9968d907b6e5db51aa8cdacd96af to your computer and use it in GitHub Desktop.
Save 0xdeepmehta/c44c9968d907b6e5db51aa8cdacd96af to your computer and use it in GitHub Desktop.
DiscordreminderBot
#!/usr/bin/env python
"""
Name: Notifier
Description: A discord bot to handle schedules.
"""
import os
import discord
import asyncio
import sys
import requests
from datetime import datetime
from discord.ext import commands
from discord.ext import tasks
from core.config import LOG_PREFIX as L, DATETIME_FORMAT, EMOJIS, SETREMINDER, CLEAR, DELREMINDER
from core.database import Reminder, Prefix
from core.config import db
from core.utils import check_datetime_format, convert_to_hex_color, get_current_time
TOKEN = os.getenv("CLIENT_SECRET")
log_file = open("log.txt", "a")
db.connect()
def determine_prefix(client, message):
server = Prefix.get(Prefix.server == str(message.guild.id))
return server.char
client = commands.Bot(command_prefix=determine_prefix)
## Bot Commands Section.
@client.event
async def on_ready():
print(f"{L}Notifier started the fire.")
@client.command()
@commands.has_role('notifier')
async def setreminder(ctx):
"""
Saves a reminder.
"""
print(f"{L}Process of setting reminding start.")
await ctx.send(f"Please mention the discord channel you would like remind to be sent in:\n\nFor example: #reminders\n**Within {SETREMINDER['mention']} sec.**")
server = Prefix.get(Prefix.server == str(ctx.message.guild.id))
# Taking the channel mention.
try:
channel = await client.wait_for("message", check=lambda m: len(m.channel_mentions) == 1 and m.author == ctx.author, timeout=SETREMINDER['mention'])
print(f"{L}Channel: ", channel.content)
except Exception as e:
await ctx.send(f"**No Remider Added.**, {str(e)}")
return None
# Taking mesasge
await ctx.send(f"Please enter the message you wanna use as an reminder. \n\nYou've {SETREMINDER['message']} sec.")
try:
message = await client.wait_for("message", check=lambda m: m.author == ctx.author, timeout=SETREMINDER['message'])
print(f"{L}Message: ", message.content)
except Exception as e:
await ctx.send(f"**No Remider Added.**, {str(e)}")
return None
# Taking the time.
await ctx.send(f"What time will the message be sent?\n\nExample format: Jun 1 2005 1:33PM\n**Within {SETREMINDER['datetime']} seconds.**")
try:
msg = await client.wait_for("message", check=lambda msg: check_datetime_format(msg) and ctx.author == msg.author, timeout=SETREMINDER['datetime'])
except Exception as e:
await ctx.send(f"**No Remider Added.**, {str(e)}")
return None
time = datetime.strptime(msg.content, DATETIME_FORMAT)
def check_emoji(reaction, user):
return user == message.author and str(reaction.emoji) == '👍'
confirmation_message = f"""
**Does this look correct?**
Channel:
> {channel.content}
Message:
> {message.content}
Time:
> {msg.content}
React with {EMOJIS['+1']} to set remainder.
Within {SETREMINDER['confirm']} seconds.
"""
embed = discord.Embed(title="Reminder Task.", description=confirmation_message, colour=int(server.color))
c_m = await ctx.send(embed=embed)
await c_m.add_reaction(EMOJIS['+1'])
await c_m.add_reaction(EMOJIS['-1'])
# Confirming
try:
reaction, user = await client.wait_for('reaction_add', timeout=SETREMINDER['confirm'], check=check_emoji)
except TimeoutError:
await ctx.send("**No Remider Added.**")
return None
reminder = Reminder.create(server=str(ctx.message.guild.id), channel=channel.channel_mentions[0].id, message=message.content, time=time)
await ctx.send("**Reminder Confirmend.**")
@client.command()
@commands.has_role('notifier')
async def clear(ctx):
print(f"{L}Staring the process of deleting all the tasks.")
await ctx.send(f"**Do you want to delete all the reminders.**\n\nOption: (yes/no)\nWithin {CLEAR['confirm']} seconds.")
msg = await client.wait_for('message', check=lambda m: m.content == 'yes', timeout=CLEAR['confirm'])
Reminder.delete().where(Reminder.server == ctx.message.guild.id).execute()
await ctx.send("**All records are cleared.**")
print(f"{L}Deleted all records.")
@client.command()
@commands.has_role('notifier')
async def delreminder(ctx):
"""
List all the reminders and remove according to the input.
"""
reminders = Reminder.select().where(Reminder.server == str(ctx.message.guild.id))
message = """
**Select which upcoming one you wanna remove.**
"""
server = Prefix.get(Prefix.server == str(ctx.message.guild.id))
hash_map = {}
count = 1
if len(reminders) == 0:
return await ctx.send("**Sorry, 😥 there are no upcoming reminders.**")
for reminder in reminders:
msg = f"""
ID: {count}
Time: {reminder.time}
Message: {reminder.message}
"""
hash_map[count] = reminder.id
count += 1
message += msg
embed = discord.Embed(title="Select Reminder.", description=message + f"\n\n**Enter the Id of the reminder you wanna remove.**\nWithin {DELREMINDER['id']} seconds.", colour=int(server.color))
m = await ctx.send(embed=embed)
try:
msg = await client.wait_for('message', check=lambda msg: str(msg.content).isnumeric() and int(msg.content) in hash_map.keys() and msg.author == ctx.author, timeout=DELREMINDER['id'])
except:
return await ctx.send(f"**Oh! 😥 Timeout.**")
await ctx.send(f"Are you sure you wanna remove it? \nType `yes` to delete it.\nAnswer within {DELREMINDER['confirm']} seconds.")
try:
choice = await client.wait_for('message', check=lambda m: m.content == 'yes' and m.author == ctx.author and m.content != 'no', timeout=DELREMINDER['confirm'])
except:
return await ctx.send(f"**Oh! 😥 Timeout.**")
Reminder.delete().where(Reminder.id==int(msg.content)).execute()
await ctx.send("**Deleted.**")
@client.event
async def on_guild_join(guild):
print(f"{L}Bot, Joined {guild} and i'm setting prefix to '.'")
await guild.create_role(name="notifier", colour=discord.Color.green())
Prefix.create(server=str(guild.id), prefix=".")
@client.event
async def on_guild_remove(guild: discord.Guild):
try:
Prefix.delete().where(Prefix.server == str(guild.id)).execute()
for role in guild.roles:
if role.name == "notifier":
role.delete()
print(f"{L}Removed the record of prefix from {guild}")
except:
print(f"{L}Oh! man I can't find record of {guild}")
@client.command()
@commands.has_role('notifier')
async def setprefix(ctx, prefix):
if len(prefix) != 0:
server = Prefix.get(Prefix.server == str(ctx.message.guild.id))
server.char = prefix
server.save()
print(f"{L}Changed the prefix to '{prefix}' of '{ctx.message.guild.id}'")
await ctx.send("Prefix changed.")
else:
await ctx.send("**X Wrong Command, please specify the prefix.**")
@client.command()
@commands.has_role('notifier')
async def setcolor(ctx: commands.Context, color):
if len(color) != 0:
if int_color := convert_to_hex_color(color):
server_id = ctx.message.guild.id
server = Prefix.get(Prefix.server == str(server_id))
server.color = int_color
server.save()
return await ctx.send(f"**Color changed to {color}**")
return await ctx.send("**Oh! Not a valid color format.**")
@client.command()
@commands.has_role('notifier')
async def time(ctx: commands.Context):
guild_id = str(ctx.message.guild.id)
server = Prefix.get(Prefix.server == guild_id)
now = get_current_time(server.timezone)
message = f"""
**Timezone: ** {server.timezone}
**Date: ** {now.strftime("%D")}
**Time: ** {now.strftime("%H : %M")}
"""
embed = discord.Embed(title="Time", description=message, colour=server.color)
await ctx.send(embed=embed)
@client.command()
@commands.has_role('notifier')
async def settz(ctx: commands.Context, timezone: str):
if get_current_time(timezone):
guild_id = str(ctx.message.guild.id)
server = Prefix.get(Prefix.server == guild_id)
server.timezone = timezone
server.save()
return await ctx.send(f"Timezone set to **{timezone}**")
return await ctx.send(f"**Ah! Not a valid timezone.**")
# NOT ACTIVE ::
# #
# @client.command()
# async def setavatar(ctx: commands.Context):
# if len(ctx.message.attachments) == 1:
# url = ctx.message.attachments[0].url
# r = requests.get(url)
# try:
# await client.user.edit(avatar=r.content)
# except:
# return await ctx.send("**I don't wanna change.**")
# await ctx.send("**Avatar Changed.**")
# Task to send reminder.
async def send_notification():
await client.wait_until_ready()
print(f"{L}Executing the reminding task.")
while not client.is_closed():
print(f"{L}Loop Started.")
for r in Reminder.select():
server = Prefix.get(Prefix.server == r.server)
now = get_current_time(server.timezone)
if now.year == r.time.year and now.month == r.time.month and now.day == r.time.day and now.hour == r.time.hour and now.minute == r.time.minute:
guild = client.get_guild(int(r.server))
channel = guild.get_channel(int(r.channel))
await channel.send(r.message)
# Removing the message from database as soon it send.
Reminder.delete().where(Reminder.id == r.id).execute()
await asyncio.sleep(60)
# @client.event
# async def on_message(message):
# if message.author == client.user:
# return None
# reminders = Reminder.select()
# now = datetime.now()
# for r in reminders:
# # if now.year == r.year and now.month == r.month and now.day == r.day and now.hour == r.hour and now.minute == r.minute:
# channel = client.get_channel(int(r.channel))
# await channel.send(r.message)
if __name__ == "__main__":
if len(sys.argv) == 1:
client.loop.create_task(send_notification())
client.run(TOKEN)
elif len(sys.argv) == 2:
if sys.argv[1] == "recreate":
db.create_tables([Reminder, Prefix])
print(f"{L}Database tables updated.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment