Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Chatbot/Chatbot.py
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
296 lines (248 sloc)
15.8 KB
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
#==============This code was written by Emily================== | |
# This section of code was adapted from https://realpython.com/how-to-make-a-discord-bot-python/#creating-a-discord-connection by Emily | |
import os | |
import random | |
import discord | |
import steam | |
import requests | |
#import JSON | |
from steam.webapi import WebAPI | |
from dotenv import load_dotenv #only used so we can have the token outside of the source code | |
from steam.steamid import * | |
tempButPermIDArraySteam = [] | |
tempButPermIDArrayDiscord = [] | |
load_dotenv() | |
TOKEN = os.getenv('DISCORD_TOKEN') | |
GUILD = os.getenv('DISCORD_GUILD') | |
steamApiKey = os.getenv('STEAM_API_KEY') | |
catApiKey = os.getenv('CAT_API_KEY') | |
client = discord.Client() | |
api = WebAPI(key=steamApiKey) | |
#==================DEFINITIONS GO HERE================== | |
#==================Emily=Function=Start================= | |
#def fetchSteamID(): #this is a stub to replace | |
#return 76561198108012956 #my steamID, don't abuse pls - Emily | |
def fetchGameID(): #this is a stub to replace | |
return 582010 #this is monster hunter world | |
def steamAchievementPercentages(steamID, gameID): #Emily | |
steamID = str(steamID) | |
gameID = str(gameID) | |
achieveList= requests.get("http://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v0001/?appid=" +gameID+ "&key=" +steamApiKey+ "&steamid=" +steamID) | |
totalAchieves = 0 | |
achievesCompleted = 0 | |
#this section formats the api, might be useful in future definitions | |
achieveList = achieveList.text | |
achieveList = achieveList.replace("\"", " ") | |
achieveList = achieveList.replace("},{", "-") | |
#may need something adding to this line in future api use | |
achieveList = achieveList.strip("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,:0123456789\" {}") | |
#this section turns the string into a list | |
achieveList = list(achieveList.split("-")) | |
#this section iterates over the list to find the total achievements | |
#print (achieveList) | |
for achieve in achieveList: | |
if "achieved :0" in achieve: | |
totalAchieves = totalAchieves + 1 | |
if "achieved :1" in achieve: | |
achievesCompleted = achievesCompleted + 1 | |
totalAchieves = totalAchieves + 1 | |
if totalAchieves > 0: | |
percentage= round ((achievesCompleted/totalAchieves)*100, 2) | |
#messages are different depending on what % achieves you have | |
else: | |
percentage = 0 | |
if percentage <= 25: | |
reply = ["Do you even play this game?! You only have "+ str(percentage) +"% of the achievements unlocked! \nGit gud scrub"] | |
elif percentage <= 50: | |
reply = ["I don't know why you're asking for an embarrassing number, you have "+ str(percentage) +"% of achievements unlocked"] | |
elif percentage <= 75: | |
reply = ["You have " + str(percentage) + "% of achievements unlocked. \nGood job?"] | |
elif percentage < 100: | |
reply = ["You have " + str(percentage) + "% of steam achievements unlocked. \nNot quite 100% though is it?"] | |
else: | |
reply = ["You really don't have a life do you? You have all of the achievements for this game. \nDo they fill the hole in your life?"] | |
return random.choice(reply) | |
def isUserBanned(steamID):#Emily | |
linkCheck="http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=" + steamApiKey + "&steamids="+ str(steamID) | |
api = requests.get("http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=" + steamApiKey + "&steamids="+ str(steamID)) | |
print (linkCheck) | |
api = api.text | |
#api = ['"CommunityBanned":true', '"VACBanned":true', '"NumberOfVACBans":1', '"DaysSinceLastBan":1', '"NumberOfGameBans":5', '"EconomyBan":"none"}]}'] | |
#this section turns the string into a list | |
api = list(api.split(",")) | |
api = api[1:7] | |
print (api) | |
if api == ['"CommunityBanned":false', '"VACBanned":false', '"NumberOfVACBans":0', '"DaysSinceLastBan":0', '"NumberOfGameBans":0', '"EconomyBan":"yes"}]}']: | |
reply = ["Looks like you've been good! No bans all round"] | |
else: | |
banList = [] | |
if '"CommunityBanned":false' not in api: | |
banList.append("Community banned") | |
if '"VACBanned":false' not in api: | |
banList.append("VACBanned") | |
if '"EconomyBan":"none"}]}' not in api: | |
banList.append("Economy Banned") | |
if '"NumberOfGameBans":0' not in api: | |
gameBans = api[4] | |
gameBans = ''.join(x for x in gameBans if x.isdigit()) #for this list I used https://www.tutorialspoint.com/How-to-remove-characters-except-digits-from-string-in-Python for help | |
banList.append("you've had " + gameBans + " games ban you") | |
daysSinceBan = api[3] | |
daysSinceBan = ''.join(x for x in daysSinceBan if x.isdigit()) | |
banList.append("and it's been " + daysSinceBan + " days since you were last banned") | |
reply = ["Looks like you've been a bad little gamer because you have been: \n" + ", ".join(banList), | |
"Getting quite the ban collection here because you're: \n" + ", ".join(banList)] | |
return random.choice(reply) | |
def iNeedACat(): # Emily | |
api = requests.get("https://api.thecatapi.com/v1/images/search", params = {'q': 'requests+language:python'}, headers = {"authorisation":catApiKey}) | |
api = api.text | |
api = list(api.split(",")) | |
api = api[-3] | |
api = api[7:-1] | |
return api | |
def catMessage(): | |
reply = ["Here's a cat for you in these trying times", | |
"Emergency cat pics incoming!", | |
"*QUICK GET THE CATS*"] | |
return random.choice(reply) | |
#================Emily=Function=End============================================ | |
#================BenHB=Function=Start========================================== | |
#SteamID START | |
def findSteamID(message, discordID): | |
formattedSteamID = message.lower() | |
formattedSteamID = formattedSteamID.replace(" ","") #Formats the recieved message into an acceptable form for the program to iterate through | |
for charNum in range(len(formattedSteamID)): | |
if charNum == 0: | |
count = 0 | |
adjacencyStartIndex = 0 | |
currentChar = formattedSteamID[charNum] #loops through the message until 17 numbers are found to be adjacent to each other | |
if currentChar.isdigit(): | |
count = count + 1 | |
else: | |
count = 0 | |
adjacencyStartIndex = charNum + 1 | |
if count == 17: | |
formattedSteamID = formattedSteamID[adjacencyStartIndex:charNum+1] | |
break | |
if len(formattedSteamID) == 17 and formattedSteamID.isdigit(): #and formattedSteamID.steam.steamid.is_valid(): | |
if formattedSteamID not in tempButPermIDArraySteam and discordID not in tempButPermIDArrayDiscord : | |
tempButPermIDArrayDiscord.append(discordID) | |
tempButPermIDArraySteam.append(formattedSteamID) | |
sharedRelationshipIndex = tempButPermIDArrayDiscord.index(discordID) | |
return("I have your ID now. Thanks!!! \n Here is the ID that was registered: \n" + tempButPermIDArraySteam[sharedRelationshipIndex]) | |
elif(formattedSteamID in tempButPermIDArraySteam and discordID not in tempButPermIDArrayDiscord) or (formattedSteamID not in tempButPermIDArraySteam and discordID in tempButPermIDArrayDiscord): | |
sharedRelationshipIndex = tempButPermIDArrayDiscord.index(discordID) | |
return("This xor is working perfectly fine and will have code implemented shortly-ish... \n Here is the ID that was registered: \n" + tempButPermIDArraySteam[sharedRelationshipIndex]) | |
else: | |
sharedRelationshipIndex = tempButPermIDArrayDiscord.index(discordID) | |
return("I already have your ID. Thanks anyway though!!! \n Here is the ID that was registered: \n" + tempButPermIDArraySteam[sharedRelationshipIndex]) | |
else: | |
return("To link your steam requires a SteamID64 which can be found at:") | |
#SteamID END | |
#==================END OF DEFINITIONS=================== | |
@client.event #Prints in the terminal if bot connects successfully | |
async def on_ready(): | |
print(f'{client.user} has connected to Discord!') | |
for guild in client.guilds: | |
if guild.name == GUILD: | |
break | |
print( f'{client.user} is connected to the following guild:\n' | |
f'{guild.name}(id: {guild.id})') | |
members = '\n - '.join([member.name for member in guild.members]) | |
print(f'Guild Members:\n - {members}') | |
polls = {} # masud added this to hold poll data. Can be switched to a database in the future | |
@client.event | |
async def on_message(message): #checks for a message | |
if message.author == client.user: #makes sure it's a user | |
return | |
greetings = ["hello", "howdy", "hey",] #Says hello (creepily) to the user if they use a greeting word | |
if [entry for entry in greetings if(entry in message.content.lower())]: #This line is adapted from https://www.geeksforgeeks.org/python-test-if-string-contains-element-from-list/ by Emily | |
creepyHellos =["Why hello there, I am awakening from my slumber", | |
"My child I am learning, hi", | |
"I was enjoying the void before you woke me, I guess it's polite to say hello", | |
"Like life, my sleep was short. Hello child", | |
"Hello, what do you need me for this time?", | |
"Howdy y'all- yeah that wasn't working for me either. What can I do?",] | |
await message.channel.send(random.choice(creepyHellos)) | |
achievementWords = ["achievement", "steam" ] # This is to call the steamAchievementPercentages() function | |
#if [entry for entry in achievementWords if(entry in message.content.lower())]: | |
if "steam" in message.content.lower() and [entry for entry in achievementWords if(entry in message.content.lower())]: | |
await message.channel.send(steamAchievementPercentages(findSteamID(message.content.lower(), message.author.id), fetchGameID())) | |
banWords = ["banned", "ban", "bans"] | |
if "steam" in message.content.lower() and [entry for entry in banWords if(entry in message.content.lower())]: | |
try: | |
await message.channel.send(isUserBanned(findSteamID(message.content.lower(), message.author.id))) | |
except: | |
randomSteamIDErrorReplies = ["Ben get your SteamId function under control I can't work under these conditions", | |
"Something went wrong *looks pointedly at Ben*", | |
"Why it looks like the SteamID function broke down, I wonder why, *Ben*"] | |
await message.channel.send(random.choice(randomSteamIDErrorReplies)) | |
if "cat" in message.content.lower(): | |
await message.channel.send(catMessage()) | |
await message.channel.send(iNeedACat()) | |
# ================================================ | |
# ================ Masud did this ================ | |
if "salt " == (message.content.lower())[:5]: # checks if the input matches "salt " | |
communityName = (message.content)[5:] # saves the rest of the input as communityName | |
await message.add_reaction("🆗") # devops work item 35 | |
if communityName.upper() in polls.values(): # if there is a poll active already | |
pollID = list(polls.keys())[list(polls.values()).index(communityName.upper())] # get the ID of the poll | |
await message.channel.send(f'The community: {communityName} already has a poll active. Poll ID:{pollID}.') # message to discord | |
else: # and if there is not an active poll already... | |
poll = await message.channel.send(f'vote here for {communityName}:') # create the vote poll | |
# print(f'[BOT DEBUG] {communityName} added to list of polls') # print to console for debugging only | |
polls[poll.id] = communityName.upper() # save the pollID and communityName together | |
# print("[BOT DEBUG] Poll dict:\n",polls) # print list of polls active for debugging only | |
await poll.add_reaction("✅") # add the tick emoji for the poll | |
await poll.add_reaction("❌") # add the cross emoji for the poll | |
if "count " == (message.content.lower())[:6]: # checks if the input matches "count ". DevOps work item 33 | |
communityName = (message.content)[6:] # saves the rest of the input as communityName | |
if communityName.upper() not in polls.values(): # checks if the poll does not exist already | |
await message.channel.send(f'No poll found for community: {communityName}.') # messages to discord | |
else: # if the poll does exist ... | |
pollID = list(polls.keys())[list(polls.values()).index(communityName.upper())] # get the pollID with the matching communityName | |
pollMessage = await message.channel.fetch_message(pollID) # get the message object with the pollID | |
pollReactions = pollMessage.reactions # accesses the reactions for the pollMessage object | |
await message.channel.send(f'Here are the saltiness statistics for the community {communityName}\nPoll ID:{pollID}') # message to discord | |
countEmbed = discord.Embed() # Discord embed object | |
countDesc = "" # description of countEmbed object | |
countEmbed.title = f"Is the community {communityName} salty or supportive?" # title of countEmbed object. DevOps work item 32 | |
tickCount = 0 | |
crossCount = 0 | |
for emj in pollReactions: # for each emoji in the reactions object | |
emojiCount = emj.count - 1 # remove 1 vote, which was from the bot. | |
# print("[BOT DEBUG] emj.emoji:",emj.emoji) # debug code for reactions.emoji object | |
if emj.emoji == "✅": # if emoji is tick emoji | |
tickCount = emj.count - 1 # this reaction will be tickCount | |
elif emj.emoji == "❌": # if emoji is cross emoji | |
crossCount = emj.count - 1 # this reaction will be crossCount | |
if emojiCount == 1: # adjust embed description accordingly | |
countDesc = countDesc + f'\n{emj.emoji} : {emojiCount} vote' | |
else: | |
countDesc = countDesc + f'\n{emj.emoji} : {emojiCount} votes' | |
# add a message to the end of the results depending on the votes for the emojis. DevOps work item 34 | |
# print("[BOT DEBUG] tick cross :",tickCount,crossCount) # this code was used to debug the tick and cross counts. | |
if tickCount == crossCount: | |
countDesc = countDesc + "\n This community seems to be equally supportive and salty." | |
elif tickCount > crossCount: | |
countDesc = countDesc + "\n This community seems to be more supportive." | |
elif tickCount < crossCount: | |
countDesc = countDesc + "\n This community seems to be more salty." | |
# add the description to the embed and message it to the channel. | |
countEmbed.description = countDesc # add embed description to embed | |
await message.channel.send(embed=countEmbed) # send the embed to the channel the message is in | |
# ================ up to about here ================ | |
#BenHB Start | |
if ' steamid ' in message.content.lower() or ' steam id ' in message.content.lower() or 'steamid' in message.content.lower() or 'steam id ' in message.content.lower(): | |
messageInfo = findSteamID(message.content, message.author.id) | |
await message.channel.send(messageInfo) | |
#GameID START ======= WIP | |
#async def gameIDRetrieve(gameName): | |
#sharedIDIndex = tempButPermIDArrayDiscord[message.author.id] | |
#steamId = tempButPermIDArraySteam[sharedIDIndex] | |
#response = await fetch(`https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=${steamApiKey}&steamid=${profileId}&format=json`); | |
#json = await response.json(); | |
#userGameIDs = json.response.games.map(o=>o.appid); | |
#console.log(JSON.stringify(userGameIDs)); | |
#BenHB End | |
client.run(TOKEN) #this is the token of the discord bot. You can create your own bot and put that token in here or the .env file to run the code | |
#================================ |