Skip to content
Permalink
master
Switch branches/tags

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?
Go to file
 
 
Cannot retrieve contributors at this time
import json
import requests
import time
import urllib
import configparser
import logging
import random
#credit for these tutorials which helped when creating LunaWei:
#https://www.codementor.io/garethdwyer/building-a-telegram-bot-using-python-part-1-goi5fncay
#https://github.com/livz/LanaBot
#emoji source
#https://unicode.org/emoji/charts/full-emoji-list.html
#weather api source
#https://openweathermap.org/
#jokes found at: https://inews.co.uk/light-relief/humour/jokes-kids-funny/
#facts found at: https://www.thefactsite.com/2011/07/top-100-random-funny-facts.html
lunatoken = " "
OWM_KEY = " "
news = ["https://www.bbc.co.uk/news", "https://www.telegraph.co.uk/news/", "https://www.dailymail.co.uk/news/index.html", "https://www.thesun.co.uk/news/", "https://www.theguardian.com/uk"]
#greetings
greetings = ["hello \U0001F60B", "hello", "hi \U0001F61B", "hi", "what's up", "hey", "hi!", "hola", ]
inline_bot = " Hey some cool bots that already exist and might be useful are :\n @gif/@coub to search for GIF\n@youtube/@vid to search videos on Youtube\n@bing/@pic to search images on Bing and Yandex\n@wiki to search for information on Wikipedia (opens link)\n@imdb to search movies info on IMDB\n@sticker to search for stickers using available emoji\n@dictrobot/@exactlyappbot to search for English dictionary definitions of words\n@iLyricsBot to search for Lyrics to any song\n@lutilbot to translate words/sentences into over 70 languages using InLine Translator\n@gamee/@gamebot to get a list of available Telegram games which play in-app"
#bye
bye = ["bye \U0001F44B","bye", "see you", "see ya", "talk to you later ! \U0001F44B", "I'm gonna miss you!", "Stay safe \U0001F60A"]
#thanks
thanks = ["thank you \U0001F60A", "tks", "thanks", "thank you", "ty", "Thanks \U0001F60A"]
welcome = ["you're welcome", "no problem", "welcome"]
welcome_RESP = ["okay", "so, tell me more about you!", "okie"]
#Compliment ( user to bot)
compliment = ["you're cute", "cute", "you're so nice", "you're lovely", "smart luna", "you're smart", "smart"]
#BotFeelings -> user / BAD language
like = ["we are friends", "let's be friends", "you're cool", "we can be good friends", "cool", "nice"]
dislike = ["I don't like you \U0001F641", "that's not nice", "please moderate your language", "have some respect!"]
bad_Lang = ["fuck you", "fuck", "shit", "cunt", "dumbass", "fucking idiot", "stupid bot", "stupid luna", "bitch"]
userFeeling = ["do you like me?", "are we friends?", "you're my friend", "love you", "I love you"]
#RandomStuff
someWords = ["ok", "okay", "oki doki", "alright"]
#Jokes
jokes = ["Let me tell you a joke:\nWhat did 0 say to 8? Nice belt!"]
entWords = ["something funny", "tell me something funny", "entertain me", "funny facts", "funny", "joke of the day"]
funny =["Was the joke funny?", "Did you like the joke"]
fFacts = ["funny fact", "fact", "tell me a fact", "fact of the day"]
fFactResp = ['"Snakes can help predict earthquakes.\nThey can sense a coming earthquake from 75 miles away (121 km), up to five days before it happens.\nCheck out more facts at: https://www.thefactsite.com/2011/07/top-100-random-funny-facts.html" ' , '"Bananas are curved because they grow towards the sun.\nCheck out more facts at: https://www.thefactsite.com/2011/07/top-100-random-funny-facts.html"']
#YES / No
yes = ["yes", "ye", "sure", "yap", "Yes"]
no = ["no", "nope", "No"]
#Movie Recomendations from the bot
movie = ["I suggest you watching the Incredibles 2.", "I suggest you watching Mission: Impossible – Fallout.", "I suggest you watching Jurassic World: Fallen Kingdom."]
mquestion = ["movie", "movies", "tell me about movies"]
#Music
musUser = ["tell me a song", "recommend me music", "do you like music?", "do you listen to music?"]
mscBot = ["I love BTS - Idol.\nHere is the video of the song https://youtu.be/pBuZEGYXA6E", "I love TWICE - TT.\nHere is the video of the song https://youtu.be/ePpPVE-GGJw"]
#Normal Questions and responses
questions = ["How are you?", "How are you doing?", "How is it going?", "What are you up to?", "how are you", "how are you?"]
response = ["I'm fine", "Good, what about you?", "good", "I am good \U0001F604", "I am fine \U0001F63D", "I'm okay"]
#Emotions from the user
goodEM = ["I am fine", "I am great", "I am okay", "I'm good", "I'm okay", "I'm cool", "I'm super good", "good"]
badEM = ["I am bad", "I am sad", "I am depressed", "I am not well", "I am annoyed", "I am angry", "I'm bad", "I'm sad","I feel sad", "sad"]
goodMood = ["I am happy that you're fine", "I am happy for you", "That'a lovely!", "That's amazing"]
badMood = ["I'm sad to hear that", "I'm sorry for you", "Don't worry, be happy!", "Think positive"]
# Cities for the weather requests
cities = ["London", "Coventry", "Lisbon", "Seoul"]
help = str("Hello, the /help command gives you basic instructions on how to use LunaWei. \U0001F4D6\n /start - start the bot\n /weather - give information about the weather \n /calculator - solve simple math calculations\n /joke - tell you a joke\n /fact tell you a fact\n /music - some of my favourite songs! \U0001F60B \n /inline - List of all the amazing inline bots " )
# Lambda functions to parse updates from telegram
def getText(update):
return update["message"]["text"]
def getLocation(update):
return update["message"]["location"]
def getChatId(update):
return update["message"]["chat"]["id"]
def getUpId(update):
return int(update["update_id"])
def getResult(updates):
return updates["result"]
# Lambda functions to parse weather responses, [0] refers to the position of value saved in the list
def getDesc(w):
return w["weather"][0]["description"]
def getTemp(w):
return w["main"]["temp"]
def getCity(w):
return w["name"]
logger = logging.getLogger("LunaBot")
logger.setLevel(logging.DEBUG)
# Configure file and console logging
def configLogging():
# Create file logger and set level to DEBUG
# Mode = write -> clear existing log file
handler = logging.FileHandler("run.log", mode="w")
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
#create console handler and set level to INFO
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
formatter = logging.Formatter("[%(levelname)s] - %(message)s")
ch.setFormatter(formatter)
logger.addHandler(ch)
# settings from configuration file
def parseConfig():
global URL, URL_OWM, POLLING_TIMEOUT
c = configparser.ConfigParser()
c.read("config.ini")
lunatoken = c.get("Settings", "lunatoken")
URL = "https://api.telegram.org/bot{}/".format(lunatoken)
OWM_KEY = c.get("Settings", "OWM_KEY")
URL_OWM = "http://api.openweathermap.org/data/2.5/weather?appid={}&units=metric".format(OWM_KEY)
POLLING_TIMEOUT = c.get("Settings", "POLLING_TIMEOUT")
# make a request to telegram bot and get JSON response
def recieve_url(url):
logger.debug("URL: %s" % url)
response = requests.get(url)
jResp = json.loads(response.content.decode("utf8")) #parses it into a dictionary | turns encoded data into Python objects
return jResp
# retrieve a list of updates to lunabot
def get_UPD(offset=None):
url = URL + "getUpdates?timeout=%s" % POLLING_TIMEOUT
logger.info("Getting updates")
if offset:
url += "&offset={}".format(offset)
js = recieve_url(url)
return js
# keyboard for cities
def CITY_KeyBoard():
keyboard = [[{"text": c}] for c in cities]
keyboard.append([{"text": "Share location", "request_location": True}])
replyKeyboard = {"keyboard": keyboard, "one_time_keyboard": True}
logger.debug(replyKeyboard)
return json.dumps(replyKeyboard)
# query OWM for the weather for place or coords [share location] |
def getWeather(place):
if isinstance(place, dict): # coordinates are provided
lat, lon = place["latitude"], place["longitude"]
url = URL_OWM + "&lat=%f&lon=%f&cnt=1" % (lat, lon)
logger.info("Requesting weather: " + url)
js = recieve_url(url)
logger.debug(js)
return u"%s \N{DEGREE SIGN}C, %s in %s" % (getTemp(js), getDesc(js), getCity(js))
else: # one of the options / city name
# make req
url = URL_OWM + "&q={}".format(place)
logger.info("Requesting weather: " + url)
js = recieve_url(url)
logger.debug(js)
return u"%s \N{DEGREE SIGN}C, %s in %s" % (getTemp(js), getDesc(js), getCity(js))
# send URL-encoded message to chat id
def luna_message(text, chatId, interface=None):
text = text.encode('utf-8', 'strict')
text = urllib.parse.quote_plus(text)
url = URL + "sendMessage?text={}&chat_id={}&parse_mode=Markdown".format(text, chatId)
if interface:
url += "&reply_markup={}".format(interface)
requests.get(url)
# get the last id and returns the highest ID
def getLastUpdateId(updates):
ids = []
for update in getResult(updates):
ids.append(getUpId(update))
return max(ids)
# keep track of conversation states , save data
chats = {}
# get the text and chat id to check msg received and later on send a response
def handleUpdates(updates):
for update in getResult(updates):
chatId = getChatId(update)
try:
text = getText(update)
except Exception as e:
logger.error("No text field in update. Try to get location")
loc = getLocation(update)
# if was weather previously requested
if (chatId in chats) and (chats[chatId] == "weatherReq"):
logger.info("Weather requested for %s in chat id %d" % (str(loc), chatId))
# Send weather to chat id and clear state
luna_message(getWeather(loc), chatId)
del chats[chatId]
continue
if text == "/weather":
keyboard = CITY_KeyBoard()
chats[chatId] = "weatherReq"
luna_message("Please select a city \U0001F5FA", chatId, keyboard)
elif text == "/start":
luna_message("Hey there! I'm LunaWei and I'm still in development, so please be patient! \U0001F638", chatId)
elif text == "/help":
luna_message(help, chatId )
elif text == "/joke":
luna_message(str(random.choice(jokes)), chatId)
luna_message(str(random.choice(funny)), chatId)
elif text == "/fact":
luna_message(str(random.choice(fFactResp)), chatId)
elif text == "/music":
luna_message(str(random.choice(mscBot)), chatId)
elif text == "/calculator":
luna_message(str("Coming soon \U0001F51C"), chatId)
elif text == "/news":
luna_message(str(random.choice(news)), chatId)
elif text == "/inline":
luna_message(inline_bot , chatId)
elif text.lower() in greetings:
luna_message(str(random.choice(greetings)), chatId)
elif text.lower() in questions:
luna_message(str(random.choice(response)), chatId)
elif text.lower() in mquestion:
luna_message(str(random.choice(movie)), chatId)
elif text.lower() in goodEM:
luna_message(str(random.choice(goodMood)), chatId)
elif text.lower() in badEM:
luna_message(str(random.choice(badMood)), chatId)
elif text.lower() in bye:
luna_message(str(random.choice(bye)), chatId)
elif text.lower() in compliment:
luna_message(str(random.choice(thanks)), chatId)
elif text.lower() in thanks:
luna_message(str(random.choice(welcome)), chatId)
elif text.lower() in welcome:
luna_message(str(random.choice(welcome_RESP)), chatId)
elif text.lower() in bad_Lang:
luna_message(str(random.choice(dislike)), chatId)
elif text.lower() in userFeeling:
luna_message(random.choice(like), chatId)
elif text.lower() in someWords:
luna_message(str(random.choice(someWords)), chatId)
elif text.lower() in musUser:
luna_message(str(random.choice(mscBot)), chatId)
elif text.lower() in entWords:
luna_message(str(random.choice(jokes)), chatId)
elif text.lower() in yes:
luna_message(str(random.choice(someWords)), chatId)
elif text.lower() in no:
luna_message(str(random.choice(someWords)), chatId)
elif text.lower() in fFacts:
luna_message(str(random.choice(fFactResp)), chatId)
elif text.startswith("/"):
logger.warning("Invalid command %s" % text)
continue
elif (text in cities) and (chatId in chats) and (chats[chatId] == "weatherReq"):
logger.info("Weather requested for %s" % text)
#send weather to chat id
luna_message(getWeather(text), chatId)
del chats[chatId]
else:
luna_message("Hey noob! Please use the /help \U0001F4D6 command.", chatId)
def main():
# set up file and console loggers
configLogging()
# get tokens and keys from settings file
parseConfig()
# Main loop
last_update_id = None
while True:
updates = get_UPD(last_update_id)
if len(getResult(updates)) > 0:
last_update_id = getLastUpdateId(updates) + 1
handleUpdates(updates)
time.sleep(0.5)
if __name__ == "__main__":
main()