diff --git a/README.md b/README.md
index 50212f3..d50fda1 100644
--- a/README.md
+++ b/README.md
@@ -37,8 +37,11 @@ pip install -r requirements.txt
* Retrieve your firebase database url
* Set up telegram bot via [BotFather](https://t.me/BotFather)
* Insert all of them into .env as follows, you can use py dotenv or set it as env variable in your venv
+* You can use the same TOKEN for BOT_TOKEN & TEST_TOKEN but I recommend using two different bots for testing and production
+
``` .env
BOT_TOKEN=your_bot_token
+TEST_TOKEN=your_test_token
DATABASE_URL=firebase_url
GOOGLE_API_EMAIL=google_api_email
FIREBASE_JSON=service_account_key
@@ -46,19 +49,6 @@ GOOGLE_JSON=service_account_key
```
### Step 3
-* Run ngrok
-``` terminal
-ngrok http 5000
-```
-* Copy the link, it should look something like this 'https://
.ap.ngrok.io'
-* Set up web hook by opening this link:
-``` url
-https://api.telegram.org/bot/setwebhook?url=https://.ap.ngrok.io/webhook
-```
-* You should see this:
-``` json
-{"ok":true,"result":true,"description":"Webhook was set"}
-```
* Proceed to project directory and run:
``` python
python3.9 test.py
@@ -77,7 +67,9 @@ python3.9 test.py
/addincome - Add Income Entry
-/retrievetransaction - Retrieve transaction from dates
+/getdaytransaction - Retrieve transaction from dates
+
+/getoverall - Retrieve overall transaction for a month
/cancel - Cancel Conversation
@@ -101,4 +93,4 @@ Bruce Wang: hello@brucewzj.com
LinkedIn: [https://www.linkedin.com/in/brucewzj/](https://www.linkedin.com/in/brucewzj/)
-Project Link: [https://github.com/brucewzj99/tele-tracker](https://github.com/brucewzj99/tele-tracker)
+Project Link: [https://github.com/brucewzj99/tele-tracker-v2](https://github.com/brucewzj99/tele-tracker-v2)
diff --git a/bot/common.py b/bot/common.py
index 8df3b05..0b20b61 100644
--- a/bot/common.py
+++ b/bot/common.py
@@ -26,8 +26,9 @@ class ConversationState(Enum):
CONFIG_SUBCATEGORY,
CONFIG_PAYMENT,
CONFIG_SUBPAYMENT,
- HANDLE_RETRIEVE_TRANSACTION,
+ HANDLE_GET_TRANSACTION,
+ HANDLE_GET_OVERALL,
INCOME,
WORK_PLACE,
CPF,
- ) = range(22)
+ ) = range(23)
diff --git a/bot/google_sheet.py b/bot/google_sheet.py
index 16058cb..449a6b7 100644
--- a/bot/google_sheet.py
+++ b/bot/google_sheet.py
@@ -22,6 +22,7 @@
payment_main_range = "Dropdown!A12:J12"
quick_others_range = "Tracker!I3:J13"
income_range = "Dropdown!L2:L9"
+overall_range = "!M13:O25"
def get_main_dropdown_value(sheet_id, entry_type):
@@ -266,7 +267,7 @@ def get_quick_add_others(sheet_id):
return others_list
-def retrieve_transaction(sheet_id, month, date):
+def get_day_transaction(sheet_id, month, date):
result = (
sheets_api.spreadsheets()
.values()
@@ -353,3 +354,12 @@ def update_income(sheet_id, month, row_data):
body=body_r,
).execute()
return True
+
+def get_overall(sheet_id, month):
+ result = (
+ sheets_api.spreadsheets()
+ .values()
+ .get(spreadsheetId=sheet_id, range=f"{month}{overall_range}")
+ .execute()
+ )
+ return result.get("values", [])
\ No newline at end of file
diff --git a/bot/telegram_bot.py b/bot/telegram_bot.py
index ae45987..e7eca28 100644
--- a/bot/telegram_bot.py
+++ b/bot/telegram_bot.py
@@ -37,6 +37,10 @@ def check_date_format(date_string):
pattern = r"\b\d{1,2}\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b"
return bool(re.fullmatch(pattern, date_string, re.IGNORECASE))
+def check_month_format(month_string):
+ pattern = r"^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)$"
+ return bool(re.fullmatch(pattern, month_string, re.IGNORECASE))
+
def get_category_text(sheet_id, entry_type):
msg = ""
@@ -608,26 +612,36 @@ def help(update, context):
update.message.reply_text(HELP_TEXT)
-def retrieve_transaction(update, context):
+def get_day_transaction(update, context):
context.user_data.clear()
telegram_id = update.effective_user.id
try:
context.user_data["sheet_id"] = db.get_user_sheet_id(telegram_id)
- update.message.reply_text(RETRIEVE_TRANSACTION_TEXT)
- return CS.HANDLE_RETRIEVE_TRANSACTION
+ update.message.reply_text(GET_TRANSACTION_TEXT)
+ return CS.HANDLE_GET_TRANSACTION
except Exception as e:
update.message.reply_text(ERROR_TEXT)
return ConversationHandler.END
+def get_overall(update, context):
+ context.user_data.clear()
+ telegram_id = update.effective_user.id
+ try:
+ context.user_data["sheet_id"] = db.get_user_sheet_id(telegram_id)
+ update.message.reply_text(GET_OVERALL_TEXT)
+ return CS.HANDLE_GET_OVERALL
+ except Exception as e:
+ update.message.reply_text(ERROR_TEXT)
+ return ConversationHandler.END
-def handle_retrieve_transaction(update, context):
+def handle_get_transaction(update, context):
sheet_id = context.user_data["sheet_id"]
reply = update.message.text
msg = ""
try:
if check_date_format(reply):
day, month = reply.split(" ")
- total_spend, transport_values, other_values = gs.retrieve_transaction(
+ total_spend, transport_values, other_values = gs.get_day_transaction(
sheet_id, month, day
)
if not total_spend:
@@ -643,11 +657,32 @@ def handle_retrieve_transaction(update, context):
update.message.reply_text(msg)
return ConversationHandler.END
else:
- update.message.reply_text(RETRIEVE_TRANSACTION_TEXT)
- return CS.HANDLE_RETRIEVE_TRANSACTION
+ update.message.reply_text(GET_TRANSACTION_TEXT)
+ return CS.HANDLE_GET_TRANSACTION
except Exception as e:
update.message.reply_text(ERROR_TEXT)
+def handle_get_overall(update, context):
+ sheet_id = context.user_data["sheet_id"]
+ month = update.message.text
+ msg = ""
+ try:
+ if check_month_format(month):
+ values = gs.get_overall(sheet_id, month)
+ msg = "```\n"
+ for row in values:
+ if len(row) == 3:
+ msg += "{:<20} {:<10} {:<10}\n".format(*row)
+ elif len(row) == 2:
+ msg += "{:<20} {:<10}\n".format(*row)
+ msg += "```"
+ update.message.reply_text(msg, parse_mode='Markdown')
+ return ConversationHandler.END
+ else:
+ update.message.reply_text(GET_OVERALL_TEXT)
+ return CS.HANDLE_GET_OVERALL
+ except Exception as e:
+ update.message.reply_text(ERROR_TEXT)
def add_income(update, context):
context.user_data.clear()
@@ -749,9 +784,12 @@ def setup_handlers(dispatcher):
}
# Retrieve transaction-related states and handlers
- retrieve_transaction_states = {
- CS.HANDLE_RETRIEVE_TRANSACTION: [
- MessageHandler(Filters.text & ~Filters.command, handle_retrieve_transaction)
+ get_transaction_states = {
+ CS.HANDLE_GET_TRANSACTION: [
+ MessageHandler(Filters.text & ~Filters.command, handle_get_transaction)
+ ],
+ CS.HANDLE_GET_OVERALL: [
+ MessageHandler(Filters.text & ~Filters.command, handle_get_overall)
],
}
@@ -768,7 +806,8 @@ def setup_handlers(dispatcher):
CommandHandler("addtransport", add_transport),
CommandHandler("addothers", add_others),
CommandHandler("addincome", add_income),
- CommandHandler("retrievetransaction", retrieve_transaction),
+ CommandHandler("getdaytransaction", get_day_transaction),
+ CommandHandler("getoverall", get_overall)
],
states={
CS.SET_UP: [MessageHandler(Filters.text & ~Filters.command, set_up)],
@@ -776,7 +815,7 @@ def setup_handlers(dispatcher):
**config_states,
**entry_states,
**quick_add_states,
- **retrieve_transaction_states,
+ **get_transaction_states,
**add_income_states,
},
fallbacks=[CommandHandler("cancel", cancel)],
diff --git a/bot/text_str.py b/bot/text_str.py
index 6925e22..354e324 100644
--- a/bot/text_str.py
+++ b/bot/text_str.py
@@ -52,16 +52,18 @@
+ "/addtransport - Quick Add Transport Entry\n"
+ "/addothers - Quick Add Other Entry\n"
+ "/addincome - Add Income Entry\n"
- + "/retrievetransaction - Retrieve transaction from dates\n"
+ + "/getdaytransaction - Retrieve transaction from dates\n"
+ + "/getoverall - Retrieve overall transaction for a month\n"
+ "/cancel - Cancel Conversation\n"
+ "\nTo report bugs, please create a issue at https://github.com/brucewzj99/tele-tracker-v2/issues or contact me @bruceeew on Telegram"
)
-RETRIEVE_TRANSACTION_TEXT = "Please specify the date and month you wish to retrieve from in this format: DD MMM\ne.g 16 Mar\nor use /cancel to exit"
+GET_TRANSACTION_TEXT = "Please specify the date and month you wish to retrieve from in this format: DD MMM\ne.g 16 Mar\nor use /cancel to exit"
+GET_OVERALL_TEXT = "Please specify the month you wish to retrieve your overall transaction in this format: MMM\ne.g Mar\nor use /cancel to exit"
ADD_INCOME_TEXT = "Add income\nPlease state your income followed by any remarks (optional): [income],[remarks]\ne.g. 2000, Something"
ADD_INCOME_RETRY_TEXT = (
- "Please follow this format: [income],[remarks]\ne.g. 2000, Something"
+ "Please follow this format:\n[income],[remarks]\ne.g. 2000, Something"
)
CHOOSE_INCOME_SOURCE_TEXT = "Please choose your income source"
CPF_TEXT = "Is there CPF?"
diff --git a/release_notes.md b/release_notes.md
index ba3cbc0..4521888 100644
--- a/release_notes.md
+++ b/release_notes.md
@@ -49,4 +49,14 @@
## Version 2.0.2 - Date 1 Jun 2023
### Bug Fix 🛠️
-- Day 1 sum creation bug
\ No newline at end of file
+- Day 1 sum creation bug
+
+## Version 2.1.0 - Date 1 Jun 2023
+### New Features 🆕
+- Added get overall functions
+
+### Enhancement 🔥
+- Rename retrievetransaction to getdaytransaction
+
+### For Developer 🧑💻
+- When you run test.py, ngrok will auto setup with the correct webhook!
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 7562a9f..cebca6e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,4 +5,5 @@ google-api-python-client==2.86.0
google-auth==2.17.3
google-auth-httplib2==0.1.0
pytz==2023.3
-firebase-admin==6.1.0
\ No newline at end of file
+firebase-admin==6.1.0
+pyngrok==6.0.0
\ No newline at end of file
diff --git a/test.py b/test.py
index ca74594..df94bd2 100644
--- a/test.py
+++ b/test.py
@@ -3,26 +3,26 @@
from flask import Flask, request
import os
from bot.telegram_bot import setup_handlers
+from pyngrok import ngrok
TOKEN = os.environ.get("TEST_TOKEN")
app = Flask(__name__)
updater = Updater(token=TOKEN)
dispatcher = updater.dispatcher
-
@app.route("/webhook", methods=["POST"])
def webhook():
update = Update.de_json(request.get_json(), updater.bot)
dispatcher.process_update(update)
return "OK"
-
@app.route("/")
def index():
return "Bot is running!"
-
-setup_handlers(dispatcher) # Call function to set up bot handlers
+setup_handlers(dispatcher)
if __name__ == "__main__":
- app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))
+ public_url = ngrok.connect(5000, "http").public_url
+ updater.bot.set_webhook(url=f"{public_url}/webhook")
+ app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))
\ No newline at end of file