{"id":42943662,"url":"https://github.com/sickmz/microw","last_synced_at":"2026-01-30T20:12:14.167Z","repository":{"id":239335002,"uuid":"798533964","full_name":"sickmz/microw","owner":"sickmz","description":"A telegram bot designed to track expenses.","archived":false,"fork":false,"pushed_at":"2024-06-11T19:04:29.000Z","size":40506,"stargazers_count":50,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-06-12T01:26:59.925Z","etag":null,"topics":["expense-manager","expense-tracker","google-sheets","python","python-telegram-bot","telegram"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sickmz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-10T01:11:11.000Z","updated_at":"2024-06-11T19:04:33.000Z","dependencies_parsed_at":"2024-06-11T20:27:14.407Z","dependency_job_id":null,"html_url":"https://github.com/sickmz/microw","commit_stats":null,"previous_names":["sickmz/microw"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sickmz/microw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sickmz%2Fmicrow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sickmz%2Fmicrow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sickmz%2Fmicrow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sickmz%2Fmicrow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sickmz","download_url":"https://codeload.github.com/sickmz/microw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sickmz%2Fmicrow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28918235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T19:10:10.838Z","status":"ssl_error","status_checked_at":"2026-01-30T19:06:40.573Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expense-manager","expense-tracker","google-sheets","python","python-telegram-bot","telegram"],"created_at":"2026-01-30T20:12:13.551Z","updated_at":"2026-01-30T20:12:14.157Z","avatar_url":"https://github.com/sickmz.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/sickmz/microw/assets/24682196/a46ceee3-ab8a-46bf-85e1-6b245bacbea2\" alt=\"daruma\" width=\"200\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"/LICENSE\"\u003e\n    \u003cimg alt=\"License: MIT\" src=\"https://cdn.prod.website-files.com/5e0f1144930a8bc8aace526c/65dd9eb5aaca434fac4f1c34_License-MIT-blue.svg\"/\u003e\u003c/a\u003e\u0026nbsp;\n  \u003ca href=\"https://t.me/sickmz\"\u003e\n    \u003cimg alt=\"Telegram\" src=\"https://img.shields.io/badge/Telegram-Chat%20with%20me-green\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Overview \n\nThis is a telegram bot that allows you to manage your finances on a local `.xlsx` file and add, delete, create an expense list, show charts and set budgets with alerts. In addition, you can synchronize it with Google Sheets.\n## ToC\n\n- [Demo](#demo)\n- [What's new](#whats-new)\n- [Next features](#next-features)\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Mermaid-based state diagram](#mermaid-based-state-diagram)\n- [(Optional) Run with Docker](#optional-run-with-docker)\n- [(Optional) Setting as Systemd service](#optional-setting-as-systemd-service)\n- [Contributing](#contributing)\n\n## Demo\n\n\u003cdiv align=\"center\"\u003e\n  \u003cvideo src=\"https://github.com/sickmz/microw/assets/24682196/5d313126-2309-4a17-9004-7fac3babe1cb\" width=\"400\" /\u003e\n\u003c/div\u003e\n\n## What's new\n- 📝 **Local `.xlsx` file management**: now by default all saved, deleted expenses, charts and lists are produced locally, under your control.\n- 🌐 **Sync with Google Sheet**: you can synchronize the last expenses you entered in your local `.xlsx` directly to Google Sheets.\n    - **Automatic sync**: a background task wakes up every few minutes (configurable) and sync new expenses (if there are any new ones) with your Google Sheets. You can enable or disable Google Sheets synchronization via the `⚙️ Settings` command.\n- All operations are now ***extremely faster*** because of the work being done locally. Google's API is very slow, so a batch synchronization of expenses is the best solution to ensure maximum responsiveness.\n- ⚙️To improve readability and maintenance, the code was split into modules.\n- 💰 Budgeting Feature: You can now set a budget for different expense categories and track your spending against these budgets.\n    - Receive notifications when your spending exceeds the set budget for any category. You can enable or disable budget notifications via the `⚙️ Settings` command.\n- Docker image\n- Mermaid-based state diagram\n\n## Next features\n- [x] ~~Initial decision screen between Google Sheets and *save data locally* in .csv format with ability to export and share (for those not planning to use gsheet)~~\n- [x] ~~Improve the speed of execution for the elimination of an expense~~\n- [x] ~~Simplify the code and make it more modular~~\n- [x] ~~Creation of budgets with alerts if exceeded~~\n- [x] ~~Docker image~~\n- [ ] Income management\n- [ ] Cash account\n- [ ] Investments\n\n## Features\n- `✏️ Add` expense with two dependent lists, category and subcategory.\n- `❌ Delete` expense with pagination to go back through older expenses.\n- `📊 Charts` of four types: yearly and monthly breakdowns, trends, and heatmaps.\n- `📋 List` to displays a summary of expenses for the current year.\n- `💰 Budget` set a budget for different expense categories.\n- `⚙️ Settings` show the system settings (currently Google Sheet sync and budget alerts).\n\n## Installation\n\n- Clone the repository:\n\n```\ngit clone https://github.com/sickmz/microw.git\ncd microw\n```\n\n- Create a virtual environment:\n\n```\npython3 -m venv venv\nsource venv/bin/activate\n```\n\n- Install the required packages:\n\n```\npip install -r requirements.txt\n```\n\n- Create a Google Service Account\n  - Go to the [Google Cloud Console](https://console.cloud.google.com/).\n  - Create a new project or select an existing one.\n  - Enable the Google Sheet Api for this project.\n  - Navigate to the \"APIs \u0026 Services\" \u003e \"Credentials\" section.\n  - Click \"Create credentials\" \u003e \"Service account\".\n  - Fill in the service account details and click \"Create\".\n  - Click \"Furnish a new private key\" \u003e \"JSON\" \u003e \"Create\". The JSON file will be downloaded automatically.\n  - Rename the downloaded file to credentials.json and place it in the root directory of the project.\n  - Share your spreadsheet with the email of Google Service Account.\n\n- Environments configurations: create a `.env` file in the root directory of the project with `touch .env`\n- Open the `.env` file in a text editor and add the following lines, replacing the placeholders with your actual values:\n\n```\nTELEGRAM_BOT_TOKEN=your_telegram_token_bot\nTELEGRAM_USER_ID=your_telegram_user_id\nREMOTE_SPREADSHEET_ID=your_remote_remote_spreadsheet_id\nREMOTE_EXPENSE_SHEET=your_remote_expense_sheet_name\n```\n\n\u003e [!WARNING]\n\u003e Make sure to add `.env` and `credentials.json` to your `.gitignore` file to prevent accidental commits.\n\n## Usage\n\n1. Start a conversation with the bot on telegram.\n2. Use the `/start` command to initiate interaction.\n3. Choose an action: `✏️ Add`, `❌ Delete`, `📊 Charts`, `📋 List`, `💰 Budget` or `⚙️ Settings`.\n4. Follow the bot's prompts.\n\n\u003e [!TIP]\n\u003e I recommend setting a `/cancel` command on BotFather to interrupt a workflow (e.g., stop entering an expense).\n\n## Mermaid-based state diagram\n\n\nTo see how this diagram is made you can look at [this](https://github.com/sickmz/microw/blob/main/microw.mmd?short_path=34ba1cf) file.\n\n```mermaid\nflowchart TB\n    A((\"start\")):::entryPoint --\u003e B(\"Authorize User\")\n    B --\u003e |\"Authorized\"| C((\"Show Main Menu\")):::state\n    B --\u003e |\"Not Authorized\"| End((\"END\")):::termination\n    \n    C --\u003e |\"✏️ Add\"| D(\"Select Category\"):::state\n    C --\u003e |\"❌ Delete\"| E(\"Check Expenses\"):::state\n    C --\u003e |\"📊 Charts\"| F(\"Select Chart Type\"):::state\n    C --\u003e |\"📋 List\"| G(\"Generate Expense List\"):::state\n    C --\u003e |\"💰 Budget\"| H(\"Select Budget Action\"):::state\n    C --\u003e |\"⚙️ Settings\"| I(\"Show Settings\"):::state\n\n    D --\u003e J((\"Select Subcategory\"))\n    J --\u003e K((\"Enter Price\"))\n    K --\u003e L((\"Save Expense\"))\n    L --\u003e C\n\n    E --\u003e |\"No expenses\"| O((\"No Expenses Message\"))\n    E --\u003e |\"Expenses exist\"| P((\"Show Paginated Expenses\"))\n    O --\u003e C\n    P --\u003e C\n\n    F --\u003e |\"Pie\"| Q((\"Generate Pie Chart\"))\n    F --\u003e |\"Histogram\"| R((\"Generate Histogram\"))\n    F --\u003e |\"Trend\"| S((\"Generate Trend Chart\"))\n    F --\u003e |\"Heatmap\"| T((\"Generate Heatmap\"))\n    Q --\u003e C\n    R --\u003e C\n    S --\u003e C\n    T --\u003e C\n\n    G --\u003e U((\"Generate Expense List\"))\n    U --\u003e C\n\n    H --\u003e |\"Set\"| V((\"Select Budget Category\"))\n    H --\u003e |\"Show\"| W((\"Show Budgets\"))\n    V --\u003e X((\"Enter Budget Amount\"))\n    W --\u003e C\n    X --\u003e C\n\n    I --\u003e Y((\"Show Settings\"))\n    Y --\u003e Z((\"Handle Settings Choice\"))\n    Z --\u003e C\n\n    subgraph Main\n        A1((\"cancel\")):::entryPoint\n        A1 --\u003e C\n    end\n    \n    style A fill:#00FF00,stroke:#000000,stroke-width:2px\n    style B fill:#726000,stroke:#000000,stroke-width:2px\n    style End fill:#FF0000,stroke:#000000,stroke-width:2px\n    classDef state fill:#88443f,stroke:#000000,stroke-width:1px\n    classDef entryPoint fill:#009c11, stroke:#42FF57, color:#ffffff\n    classDef termination fill:#bb0007, stroke:#E60109, color:#ffffff\n```\n\n## (Optional) Run with Docker\n\nThe command `docker compose up -d` will automatically build the docker image, just make sure to pass the `.env` file and `credentials.json` as volumes. In the repo I uploaded a sample of `docker-compose.yaml`. To install Docker look at [this](https://gist.github.com/sickmz/2fe45975a56adcdd3d9f67842064f796#file-docker-installation) gist.\n\n## (Optional) Setting as Systemd Service:\n\n1. Create a new systemd service file:\n\n```\nsudo nano /etc/systemd/system/microw.service\n```\n\n2. Copy the following content into the file:\n\n```\n[Unit]\nDescription=microw\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/home/$USER/code-server/workspace/microw/venv/bin/python3 main.py\nWorkingDirectory=/home/$USER/code-server/workspace/microw\n\n[Install]\nWantedBy=multi-user.target\n```\n\n3. Replace the `ExecStart` and `WorkingDirectory` paths with the actual paths to your script and project directory.\n\n4. Reload the systemd daemon, enable and start the service:\n\n```\nsudo systemctl daemon-reload\nsudo systemctl enable microw.service\nsudo systemctl start microw.service\n```\n\u003e [!NOTE]\n\u003e You can check the status of the service by typing `sudo systemctl status microw.service`\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsickmz%2Fmicrow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsickmz%2Fmicrow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsickmz%2Fmicrow/lists"}