Created
July 14, 2019 04:29
-
-
Save cjgunnar/7f4dd14f4b7730c724e72fdba1d46207 to your computer and use it in GitHub Desktop.
Timecheck bot source code (token hidden)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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