Skip to content

Commit a34a7d6

Browse files
committed
v2.1.0
1 parent 9230955 commit a34a7d6

File tree

8 files changed

+95
-40
lines changed

8 files changed

+95
-40
lines changed

README.md

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,18 @@ pip install -r requirements.txt
3737
* Retrieve your firebase database url
3838
* Set up telegram bot via [BotFather](https://t.me/BotFather)
3939
* Insert all of them into .env as follows, you can use py dotenv or set it as env variable in your venv
40+
* You can use the same TOKEN for BOT_TOKEN & TEST_TOKEN but I recommend using two different bots for testing and production
41+
4042
``` .env
4143
BOT_TOKEN=your_bot_token
44+
TEST_TOKEN=your_test_token
4245
DATABASE_URL=firebase_url
4346
GOOGLE_API_EMAIL=google_api_email
4447
FIREBASE_JSON=service_account_key
4548
GOOGLE_JSON=service_account_key
4649
```
4750

4851
### Step 3
49-
* Run ngrok
50-
``` terminal
51-
ngrok http 5000
52-
```
53-
* Copy the link, it should look something like this 'https://<address>.ap.ngrok.io'
54-
* Set up web hook by opening this link:
55-
``` url
56-
https://api.telegram.org/bot<bot_token>/setwebhook?url=https://<address>.ap.ngrok.io/webhook
57-
```
58-
* You should see this:
59-
``` json
60-
{"ok":true,"result":true,"description":"Webhook was set"}
61-
```
6252
* Proceed to project directory and run:
6353
``` python
6454
python3.9 test.py
@@ -77,7 +67,9 @@ python3.9 test.py
7767

7868
/addincome - Add Income Entry
7969

80-
/retrievetransaction - Retrieve transaction from dates
70+
/getdaytransaction - Retrieve transaction from dates
71+
72+
/getoverall - Retrieve overall transaction for a month
8173

8274
/cancel - Cancel Conversation
8375

@@ -101,4 +93,4 @@ Bruce Wang: [email protected]
10193

10294
LinkedIn: [https://www.linkedin.com/in/brucewzj/](https://www.linkedin.com/in/brucewzj/)
10395

104-
Project Link: [https://github.com/brucewzj99/tele-tracker](https://github.com/brucewzj99/tele-tracker)
96+
Project Link: [https://github.com/brucewzj99/tele-tracker-v2](https://github.com/brucewzj99/tele-tracker-v2)

bot/common.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ class ConversationState(Enum):
2626
CONFIG_SUBCATEGORY,
2727
CONFIG_PAYMENT,
2828
CONFIG_SUBPAYMENT,
29-
HANDLE_RETRIEVE_TRANSACTION,
29+
HANDLE_GET_TRANSACTION,
30+
HANDLE_GET_OVERALL,
3031
INCOME,
3132
WORK_PLACE,
3233
CPF,
33-
) = range(22)
34+
) = range(23)

bot/google_sheet.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
payment_main_range = "Dropdown!A12:J12"
2323
quick_others_range = "Tracker!I3:J13"
2424
income_range = "Dropdown!L2:L9"
25+
overall_range = "!M13:O25"
2526

2627

2728
def get_main_dropdown_value(sheet_id, entry_type):
@@ -266,7 +267,7 @@ def get_quick_add_others(sheet_id):
266267
return others_list
267268

268269

269-
def retrieve_transaction(sheet_id, month, date):
270+
def get_day_transaction(sheet_id, month, date):
270271
result = (
271272
sheets_api.spreadsheets()
272273
.values()
@@ -353,3 +354,12 @@ def update_income(sheet_id, month, row_data):
353354
body=body_r,
354355
).execute()
355356
return True
357+
358+
def get_overall(sheet_id, month):
359+
result = (
360+
sheets_api.spreadsheets()
361+
.values()
362+
.get(spreadsheetId=sheet_id, range=f"{month}{overall_range}")
363+
.execute()
364+
)
365+
return result.get("values", [])

bot/telegram_bot.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ def check_date_format(date_string):
3737
pattern = r"\b\d{1,2}\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b"
3838
return bool(re.fullmatch(pattern, date_string, re.IGNORECASE))
3939

40+
def check_month_format(month_string):
41+
pattern = r"^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)$"
42+
return bool(re.fullmatch(pattern, month_string, re.IGNORECASE))
43+
4044

4145
def get_category_text(sheet_id, entry_type):
4246
msg = ""
@@ -608,26 +612,36 @@ def help(update, context):
608612
update.message.reply_text(HELP_TEXT)
609613

610614

611-
def retrieve_transaction(update, context):
615+
def get_day_transaction(update, context):
612616
context.user_data.clear()
613617
telegram_id = update.effective_user.id
614618
try:
615619
context.user_data["sheet_id"] = db.get_user_sheet_id(telegram_id)
616-
update.message.reply_text(RETRIEVE_TRANSACTION_TEXT)
617-
return CS.HANDLE_RETRIEVE_TRANSACTION
620+
update.message.reply_text(GET_TRANSACTION_TEXT)
621+
return CS.HANDLE_GET_TRANSACTION
618622
except Exception as e:
619623
update.message.reply_text(ERROR_TEXT)
620624
return ConversationHandler.END
621625

626+
def get_overall(update, context):
627+
context.user_data.clear()
628+
telegram_id = update.effective_user.id
629+
try:
630+
context.user_data["sheet_id"] = db.get_user_sheet_id(telegram_id)
631+
update.message.reply_text(GET_OVERALL_TEXT)
632+
return CS.HANDLE_GET_OVERALL
633+
except Exception as e:
634+
update.message.reply_text(ERROR_TEXT)
635+
return ConversationHandler.END
622636

623-
def handle_retrieve_transaction(update, context):
637+
def handle_get_transaction(update, context):
624638
sheet_id = context.user_data["sheet_id"]
625639
reply = update.message.text
626640
msg = ""
627641
try:
628642
if check_date_format(reply):
629643
day, month = reply.split(" ")
630-
total_spend, transport_values, other_values = gs.retrieve_transaction(
644+
total_spend, transport_values, other_values = gs.get_day_transaction(
631645
sheet_id, month, day
632646
)
633647
if not total_spend:
@@ -643,11 +657,32 @@ def handle_retrieve_transaction(update, context):
643657
update.message.reply_text(msg)
644658
return ConversationHandler.END
645659
else:
646-
update.message.reply_text(RETRIEVE_TRANSACTION_TEXT)
647-
return CS.HANDLE_RETRIEVE_TRANSACTION
660+
update.message.reply_text(GET_TRANSACTION_TEXT)
661+
return CS.HANDLE_GET_TRANSACTION
648662
except Exception as e:
649663
update.message.reply_text(ERROR_TEXT)
650664

665+
def handle_get_overall(update, context):
666+
sheet_id = context.user_data["sheet_id"]
667+
month = update.message.text
668+
msg = ""
669+
try:
670+
if check_month_format(month):
671+
values = gs.get_overall(sheet_id, month)
672+
msg = "```\n"
673+
for row in values:
674+
if len(row) == 3:
675+
msg += "{:<20} {:<10} {:<10}\n".format(*row)
676+
elif len(row) == 2:
677+
msg += "{:<20} {:<10}\n".format(*row)
678+
msg += "```"
679+
update.message.reply_text(msg, parse_mode='Markdown')
680+
return ConversationHandler.END
681+
else:
682+
update.message.reply_text(GET_OVERALL_TEXT)
683+
return CS.HANDLE_GET_OVERALL
684+
except Exception as e:
685+
update.message.reply_text(ERROR_TEXT)
651686

652687
def add_income(update, context):
653688
context.user_data.clear()
@@ -749,9 +784,12 @@ def setup_handlers(dispatcher):
749784
}
750785

