Last active
September 1, 2017 04:58
-
-
Save kbrsh/ce6de1509ddb02d2bbda59483a62b3ae to your computer and use it in GitHub Desktop.
Galaxy - Spread Stars
This file contains 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
from slackclient import SlackClient | |
from random import randint | |
import re | |
import time | |
import sqlite3 | |
import os | |
userRE = re.compile("<@([\w\d]+)>") | |
db = sqlite3.connect("Galaxy.db") | |
db.execute("CREATE TABLE IF NOT EXISTS SCORES (ID TEXT PRIMARY KEY, AMOUNT TEXT)") | |
token = os.environ["SLACK_TOKEN"] | |
sc = SlackClient(token) | |
usersList = sc.api_call("users.list") | |
userIDS = {} | |
channelMessageAmount = {} | |
channelMessageUsers = {} | |
maxThreadMessageLimit = 10 | |
maxThreadUserLimit = 5 | |
admin = set(["kbr", "galaxy", "lucadem1313"]) | |
adminIDS = [] | |
kbrID = None | |
for userInfo in usersList["members"]: | |
userIDS["<@" + userInfo["id"] + ">"] = userInfo["id"] | |
if userInfo["name"] in admin: | |
if userInfo["name"] == "kbr": | |
kbrID = userInfo["id"] | |
db.execute("INSERT OR IGNORE INTO SCORES (ID,AMOUNT) VALUES (?,'∞')", [userInfo["id"]]) | |
adminIDS.append(userInfo["id"]) | |
db.commit() | |
helpMessage = """Hey Universe! | |
I'm Galaxy. :milky_way: | |
If you want to show someone that you appreciate them, you can give them a :star:. Just mention them and add a star emoji anywhere in your message. You can also mention multiple people at once. | |
Here are some other things I can do: | |
Commands: | |
- `galaxy top` view user leaderboard | |
- `galaxy show @user` view a user's stars | |
- `galaxy help` show this help message | |
Administrators have special privileges, and have infinite stars! They can also run the following commands: | |
- `galaxy remove @user <amount>` remove a certain amount of stars from a user | |
- `galaxy post <channel> <message>` post a message to a channel | |
- `galaxy lottery` conduct a lottery | |
I'm a bot made by <@""" + kbrID + """>.""" | |
def post(event, message): | |
if "thread_ts" in event: | |
sc.api_call( | |
"chat.postMessage", | |
channel=event["channel"], | |
text=message, | |
thread_ts=event["thread_ts"] | |
) | |
else: | |
sc.api_call( | |
"chat.postMessage", | |
channel=event["channel"], | |
text=message | |
) | |
def insert(ID): | |
db.execute("INSERT INTO SCORES (ID,AMOUNT) VALUES (?,'1')", [ID]) | |
db.commit() | |
def update(ID, amount): | |
db.execute("UPDATE SCORES set AMOUNT = ? where ID = ?", [amount, ID]) | |
db.commit() | |
def getAmount(ID): | |
cursor = db.execute("SELECT AMOUNT FROM SCORES WHERE ID = ?", [ID]).fetchone() | |
if cursor == None: | |
return None | |
else: | |
return cursor[0] | |
def getRandom(): | |
return db.execute("SELECT ID,AMOUNT FROM SCORES ORDER BY RANDOM() LIMIT 1").fetchone() | |
if sc.rtm_connect(): | |
while True: | |
res = sc.rtm_read() | |
for event in res: | |
if "subtype" not in event and event["type"] == "message": | |
text = event["text"] | |
user = event["user"] | |
channel = event["channel"] | |
cmd = text[0:6] | |
isAdmin = user in adminIDS | |
# Warn about threads | |
if "thread_ts" not in event: | |
if channel in channelMessageUsers: | |
if user not in channelMessageUsers[channel]: | |
channelMessageUsers[channel].append(user) | |
else: | |
channelMessageUsers[channel] = [user] | |
if channel in channelMessageAmount: | |
channelMessageAmount[channel] += 1 | |
else: | |
channelMessageAmount[channel] = 1 | |
if channelMessageAmount[channel] >= maxThreadMessageLimit: | |
channelMessageUsersLength = len(channelMessageUsers[channel]) | |
if channelMessageUsersLength <= maxThreadUserLimit and channelMessageUsersLength > 1: | |
post(event, "Use threads please. " + (" ".join([("<@" + userID + ">") for userID in channelMessageUsers[channel]]))) | |
channelMessageUsers[channel] = [] | |
channelMessageAmount[channel] = 0 | |
if cmd == "galaxy": | |
split = text.split(" ") | |
cmd = split[1] | |
if cmd == "help": | |
# Show Help Message | |
post(event, helpMessage) | |
elif cmd == "show": | |
# Show Stars | |
if len(split) == 2: | |
post(event, "Please include a user.") | |
else: | |
showUser = split[2] | |
if showUser in userIDS: | |
amount = getAmount(userIDS[showUser]) | |
if amount == None: | |
post(event, "User " + showUser + " does not have any stars.") | |
else: | |
plural = "s" | |
if amount == "1": | |
plural = "" | |
post(event, "User " + showUser + " has recieved " + amount + " star" + plural + ". :stars:") | |
else: | |
post(event, "User \"" + showUser + "\" does not exist") | |
elif cmd == "top": | |
# Show top 10 users | |
allResultsRaw = db.execute("SELECT ID,AMOUNT FROM SCORES ORDER BY CAST(AMOUNT AS INTEGER) DESC LIMIT 10").fetchall() | |
allResults = [[kbrID, "∞"]] | |
message = "Top Members of the Galaxy\n\n" | |
for adminID in adminIDS: | |
if adminID != kbrID: | |
allResults.append([adminID, "∞"]) | |
for result in allResultsRaw: | |
if result[0] not in adminIDS: | |
allResults.append(result) | |
for result in allResults: | |
message += "- <@" + result[0] + ">: " + result[1] + "\n" | |
post(event, message) | |
elif cmd == "remove" and isAdmin: | |
# Remove a certain amount from a user | |
length = len(split) | |
if length < 4 or userRE.search(text) == None: | |
post(event, "Please include a user and an amount") | |
else: | |
plural = "s" | |
amountToRemove = int(split[length - 1]) | |
if amountToRemove == 1: | |
plural = "" | |
matches = [] | |
for match in userRE.finditer(text): | |
mentioned = match.group(1) | |
if mentioned not in matches: | |
matches.append(mentioned) | |
oldAmount = getAmount(mentioned) | |
if oldAmount == None: | |
post(event, "User <@" + mentioned + "> does not have any stars.") | |
elif mentioned not in adminIDS: | |
pluralStars = "s" | |
newAmount = str(int(oldAmount) - amountToRemove) | |
if newAmount == "1": | |
pluralStars = "" | |
elif newAmount[0] == "-": | |
newAmount = "0" | |
update(mentioned, newAmount) | |
post(event, "<@" + user + "> removed " + str(amountToRemove) + " star" + plural + " from " + "<@" + mentioned + ">, who now has " + newAmount + " star" + pluralStars + "! :collision:") | |
else: | |
post(event, "<@" + mentioned + "> has infinite stars. :stars: :sparkles:") | |
elif cmd == "post" and isAdmin: | |
# Post a message as Galaxy | |
channel = "#" + split[2] | |
del split[:3] | |
event["channel"] = channel | |
post(event, " ".join(split)) | |
elif cmd == "lottery" and isAdmin: | |
# Conduct lottery | |
prize = randint(1, 3) | |
result = getRandom() | |
while result[0] in adminIDS: | |
result = getRandom() | |
total = str(int(result[1]) + prize) | |
update(result[0], total) | |
post(event, "<@" + result[0] + "> won " + str(prize) + " :star:s! They now have " + total + " stars. :sparkler: :moneybag:") | |
elif ":star:" in text and userRE.search(text): | |
# Give a star | |
matches = [] | |
for match in userRE.finditer(text): | |
mentioned = match.group(1) | |
if mentioned not in matches: | |
matches.append(mentioned) | |
if user == mentioned: | |
post(event, "Nice try, <@" + user + ">.") | |
elif mentioned in adminIDS: | |
post(event, "<@" + mentioned + "> has infinite stars. :stars: :sparkles:") | |
else: | |
currentAmount = getAmount(mentioned) | |
amount = "1" | |
plural = "s" | |
if currentAmount == None: | |
plural = "" | |
insert(mentioned) | |
else: | |
amount = str(int(currentAmount) + 1) | |
update(mentioned, amount) | |
post(event, "<@" + user + "> sent a :star: to " + "<@" + mentioned + ">, who now has " + amount + " star" + plural + "! :sparkles:") | |
time.sleep(1) | |
db.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment