This commit is contained in:
Florian Kellermann 2022-04-26 16:32:55 +02:00
commit 81200e0c52
13 changed files with 2341 additions and 497 deletions

View File

@ -39,24 +39,7 @@ pipeline:
from_secret: password from_secret: password
registry: registry:
from_secret: registry from_secret: registry
dockerfile: telegram_bot/Dockerfile.bot dockerfile: telegram_bot/Dockerfile
platforms: linux/amd64
when:
path: "telegram_bot/**"
event: push
build_bot_updates:
image: woodpeckerci/plugin-docker-buildx
settings:
repo:
from_secret: repo_bot_updates
username:
from_secret: username
password:
from_secret: password
registry:
from_secret: registry
dockerfile: telegram_bot/Dockerfile.updates
platforms: linux/amd64 platforms: linux/amd64
when: when:
path: "telegram_bot/**" path: "telegram_bot/**"

View File

@ -1,3 +1,6 @@
BOT_API_KEY= BOT_API_KEY=
NEWS_API_KEY= NEWS_API_KEY=
SECRET_KEY= SECRET_KEY=
BOT_EMAIL=
BOT_PASSWORD=

View File

@ -30,11 +30,6 @@ services:
env_file: env_file:
- ${PWD}/.env.bot - ${PWD}/.env.bot
aktienbot_bot_updates:
image: registry.flokaiser.com/aktienbot/bot_updates
env_file:
- ${PWD}/.env.bot
mariadb: mariadb:
image: mariadb image: mariadb
volumes: volumes:

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -10,5 +10,8 @@ RUN pip install -r requirements.txt --src /usr/local/src --no-warn-script-locati
# Copy the source code to the working directory # Copy the source code to the working directory
COPY telegram_bot /srv/flask_app COPY telegram_bot /srv/flask_app
# Run the application # Change file permissions
CMD ["/usr/local/bin/python", "bot.py"] RUN chmod +x ./deploy/start.sh
# Run the app
CMD ["./deploy/start.sh"]

View File

@ -1,14 +0,0 @@
FROM python:3.10-slim
# Change the working directory to the root of the project
WORKDIR /srv/flask_app
# Install the dependencies
COPY telegram_bot/requirements.txt /srv/flask_app/
RUN pip install -r requirements.txt --src /usr/local/src --no-warn-script-location
# Copy the source code to the working directory
COPY telegram_bot /srv/flask_app
# Run the application
CMD ["/usr/local/bin/python", "bot_updates.py"]

View File

@ -2,8 +2,8 @@
script for communicating with webservice to get data from database script for communicating with webservice to get data from database
""" """
__author__ = "Florian Kellermann, Linus Eickhoff" __author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "16.03.2022" __date__ = "26.04.2022"
__version__ = "0.0.1" __version__ = "1.0.1"
__license__ = "None" __license__ = "None"
#side-dependencies: none #side-dependencies: none
@ -13,6 +13,9 @@ import sys
import os import os
import requests as r import requests as r
from croniter import croniter # used for checking cron formatting from croniter import croniter # used for checking cron formatting
from dotenv import load_dotenv
load_dotenv() # loads environment vars
# note: for more information about the api visit swagger documentation on https://gruppe1.testsites.info/api/docs#/ # note: for more information about the api visit swagger documentation on https://gruppe1.testsites.info/api/docs#/
@ -287,6 +290,7 @@ class API_Handler:
int: status code int: status code
""" """
with r.Session() as s: with r.Session() as s:
time = time[:-3] + "Z" # remove last character and add Z to make it a valid date for db
headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)} headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)}
transaction = {"comment": str(comment), "count": float(count), "isin": str(isin), "price": float(price), "time": str(time)} # set transaction as JSON with all the attributes needed according to Swagger docs transaction = {"comment": str(comment), "count": float(count), "isin": str(isin), "price": float(price), "time": str(time)} # set transaction as JSON with all the attributes needed according to Swagger docs
req = s.post(self.db_adress + "/transaction", json=transaction, headers=headers) req = s.post(self.db_adress + "/transaction", json=transaction, headers=headers)
@ -340,21 +344,21 @@ class API_Handler:
Args: Args:
email (string): email of the user email (string): email of the user
is_admin (String): "true" if user should be Admin, "false" if not is_admin (bool): "true" if user should be Admin, "false" if not
Returns: Returns:
int: status code int: status code
""" """
with r.Session() as s: with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token} # only bot token is needed, user is chosen by email headers = {'Authorization': 'Bearer ' + self.token} # only bot token is needed, user is chosen by email
req = s.put(self.db_adress + "/user/setAdmin", json={"admin": str(is_admin),"email": str(email)}) req = s.put(self.db_adress + "/user/setAdmin", json={"admin": is_admin,"email": str(email)}, headers=headers)
return req.status_code return req.status_code
if __name__ == "__main__": # editable, just for basic on the go testing of new functions if __name__ == "__main__": # editable, just for basic on the go testing of new functions
print("This is a module for the telegram bot. It is not intended to be run directly.") print("This is a module for the telegram bot. It is not intended to be run directly.")
handler = API_Handler("https://gruppe1.testsites.info/api", "bot@example.com", "bot") handler = API_Handler("https://gruppe1.testsites.info/api", str(os.getenv("BOT_EMAIL")), str(os.getenv("BOT_PASSWORD"))) # get creds from env
print(handler.token) print(handler.token)
keywords = handler.get_user_keywords(user_id = 1709356058) #user_id here is currently mine (Linus) keywords = handler.get_user_keywords(user_id = 1709356058) #user_id here is currently mine (Linus)
print(keywords) print(keywords)

View File

@ -3,8 +3,8 @@
script for telegram bot and its functions script for telegram bot and its functions
""" """
__author__ = "Florian Kellermann, Linus Eickhoff" __author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "11.03.2022" __date__ = "26.04.2022"
__version__ = "0.0.4" __version__ = "1.2.2"
__license__ = "None" __license__ = "None"
# side-dependencies: none # side-dependencies: none
@ -14,13 +14,11 @@ __license__ = "None"
# API Documentation https://core.telegram.org/bots/api # API Documentation https://core.telegram.org/bots/api
# Code examples https://github.com/eternnoir/pyTelegramBotAPI#getting-started # Code examples https://github.com/eternnoir/pyTelegramBotAPI#getting-started
import email
import os import os
import telebot import telebot
import sys import sys
import logging import logging
import json
import re import re
import news.news_fetcher as news import news.news_fetcher as news
@ -118,7 +116,7 @@ def send_all_users(message):
bot.send_message(chat_id=user_id, text=f'Username: {username}\nEmail: {email}\nID: {id}\nCron: {cron}\nAdmin: {admin}') # format user data into readable message text bot.send_message(chat_id=user_id, text=f'Username: {username}\nEmail: {email}\nID: {id}\nCron: {cron}\nAdmin: {admin}') # format user data into readable message text
@bot.message_handler(commands=['setAdmin', 'SetAdmin']) # set admin rights to user TBD: not working!! @bot.message_handler(commands=['setAdmin', 'SetAdmin', 'setadmin', 'Setadmin']) # set admin rights to user TBD: not working!!
def set_admin(message): def set_admin(message):
""" Set admin rights to user """ Set admin rights to user
@ -136,7 +134,7 @@ def set_admin(message):
bot.reply_to(message, "You have to be an admin to use this command") bot.reply_to(message, "You have to be an admin to use this command")
return return
bot.send_message(chat_id=user_id, text='send email and "true" if this account should have admin rights, else "false"\n in format: <email>,<is_admin>') # ask for email and admin rights to set bot.send_message(chat_id=user_id, text='send email and true if this account should have admin rights, else false\n in format: <email>,<is_admin>') # request email and admin rights to change to
bot.register_next_step_handler(message, set_admin_step) bot.register_next_step_handler(message, set_admin_step)
def set_admin_step(message): def set_admin_step(message):
@ -149,7 +147,11 @@ def set_admin_step(message):
return return
email = args_message[0] email = args_message[0]
is_admin = args_message[1] is_admin = False # default: False
if args_message[1].lower() == "true": # if user types true, set is_admin to true
is_admin = True
status = api_handler.set_admin(email, is_admin) # set admin in db status = api_handler.set_admin(email, is_admin) # set admin in db
if(status == 200): if(status == 200):
@ -278,7 +280,7 @@ def send_share_update(message):
def send_share_price(message): def send_share_price(message):
str_share_price = share_fetcher.get_share_price(str(message.text)) str_share_price = share_fetcher.get_share_price(str(message.text))
bot.reply_to(message, str_share_price) bot.reply_to(message, str_share_price) # add dollar symbol etc.
@bot.message_handler(commands=['allnews', 'Allnews']) # /allnews -> get all news @bot.message_handler(commands=['allnews', 'Allnews']) # /allnews -> get all news
@ -479,8 +481,8 @@ def set_new_transaction_step(message):
amount = float(transaction_data[2]) amount = float(transaction_data[2])
price = float(transaction_data[3]) price = float(transaction_data[3])
time = dt.datetime.now().isoformat() time = dt.datetime.now().isoformat()
#print("\n\n\n\n\n") print("\n\n\n\n\n")
#print(f"{symbol},{amount},{price},{time}") print(f"{isin},{amount},{price},{time}")
status = api_handler.set_transaction(user_id, desc, isin, amount, price, time) status = api_handler.set_transaction(user_id, desc, isin, amount, price, time)
if status == 200: if status == 200:

View File

@ -2,21 +2,16 @@
script for regularly sending updates on shares and news based on user interval script for regularly sending updates on shares and news based on user interval
""" """
__author__ = "Florian Kellermann, Linus Eickhoff" __author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "05.04.2022" __date__ = "26.04.2022"
__version__ = "1.0.1" __version__ = "1.0.2"
__license__ = "None" __license__ = "None"
from calendar import month
from symtable import Symbol
from dotenv import load_dotenv from dotenv import load_dotenv
from shares.share_fetcher import get_share_price
import news.news_fetcher as news_fetcher import news.news_fetcher as news_fetcher
import time import time
import datetime
import os import os
from bot import bot from bot import bot
import sys import sys
from multiprocessing import Process
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from api_handling.api_handler import API_Handler from api_handling.api_handler import API_Handler
@ -153,9 +148,16 @@ def update_for_user(p_user_id, p_my_handler):
if(keywords): # if keywords exist and array is not empty if(keywords): # if keywords exist and array is not empty
send_to_user("If you haven't read yet: \nHere are some interesting news according to your keywords:", pUser_id=p_user_id) send_to_user("If you haven't read yet: \nHere are some interesting news according to your keywords:", pUser_id=p_user_id)
for keyword in keywords: for keyword in keywords:
news = news_fetcher.get_top_news_by_keyword(keyword)["articles"][0] # only use the most popular news news = news_fetcher.get_top_news_by_keyword(keyword)["articles"]
news_formatted = news_fetcher.format_article(news) # format for message
send_to_user(f"_keyword: {keyword}_\n\n{news_formatted}", pUser_id=p_user_id, md_mode=True) # send news with related keyword in Markdown if not news: # if empty news array
send_to_user(f"No news found for keyword _{keyword}_.", pUser_id=p_user_id, md_mode=True)
if news == None: # if news is none
send_to_user(f"Server error for keyword _{keyword}_.", pUser_id=p_user_id, md_mode=True)
else:
news_formatted = news_fetcher.format_article(news[0]) # format for message, only use the most popular article
send_to_user(f"_keyword: {keyword}_\n\n{news_formatted}", pUser_id=p_user_id, md_mode=True) # send news with related keyword in Markdown

View File

@ -1,3 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
python bot.py python bot.py &
python bot_updates.py

View File

@ -2,15 +2,13 @@
script for news fetching (by keywords) script for news fetching (by keywords)
""" """
__author__ = "Florian Kellermann, Linus Eickhoff" __author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "15.03.2022" __date__ = "26.04.2022"
__version__ = "0.0.1" __version__ = "1.0.0"
__license__ = "None" __license__ = "None"
import sys import sys
import os import os
import json
import requests import requests
import datetime as dt
from newsapi import NewsApiClient from newsapi import NewsApiClient
from dotenv import load_dotenv from dotenv import load_dotenv

View File

@ -7,7 +7,6 @@ __version__ = "0.0.2"
__license__ = "None" __license__ = "None"
import yfinance import yfinance
import json
def get_share_price(str_symbol): def get_share_price(str_symbol):