751786
# Retrieve transaction-related states and handlers
752-
retrieve_transaction_states = {
753-
CS.HANDLE_RETRIEVE_TRANSACTION: [
754-
MessageHandler(Filters.text & ~Filters.command, handle_retrieve_transaction)
787+
get_transaction_states = {
788+
CS.HANDLE_GET_TRANSACTION: [
789+
MessageHandler(Filters.text & ~Filters.command, handle_get_transaction)
790+
],
791+
CS.HANDLE_GET_OVERALL: [
792+
MessageHandler(Filters.text & ~Filters.command, handle_get_overall)
755793
],
756794
}
757795

@@ -768,15 +806,16 @@ def setup_handlers(dispatcher):
768806
CommandHandler("addtransport", add_transport),
769807
CommandHandler("addothers", add_others),
770808
CommandHandler("addincome", add_income),
771-
CommandHandler("retrievetransaction", retrieve_transaction),
809+
CommandHandler("getdaytransaction", get_day_transaction),
810+
CommandHandler("getoverall", get_overall)
772811
],
773812
states={
774813
CS.SET_UP: [MessageHandler(Filters.text & ~Filters.command, set_up)],
775814
CS.RESET_UP: [CallbackQueryHandler(reset_up)],
776815
**config_states,
777816
**entry_states,
778817
**quick_add_states,
779-
**retrieve_transaction_states,
818+
**get_transaction_states,
780819
**add_income_states,
781820
},
782821
fallbacks=[CommandHandler("cancel", cancel)],

bot/text_str.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,18 @@
5252
+ "/addtransport - Quick Add Transport Entry\n"
5353
+ "/addothers - Quick Add Other Entry\n"
5454
+ "/addincome - Add Income Entry\n"
55-
+ "/retrievetransaction - Retrieve transaction from dates\n"
55+
+ "/getdaytransaction - Retrieve transaction from dates\n"
56+
+ "/getoverall - Retrieve overall transaction for a month\n"
5657
+ "/cancel - Cancel Conversation\n"
5758
+ "\nTo report bugs, please create a issue at https://github.com/brucewzj99/tele-tracker-v2/issues or contact me @bruceeew on Telegram"
5859
)
5960

60-
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"
61+
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"
62+
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"
6163

6264
ADD_INCOME_TEXT = "Add income\nPlease state your income followed by any remarks (optional): [income],[remarks]\ne.g. 2000, Something"
6365
ADD_INCOME_RETRY_TEXT = (
64-
"Please follow this format: [income],[remarks]\ne.g. 2000, Something"
66+
"Please follow this format:\n[income],[remarks]\ne.g. 2000, Something"
6567
)
6668
CHOOSE_INCOME_SOURCE_TEXT = "Please choose your income source"
6769
CPF_TEXT = "Is there CPF?"

release_notes.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,14 @@
4949

5050
## Version 2.0.2 - Date 1 Jun 2023
5151
### Bug Fix 🛠️
52-
- Day 1 sum creation bug
52+
- Day 1 sum creation bug
53+
54+
## Version 2.1.0 - Date 1 Jun 2023
55+
### New Features 🆕
56+
- Added get overall functions
57+
58+
### Enhancement 🔥
59+
- Rename retrievetransaction to getdaytransaction
60+
61+
### For Developer 🧑‍💻
62+
- When you run test.py, ngrok will auto setup with the correct webhook!

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ google-api-python-client==2.86.0
55
google-auth==2.17.3
66
google-auth-httplib2==0.1.0
77
pytz==2023.3
8-
firebase-admin==6.1.0
8+
firebase-admin==6.1.0
9+
pyngrok==6.0.0

test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@
33
from flask import Flask, request
44
import os
55
from bot.telegram_bot import setup_handlers
6+
from pyngrok import ngrok
67

78
TOKEN = os.environ.get("TEST_TOKEN")
89
app = Flask(__name__)
910
updater = Updater(token=TOKEN)
1011
dispatcher = updater.dispatcher
1112

12-
1313
@app.route("/webhook", methods=["POST"])
1414
def webhook():
1515
update = Update.de_json(request.get_json(), updater.bot)
1616
dispatcher.process_update(update)
1717
return "OK"
1818

19-
2019
@app.route("/")
2120
def index():
2221
return "Bot is running!"
2322

24-
25-
setup_handlers(dispatcher) # Call function to set up bot handlers
23+
setup_handlers(dispatcher)
2624

2725
if __name__ == "__main__":
28-
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))
26+
public_url = ngrok.connect(5000, "http").public_url
27+
updater.bot.set_webhook(url=f"{public_url}/webhook")
28+
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))

0 commit comments

Comments
 (0)