gjoko-ai-agent

djokobozinov/gjoko-ai-agentView source, setup instructions & docs on GitHub

A self-hosted personal AI agent for small, useful automations across everyday tools. It can chat with you through Telegram, summarize Gmail, capture quick notes into Notion, send local weather clothing advice, create and report on Google Calendar events, and expose password-protected setup utilities. Each capability is optional and enabled independently with environment variables; there is no database.

Features

01

Telegram AI assistant

Message the bot and get OpenAI-powered replies in the same Telegram chat.

02

Notion note capture

Save *-prefixed Telegram messages to Notion, including automatic subpages with *<name>, <note>.

03

Reply-to-note capture

Reply to any Telegram message with * to save the replied message text into Notion.

04

Gmail summaries

Connect up to 5 Gmail accounts with read-only OAuth and summarize unread messages with OpenAI.

05

Telegram delivery

Receive Gmail summaries in Telegram, including category prefixes for social and promotions.

06

Daily weather report

Get 07:30 and 20:30 Europe/Ljubljana Vransko forecasts with clothing advice for adults and kids.

07

Daily calendar report

Get a 20:00 Europe/Ljubljana Telegram message with tomorrow's Google Calendar events, holidays, and birthdays.

08

Calendar event creation

Send Telegram messages like add event Dentist on 2026-05-21 at 14:30 to create Google Calendar events.

09

Cron automation

Run scheduled work every 30 minutes through Vercel Cron or any external cron caller.

10

Manual utilities

Password-protected pages for Telegram webhook setup, Telegram delivery tests, and manual mail checks.

11

Readiness checks

Setup/status UI shows which optional modules are enabled and which env vars are missing.

12

No database

Configuration is env-var driven, keeping deployment simple and portable.

The problem

Email fatigue is real. Inbox zero feels unreachable. Important messages get buried under newsletters, receipts, and promotions. On top of that, I kept losing quick thoughts I wanted to jot down — scattered across chat apps, drafts, and sticky notes. I wanted one place that could triage my inbox and capture my notes without extra tabs or apps.

How it works

The agent has three independent features, each enabled only when its required env vars are present:

1. Email Summaries

A cron job fetches unread Gmail messages via the Gmail API, sends them to OpenAI for summarization, and delivers the result to a Telegram chat. It processes inbox, social, and promotions — skipping spam and very short emails. Social emails get a 👥 prefix and promotions get 🏷️.

Requires: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REFRESH_TOKEN, OPENAI_API_KEY, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID

2. Telegram Assistant

When you send a text message to the bot, it calls OpenAI (default model: gpt-5-nano) and replies in the same chat. No context window management — just quick Q&A whenever you need it.

Requires: TELEGRAM_BOT_TOKEN, OPENAI_API_KEY

3. Notion Notes

Messages that start with * are saved to a Notion page instead of being sent to OpenAI. *note text appends to the root Notes page. *<name>, <note> appends to a subpage with that name, auto-created if it doesn't exist.

Requires: TELEGRAM_BOT_TOKEN, NOTION_API_KEY, NOTION_NOTES_PAGE_ID

What a summary looks like

For each unread email, the AI produces something like:

📧 Short title here
• Bullet 1: key fact
• Bullet 2: key fact
• Bullet 3: key fact (optional)

👥 Social email title
• Who interacted, what happened

🏷️ Promo email title
• Deal summary, deadline

Technical choices

  • No database — all configuration via environment variables
  • No globally required vars — each feature self-enables when its vars are present
  • Minimal UI — web pages only for OAuth setup, webhook config, and Telegram test
  • Serverless — Next.js API routes on Vercel
  • Stateless — designed for cron runs, not long-lived processes

Environment variables

VariableUsed by
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETGmail OAuth + email summaries
GOOGLE_REFRESH_TOKEN … _5Gmail accounts (up to 5)
OPENAI_API_KEYEmail summaries + Telegram assistant
OPENAI_MODELOptional model override (default gpt-5-nano)
TELEGRAM_BOT_TOKENAssistant, email delivery, webhook, test
TELEGRAM_CHAT_IDEmail delivery destination + /telegram-test
NOTION_API_KEY, NOTION_NOTES_PAGE_IDTelegram * notes → Notion
APP_URLGmail OAuth redirect + webhook setup
TEST_PASSWORDProtected utility pages
CRON_SECRETOptional bearer auth for external cron
TELEGRAM_WEBHOOK_SECRETOptional webhook header validation
MAX_EMAILS_PER_RUN, LABEL_FILTEROptional email-processing tweaks

Quick setup

Google Cloud (optional — email summaries only)

  1. Create a project in Google Cloud Console and enable the Gmail API
  2. Configure the OAuth consent screen (External, add your email as a test user)
  3. Create OAuth 2.0 credentials and add the redirect URI: https://your-domain.com/api/auth/gmail

Telegram Bot (optional — needed for Telegram features)

  1. Message @BotFather to create a bot; copy the token
  2. Message @userinfobot to get your chat ID
  3. Open /telegram-webhook in the UI and submit to register the webhook automatically

Notion Notes (optional)

  1. Create a Notion integration and copy the secret
  2. Share a Notion page with the integration and set NOTION_NOTES_PAGE_ID
  3. Subpages are auto-managed: *<name>, <note> creates or appends to a subpage

Gmail Refresh Tokens (optional)

  1. Run npm run dev and click Setup Gmail in the UI
  2. Complete the OAuth flow and copy the refresh token
  3. Repeat for additional accounts at /api/auth/gmail?action=init&account=2 (up to 5)

Running

npm install
npm run dev          # development
npm run build && npm start   # production

Scheduling

On Vercel the cron runs every 30 minutes automatically. For external cron, hit the endpoint with a bearer token:

*/30 * * * * curl -H "Authorization: Bearer $CRON_SECRET" \
  https://your-domain.com/api/cron/process

If email summaries are not configured, the endpoint returns processed: 0 with a skipped reason — no error.

Why I like it

I no longer open Gmail to see what's new. Summaries land in Telegram alongside my regular chats, so I triage without context-switching. When I have a quick question I message the bot directly. And any thought I want to keep goes straight to Notion with a single * prefix — no app-hopping, no friction.