Skip to content

Instantly share code, notes, and snippets.

@cjgunnar
Created July 14, 2019 04:29
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 cjgunnar/7f4dd14f4b7730c724e72fdba1d46207 to your computer and use it in GitHub Desktop.
Save cjgunnar/7f4dd14f4b7730c724e72fdba1d46207 to your computer and use it in GitHub Desktop.
Timecheck bot source code (token hidden)
'''
Timecheck Discord Bot
Reminds those in the list to get on at 2:35, then 2:40
Only works with Python 3.6 as of 4/2/2019
'''
# IMPORTS
import time, datetime, pytz, asyncio
asyncio
import discord
from discord.ext import commands
# CONFIG
BOT_PREFIX = "?"
# keep that secret
TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
BOT_DESCRIPTION = "Reminds users to be in the Voice by 2:40 everyday"
# INIT
bot = commands.Bot(command_prefix=BOT_PREFIX,description=BOT_DESCRIPTION)
servers = list()
# blasted dates and times
tz = pytz.timezone("US/Central")
dailyTime = datetime.time(14,40)
nextDailyTime = datetime.datetime.fromtimestamp(datetime.datetime.now().timestamp() + 6 * 60)
nextDailyTime = tz.localize(nextDailyTime)
class NotifyServer():
def __init__(self, notifyGuild, notifyChannel, voiceChannel):
self.notifyGuild = notifyGuild
self.notifyChannel = notifyChannel
self.voiceChannel = voiceChannel
self.notifiers = list()
self.enabled = True
# EVENTS
@bot.event
async def on_ready():
print('Logged in as {}!'.format(bot.user.name))
# dates
dailyTime = getNextTime()
# run forever, async
startTime()
# COMMANDS
@bot.command()
async def addme(ctx):
''' Adds the user who sent the message to the list '''
if usersInThisGuild(ctx) == None:
await ctx.send("Guild not set up")
elif ctx.author in usersInThisGuild(ctx):
await ctx.send("{} is already on the list".format(ctx.author.name))
else:
usersInThisGuild(ctx).insert(0,ctx.author)
await ctx.send("Added {} to list".format(ctx.author.name))
@bot.command()
async def removeme(ctx):
''' Removes the user who sent the message from the list '''
if usersInThisGuild(ctx) == None:
await ctx.send("Guild not set up")
try:
usersInThisGuild(ctx).remove(ctx.author)
await ctx.send("{} was removed from the list".format(ctx.author.name))
except:
await ctx.send("{} was not on the list".format(ctx.author.name))
@bot.command()
async def who(ctx):
''' Sends the list '''
if usersInThisGuild(ctx) != None and len(usersInThisGuild(ctx)) > 0:
await ctx.send("Notifiers: {}".format(list(map(lambda member: member.name, usersInThisGuild(ctx)))))
else:
await ctx.send("Nobody in list")
@bot.command()
async def status(ctx):
''' Sends info of enabled and countdown time (min) '''
if notifyServer(ctx) != None:
msg = "Enabled: {}, {}min and counting...".format(notifyServer(ctx).enabled, round((nextDailyTime.timestamp() - datetime.datetime.now().timestamp()) /60))
await ctx.send(msg)
else:
await ctx.send("Not set up. Run 'setup <textchannelID> <voicechannelID>'")
# admin commands
@bot.command()
@commands.has_permissions(administrator=True)
async def setup(ctx, notify : discord.TextChannel, voice: discord.VoiceChannel):
'''
ADMIN-ONLY: Sets the textchannel for messages and voice channel for active members, initializes lists
Parameters:
notify (str): id of text channel
voice (str): id of voice channel
'''
global servers
if ctx.guild not in list(map(lambda server: server.notifyGuild, servers)):
newServer = NotifyServer(ctx.guild, notify, voice)
servers.insert(0,newServer)
await ctx.send("Successfully setup")
else:
await ctx.send("Already setup. To change channels use command 'config'")
@setup.error
async def setup_error(ctx, error):
if isinstance(error, commands.BadArgument):
await ctx.send('Error: could not find channel, try using the ID')
@bot.command()
@commands.has_permissions(administrator=True)
async def config(ctx, notify: discord.TextChannel, voice: discord.VoiceChannel):
'''
ADMIN-ONLY: Changes the textchannel for messages and voice channel for active members
Parameters:
notify (str): id of text channel
voice (str): id of voice channel
'''
notifyServer(ctx).notify = notify
notifyServer(ctx).voiceChannel = voice
@bot.command()
@commands.has_permissions(administrator=True)
async def enable(ctx):
''' ADMIN-ONLY: Enables the bot if it was disabled '''
if ctx.guild not in list(map(lambda server: server.notifyGuild, servers)):
await ctx.send("Server not setup, run ", BOT_PREFIX, " [TextChannel] [VoiceChannel]")
else:
notifyServer(ctx).enabled = True
@bot.command()
@commands.has_permissions(administrator=True)
async def disable(ctx):
''' ADMIN-ONLY: Disables the bot. Use 'enable' to resume operation '''
if ctx.guild not in list(map(lambda server: server.notifyGuild, servers)):
await ctx.send("Server not setup, run ", BOT_PREFIX, " [TextChannel] [VoiceChannel]")
else:
notifyServer(ctx).enabled = False
@bot.command()
@commands.has_permissions(administrator=True)
async def add(ctx, *, member : discord.Member):
'''
ADMIN-ONLY: Adds a member to the list
Parameters:
member (str): member to add to list, can be name or ID
'''
if member in usersInThisGuild(ctx):
await ctx.send("{} is already on the list".format(member.name))
else:
usersInThisGuild(ctx).insert(0,member)
await ctx.send("Added {} to list".format(member.name))
@bot.command()
@commands.has_permissions(administrator=True)
async def remove(ctx, *, member : discord.Member):
'''
ADMIN-ONLY: Removes a member from the list
Parameters:
member (str): member to remove from list, can be name or ID
'''
if member not in usersInThisGuild(ctx):
await ctx.send("{} is not on the list".format(member.name))
else:
usersInThisGuild(ctx).remove(member)
await ctx.send("Removed {} from the list".format(member.name))
#helpers
def usersInThisGuild(ctx):
for server in servers:
if ctx.guild == server.notifyGuild:
return server.notifiers
return None
def notifyServer(ctx):
for server in servers:
if ctx.guild == server.notifyGuild:
return server
return None
def getNextTime():
global dailyTime
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
tomorrowAtTime = datetime.datetime.combine(tomorrow, dailyTime)
return tomorrowAtTime
def getNotifiables(server):
return [x for x in server.notifiers if x not in server.voiceChannel.members]
def getMentions(users):
return " ".join(list(map(lambda user: user.mention, users)))
def startTime():
asyncio.ensure_future(checkTime())
# run in background
async def checkTime():
global nextDailyTime
global tz
print("checktime started")
while True:
# wait until 5 min before nextDailyTime
while datetime.datetime.now(tz).timestamp() < nextDailyTime.timestamp() - 5 * 60:
await asyncio.sleep(1)
# print("Time left: ", nextDailyTime.timestamp() - datetime.datetime.now(tz).timestamp())
# send reminder
await sendReminder()
# wait 5 min
await asyncio.sleep(5 * 60)
# send notifications
await sendTime()
# reset nextDailyTime to tomorrow
nextDailyTime = getNextTime()
# while loop repeats...
# time tasks
async def sendReminder():
# print("sending reminder")
for server in servers:
msg = "5 min: " + getMentions(getNotifiables(server))
await server.notifyChannel.send(msg)
async def sendTime():
# print("sending time")
for server in servers:
msg = "It's Time: " + getMentions(getNotifiables(server))
await server.notifyChannel.send(msg)
# BOOT
try:
bot.run(TOKEN)
except KeyboardInterrupt:
print('stopped')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment