ASKY is an intelligent Telegram bot that leverages natural language processing to help users manage their daily tasks. Users simply describe their tasks in plain language, and the AI extracts, categorizes, and stores them automatically in Google Sheets — no forms, no clicks, just conversation.
- Overview
- Key Features
- Architecture
- Tech Stack
- Project Structure
- Getting Started
- Module Reference
- User Flow
- Data Schema
- Environment Variables
- Security Considerations
- Troubleshooting
- Future Roadmap
- License
ASKY bridges the gap between unstructured human language and structured task management. Instead of manually filling in task fields, users type naturally (e.g., "I need to submit the report by Friday and call the client tomorrow"), and the AI engine automatically:
- Extracts individual tasks from the message.
- Infers due dates and categories.
- Stores everything into a Google Sheets spreadsheet for persistent tracking.
- Reminds users of pending tasks every evening.
| Feature | Description |
|---|---|
| 🧠 AI-Powered Parsing | Uses Groq's Llama 3.3 70B model to extract up to 10 tasks from a single natural language message. |
| 📊 Google Sheets Backend | All tasks are stored in a Google Sheets spreadsheet — easy to view, share, and collaborate on. |
| ✅ Bulk Task Completion | Select and mark multiple tasks as done simultaneously through an interactive inline keyboard. |
| 🔔 Scheduled Reminders | Automatic daily reminder at 17:45 with a summary of active tasks. |
| 🎯 Category Detection | AI automatically categorizes each task (e.g., Work, Personal, Study). |
| 💬 Conversational UX | Minimal UI — interact entirely through Telegram chat with intuitive reply keyboards. |
┌─────────────────────────────────────────────────────────────────────┐
│ ASKY SYSTEM │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────────────────────┐ │
│ │ Telegram │◄──►│ ASKYBot │◄──►│ SheetsManager │ │
│ │ User │ │ (telegram.py)│ │ (sheets_manager.py) │ │
│ └──────────┘ └──────┬───────┘ └─────────────┬──────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ AIAgent │ │ Google Sheets │ │
│ │(ai_agent.py) │ │ (Cloud Store) │ │
│ └──────┬───────┘ └────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Groq API │ │
│ │ (Llama 3.3) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
| Component | File | Responsibility |
|---|---|---|
| Entry Point | main.py |
Bootstraps all services and starts the bot. |
| AI Engine | src/ai_agent.py |
Parses natural language into structured task JSON via Groq API. |
| Data Layer | src/sheets_manager.py |
CRUD operations on Google Sheets (save, read, update tasks). |
| Bot Interface | src/telegram.py |
Telegram command handlers, inline keyboards, and scheduled reminders. |
| Configuration | configs/.env |
Stores API keys and secrets. |
| Credentials | configs/creds.json |
Google Cloud service account credentials for Sheets API access. |
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Runtime | Python | 3.10+ | Core language |
| Bot Framework | pyTelegramBotAPI | 4.26.0 | Telegram Bot API wrapper |
| AI / LLM | Groq SDK | 0.15.0 | Interface to Llama 3.3 70B Versatile |
| Database | gspread | 6.1.4 | Google Sheets API client |
| Auth | google-auth | 2.37.0 | Google Cloud service account authentication |
| Config | python-dotenv | 1.0.1 | Environment variable management |
ASKY/
├── main.py # 🚀 Application entry point
├── requirements.txt # 📦 Python dependencies
├── .gitignore # 🔒 Git exclusion rules
├── ASKY.code-workspace # 🛠️ VS Code workspace config
├── DOCUMENTATION.md # 📘 This file
│
├── configs/ # ⚙️ Configuration & secrets
│ ├── .env # Environment variables (API keys, IDs)
│ └── creds.json # Google Cloud service account credentials
│
└── src/ # 📂 Source code package
├── __init__.py # Package initializer
├── ai_agent.py # 🧠 AI task parsing engine
├── sheets_manager.py # 📊 Google Sheets data operations
└── telegram.py # 💬 Telegram bot UI & logic
Before setting up ASKY, ensure you have:
- Python 3.10+ installed (download)
- A Telegram Bot Token — obtained from @BotFather on Telegram
- A Google Cloud Project with the Google Sheets API and Google Drive API enabled
- A Google Cloud Service Account with a downloaded
creds.jsonkey file - A Groq API Key — obtained from Groq Console
- A Google Spreadsheet shared with the service account email address
# 1. Clone the repository
git clone <your-repo-url>
cd ASKY
# 2. Create and activate a virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txtCreate a file at configs/.env with the following variables:
Warning
Do NOT commit this file to Git. It is already listed in .gitignore. Always double-check before pushing.
TELEGRAM_TOKEN=<your_telegram_bot_token>
SPREADSHEET_ID=<your_google_spreadsheet_id>
MY_CHAT_ID=<your_telegram_chat_id>
GROQ_API_KEY=<your_groq_api_key>Important
The SPREADSHEET_ID is the long alphanumeric string in your Google Sheets URL:
https://docs.google.com/spreadsheets/d/THIS_PART/edit
Tip
To find your MY_CHAT_ID, send a message to @userinfobot on Telegram.
- Go to Google Cloud Console → IAM & Admin → Service Accounts.
- Create a service account (or use an existing one).
- Generate a JSON key and save it as
configs/creds.json. - Share your Google Spreadsheet with the service account email (found in
creds.jsonunderclient_email).
python main.pyIf configured correctly, you should see:
[LOG] Notification scheduler active for ***...
[LOG] Bot ASKY active ...
The orchestrator that initializes all components and starts the bot.
# Simplified flow
SheetsManager() → AIAgent() → ASKYBot(ai, sm) → app.run()| Step | Action |
|---|---|
| 1 | Loads environment variables from configs/.env |
| 2 | Initializes SheetsManager (connects to Google Sheets) |
| 3 | Initializes AIAgent (configures Groq LLM client) |
| 4 | Initializes ASKYBot with both dependencies injected |
| 5 | Calls app.run() to start Telegram polling |
The intelligence layer that transforms free-form text into structured task objects.
| Method | Parameters | Returns | Description |
|---|---|---|---|
__init__() |
— | — | Initializes Groq client with llama-3.3-70b-versatile model and system prompt. |
parse(text) |
text: str |
list[dict] |
Sends user text to the LLM, returns up to 10 parsed task objects. |
The AI is instructed to:
- Extract up to 10 task items from the user's input.
- Return a JSON object with a
taskskey containing an array. - Each task has:
task(name),date(YYYY-MM-DD),category(auto-detected). - Default to today's date if no date is mentioned.
- Return pure JSON only — no additional text.
Input: "Submit the quarterly report by next Monday and schedule a team meeting"
Output: {
"tasks": [
{"task": "Submit the quarterly report", "date": "2026-02-23", "category": "Work"},
{"task": "Schedule a team meeting", "date": "2026-02-17", "category": "Work"}
]
}
Handles all persistent storage operations through the Google Sheets API.
| Method | Parameters | Returns | Description |
|---|---|---|---|
__init__() |
— | — | Authenticates with Google, opens the spreadsheet, and auto-creates headers if the sheet is empty. |
save_tasks(tasks) |
tasks: list[dict] |
dict | False |
Batch-appends multiple task rows to the spreadsheet. |
get_tasks(days) |
days: int = 30 |
list[dict] |
Retrieves all active (non-"Done") tasks within the specified day range. |
mark_done_bulk(task_names) |
task_names: list[str] |
bool |
Marks multiple tasks as "Done" by updating their Status column. |
On first run, SheetsManager checks if the spreadsheet is empty. If so, it automatically inserts the header row:
| Column A | Column B | Column C | Column D | Column E |
|---|---|---|---|---|
| Timestamp | Tanggal Tugas | Nama Tugas | Status | Category |
The presentation layer that manages all user interactions through the Telegram Bot API.
| Method | Parameters | Description |
|---|---|---|
__init__(ai, sm) |
ai: AIAgent, sm: SheetsManager |
Initializes bot, dependencies, user state stores, and starts the reminder scheduler. |
reminder_loop() |
— | Background thread that sends a daily task summary at 17:45. |
show_selection_menu(chat_id, tasks, message_id) |
chat_id: int, tasks: list, message_id: int | None |
Renders an interactive checklist of tasks with toggle buttons. |
run() |
— | Registers all command/message handlers and starts infinite polling. |
| Trigger | Type | Action |
|---|---|---|
/start |
Command | Displays the main reply keyboard with three options. |
/stop |
Command | Removes the keyboard and stops the bot for the user. |
➕ Tambah Tugas |
Button | Enters task-input mode; awaits free-form text. |
📋 Cek Tugas |
Button | Retrieves and displays the 10 nearest active tasks. |
✅ Selesaikan Tugas |
Button | Displays an interactive multi-select checklist. |
| Free-form text | Message | Parsed by AI when in task-input mode. |
save_task |
Callback | Saves AI-parsed tasks to Google Sheets. |
confirm_bulk |
Callback | Marks selected tasks as "Done" in Google Sheets. |
cancel_done / cancel_task |
Callback | Cancels the current operation. |
select_<name> |
Callback | Toggles task selection in the completion menu. |
The bot uses three in-memory dictionaries to track user state per session:
self.user_modes = {} # Tracks if user is in 'waiting_task' mode
self.temp_add = {} # Holds AI-parsed tasks pending confirmation
self.temp_done = {} # Holds selected tasks pending bulk completionNote
State is stored in-memory and will reset if the bot restarts. This is acceptable for a single-user or small-group bot.
User Bot AI Sheets
│ │ │ │
│ ➕ Tambah Tugas │ │ │
│ ──────────────────────────────► │ │ │
│ │ "Tugas apa yang ingin Anda │ │
│ ◄───────────────────────────── │ tambahkan hari ini?" │ │
│ │ │ │
│ "Submit report by Friday │ │ │
│ and call client tomorrow" │ │ │
│ ──────────────────────────────► │ ──── parse(text) ────────────► │ │
│ │ ◄── [{task, date, category}] ─ │ │
│ │ │ │
│ ◄── "Konfirmasi 2 Tugas Baru" │ │ │
│ [✅ Simpan] [❌ Batal] │ │ │
│ │ │ │
│ ✅ Simpan │ │ │
│ ──────────────────────────────► │ ─────── save_tasks() ─────────────────────────────► │
│ │ ◄──────────── OK ────────────────────────────────── │
│ ◄── "Berhasil disimpan!" │ │ │
User Bot Sheets
│ │ │
│ 📋 Cek Tugas │ │
│ ──────────────────────────────► │ ──── get_tasks(30) ────────────► │
│ │ ◄── [task1, task2, ...] ──────── │
│ ◄── "📋 Daftar 10 Tugas │ │
│ Terdekat: ..." │ │
User Bot Sheets
│ │ │
│ ✅ Selesaikan Tugas │ │
│ ──────────────────────────────► │ ──── get_tasks(30) ────────────► │
│ │ ◄── [task1, task2, ...] ──────── │
│ ◄── Interactive checklist │ │
│ [ ] Task A │ │
│ [ ] Task B │ │
│ [🚀 Konfirmasi] [❌ Batal] │ │
│ │ │
│ Tap Task A (toggle ✅) │ │
│ ──────────────────────────────► │ (menu refreshes with ✅ Task A) │
│ │ │
│ 🚀 Konfirmasi Selesai │ │
│ ──────────────────────────────► │ ── mark_done_bulk(["A"]) ──────►│
│ │ ◄──────── OK ────────────────── │
│ ◄── "1 Tugas berhasil │ │
│ diselesaikan!" │ │
Background Thread Bot User
│ │ │
│ (Clock hits 17:45) │ │
│ ──────────────────────────────► │ │
│ │ ── get_tasks(30)[:5] ──► │
│ │ ◄── [active tasks] ──── │
│ │ │
│ │ "🔔 Pengingat Sore (17:45): │
│ │ • Task A (2026-02-18) │
│ │ • Task B (2026-02-20)" │
│ │ ─────────────────────────────►│
| Column | Header | Type | Description | Example |
|---|---|---|---|---|
| A | Timestamp |
datetime |
When the task was added | 2026-02-17 20:30:00 |
| B | Tanggal Tugas |
date |
Task due date (YYYY-MM-DD) | 2026-02-20 |
| C | Nama Tugas |
string |
Task name/description | Submit quarterly report |
| D | Status |
enum |
Task status: Pending or Done |
Pending |
| E | Category |
string |
Auto-detected task category | Work |
| Variable | Required | Description | Example |
|---|---|---|---|
TELEGRAM_TOKEN |
✅ | Telegram Bot API token from @BotFather | (obtain from @BotFather) |
SPREADSHEET_ID |
✅ | Google Sheets document ID | (from your Sheets URL) |
MY_CHAT_ID |
✅ | Telegram chat ID for the daily reminder recipient | (from @userinfobot) |
GROQ_API_KEY |
✅ | Groq API key for accessing Llama 3.3 70B | (from console.groq.com) |
Caution
This project is designed for public GitHub hosting. Never commit sensitive files to version control. The .gitignore is pre-configured to exclude them. Always verify with git status before pushing.
Important
Before publishing to GitHub, ensure the following files are NOT tracked:
configs/.env— contains all API keys and tokensconfigs/creds.json— contains Google Cloud private key
| File | Status | Reason |
|---|---|---|
configs/.env |
🔒 Git-ignored | Contains API keys and tokens |
configs/creds.json |
🔒 Git-ignored | Google Cloud service account private key |
.venv/ |
🔒 Git-ignored | Virtual environment (large, not portable) |
__pycache__/ |
🔒 Git-ignored | Python bytecode cache |
- Rotate API keys periodically, especially if they are accidentally exposed.
- Restrict service account permissions to only the necessary Google Sheets and Drive scopes.
- Use
MY_CHAT_IDto limit reminder notifications to authorized users only. - Never hardcode secrets in source files — always use environment variables.
| Symptom | Probable Cause | Solution |
|---|---|---|
ModuleNotFoundError |
Virtual environment not activated or dependencies not installed | Run .venv\Scripts\activate then pip install -r requirements.txt |
CRITICAL_STOP: ... on startup |
Missing or invalid environment variables | Verify all values in configs/.env are correct |
| Bot doesn't respond to messages | Invalid TELEGRAM_TOKEN |
Regenerate the token via @BotFather and update .env |
Error in AIAgent: ... |
Groq API key invalid or rate limit exceeded | Verify GROQ_API_KEY in .env; check Groq status |
Error Sheets: ... |
Google Sheets API auth failure | Ensure creds.json is valid and the spreadsheet is shared with the service account |
BadRequest: Message is not modified |
Editing a message with identical content | Already handled in code — safe to ignore |
| Reminder not sending at 17:45 | MY_CHAT_ID not set or incorrect |
Update MY_CHAT_ID in .env with your Telegram chat ID |
| Tasks not appearing in Sheets | Spreadsheet not shared with service account | Share the spreadsheet with the client_email from creds.json |
| Priority | Feature | Description |
|---|---|---|
| 🔴 High | Multi-User Support | Persistent user state (database-backed) to handle concurrent users. |
| 🔴 High | Task Editing | Allow users to modify task names, dates, and categories after creation. |
| 🟡 Medium | Priority Levels | Add High / Medium / Low priority to tasks with color-coded indicators. |
| 🟡 Medium | Recurring Tasks | Support for daily, weekly, or monthly recurring tasks. |
| 🟢 Low | Timezone Support | Per-user timezone configuration for accurate reminders. |
| 🟢 Low | Analytics Dashboard | Weekly/monthly task completion statistics and productivity insights. |
| 🟢 Low | Multi-Language | Support for English and other languages alongside Indonesian. |
This project is private and intended for personal use. If you plan to open-source it, consider adding an MIT or Apache 2.0 license.
📘 Documentation generated on 2026-02-17 · Built with ❤️ by the ASKY team