Telegram + ChatGPT: How I Built a Context-Aware Diary for a Neural Network

I like discussing gym workouts, nutrition, and their impact on my productivity with ChatGPT. It helps analyze recurring patterns and track changes in behavior that I don’t notice myself. But for the advice to be more accurate, it needs context: what exactly I did, how my body reacted, and how my well-being and concentration changed.

To do this, I created a private Telegram group and started keeping notes there. For example: “concentration dropped, had coffee” and an hour later: “no effect, still feeling dull.”

Then I connected this group to ChatGPT. Now, when I ask for advice, it already knows the context — and responds much more precisely.

What I Ended Up With

I write notes in a private Telegram group. A bot captures every message and saves it to a diary.md file on my server. I added a link to this file in the “Personalization” section in ChatGPT.

Telegram + ChatGPT: How I Built a Context-Aware Diary for a Neural Network

Telegram Setup

I created a group in Telegram. Then I created a bot via @BotFather. Opened its profile → Edit Bot → Bot Settings → Group Privacy → Turn off. By default, bots can’t read messages in groups, so this setting must be disabled.

I added the bot to my group via its profile. The bot doesn’t see message history — only messages sent after it was added. This is important to keep in mind.

I copied the bot’s API key via @BotFather.

Long Polling

A simple Node.js script runs on the server. It uses long polling: it sends a request to the Telegram API with the timeout=30 parameter. Telegram doesn’t respond immediately but keeps the connection open for up to 30 seconds. As soon as a new message appears, it returns a response. If nothing arrives within 30 seconds, it returns an empty array, and the script makes a new request. Each received message is appended to diary.md.

Why long polling: it’s easy to set up — no webhook with HTTPS and a public domain is required (although I do use a domain to connect to ChatGPT). Messages arrive instantly, not every N seconds. If the server restarts, the script simply continues from the last message.

async function getUpdates(offset) {
  // timeout=30 — wait up to 30 seconds until a message appears
  const url = `https://api.telegram.org/bot${BOT_TOKEN}/getUpdates?offset=${offset}&timeout=30`;
  const response = await fetch(url);
  const data = await response.json();
  return data.result || [];
}

Saving Messages to a File

The script captures each new message and appends it to the diary.md file with date and time. If I edit a message in Telegram, the script finds the entry by ID and updates the text.

Example of a Saved Message

#12
date: 03.01.2026 14:40
Workout today. 400m run, overhead press...

The ID is needed for editing. The date is automatically taken from the message timestamp.

// Telegram returns a message object with fields:
// message.message_id — unique message ID
// message.date — timestamp in seconds
// message.text — message text

function appendToDiary(message) {
  const msgId = message.message_id;
  const date = formatDateTime(message.date);
  const text = message.text;

  const entry = `#${msgId}\ndate: ${date}\n${text}\n\n`;
  
  const existing = fs.readFileSync('diary.md', 'utf8');
  fs.writeFileSync('diary.md', existing + entry);
}

function formatDateTime(timestamp) {
  const date = new Date(timestamp * 1000);
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const year = date.getFullYear();
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  return `${day}.${month}.${year} ${hours}:${minutes}`;
}

Server Setup

I already had a VPS and my own domains, so I didn’t need to buy anything extra. Then I set up an A record on a subdomain specifically for this project. On the server, I issued an SSL certificate via certbot:

sudo certbot --apache -d site.com

I ran the script as a systemd service so it runs continuously and restarts on failure. I created the config /etc/systemd/system/telegram-diary.service and enabled it via systemctl enable.

Routing for ChatGPT

I configured two endpoints in Apache. /diary serves the file as markdown — convenient to open in a browser and read myself. /diary/raw serves the same file as plain text — this format is read better by ChatGPT.

# /diary → markdown
RewriteRule ^/diary$ /diary.md [L]

# /diary/raw → plain text
Alias /diary/raw /var/www/diary/diary.md
<Location /diary/raw>
    ForceType "text/plain; charset=utf-8"
</Location>

ChatGPT Integration

I added the link https://site.com/diary/raw to the “Personalization” section in ChatGPT settings. There’s a nuance though: it doesn’t automatically open the link. At the beginning of the conversation, you need to ask: “Open the link and analyze the diary.” After that, it reads the file and continues responding with the context in mind.

Telegram + ChatGPT: How I Built a Context-Aware Diary for a Neural Network

You can create a Custom GPT and configure an Action there to automatically load the file in every conversation. But Custom GPT doesn’t have access to the account’s Memory — it doesn’t remember previous conversations. Memory is more important to me, so I use regular ChatGPT with a manual request at the start of the dialog.

keyboard_arrow_up