TGViewer
YeaHub Tech YeaHub Tech @yeahub_tech · 412 subscribers
Post #293 110
🔖 Тайм-трекер в Telegram за вечер

Забываете отмечать рабочее время? Делаем простой бот на Node.js + TypeScript!


🔍 История

Жене нужен был отчёт за 3 месяца работы, но инструмента для учёта времени не было. Сначала писала "начало"/"конец" в WhatsApp группу. Решил автоматизировать это через Telegram Bot!


💡 Что получилось:

✅ 4 простые команды
✅ Автоподсчёт времени
✅ Экспорт в CSV
✅ Работает везде (телефон всегда под рукой!)


🔸Команды:

🔸 /work [задача] — начать работу
🔸 /done — завершить задачу
🔸 /state — текущий статус
🔸 /print — вывести CSV


🔸Стек:

• Node.js + TypeScript
• node-telegram-bot-api
• CSV для хранения
• Docker для деплоя


🔸 Быстрый старт:

1️⃣ Установка:
npm i --save node-telegram-bot-api
npm i --save @types/node-telegram-bot-api


2️⃣ Создать бота:
Идём к @BotFather → /newbot → получаем токен

3️⃣ Базовый код:
import TelegramBot from 'node-telegram-bot-api';

const token = 'YOUR_TOKEN';
const bot = new TelegramBot(token, { polling: true });

// Начать задачу
bot.onText(/\/work (.+)/, async (msg, match) => {
const chatId = msg.chat.id;
const work = match[1];
const startDate = new Date();

const entries = await getEntries();
entries.push({
work,
startDate: startDate.toJSON(),
endDate: null,
duration: null,
});
writeFile(entries);

bot.sendMessage(chatId,
`Started ${work} at ${startDate.toLocaleString()}`);
});

// Завершить задачу
bot.onText(/\/done(.*)/, async (msg) => {
const chatId = msg.chat.id;
const endDate = new Date();

const entries = await getEntries();
const targetEntry = entries[entries.length - 1];
targetEntry.endDate = endDate.toJSON();

const startDate = new Date(targetEntry.startDate);
const diff = endDate - startDate;
targetEntry.duration = formatDuration(diff);

writeFile(entries);

bot.sendMessage(chatId,
`Finished ${targetEntry.work}. Took ${diff}!`);
});


🔸 Работа с CSV:
const getEntries = async () => {
const val = fs.readFileSync(csvFilePath).toString();
const entries = [];

val.split("\n").forEach((row, index) => {
if (row === "" || index == 0) return;
const [work, startDate, endDate, duration] =
row.split(';');
entries.push({ work, startDate, endDate, duration });
});

return entries;
}

const writeFile = (entries) => {
let str = "work;startDate;endDate;duration;\n";
entries.forEach(e => {
str += Object.keys(e).map(k => e[k]).join(';') + '\n';
});
fs.writeFileSync(csvFilePath, str);
};


🔸 Использование:

/work Написать статью
→ Started at 9:00 AM

/done
→ Finished. Took 3h 25m!

/print
→ work;startDate;endDate;duration;
Статья;2025-01-20T09:00...;3h 25m


🔸 Деплой:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["node", "build/main/index.js"]


docker build -t timetracker .
docker run -ti timetracker



🔸Преимущества:

✅ Просто — 4 команды
✅ Быстро — 2 секунды на команду
✅ Везде — Telegram на всех устройствах
✅ Бесплатно — без подписок
✅ CSV — легко открыть в Excel


🔸 Идеи для улучшения:

🔸 Категории задач (#важное, #срочное)
🔸 Статистика по дням/неделям
🔸 Напоминания о перерывах
🔸 Экспорт в JSON/PDF
🔸 Интеграция с календарём


❗️ Важно:

Не коммитьте токен! Используйте .env:
import dotenv from 'dotenv';
dotenv.config();

const token = process.env.TELEGRAM_BOT_TOKEN;



Итог ⬇️

За один вечер — полнофункциональный тайм-трекер! ~200 строк кода, работает везде, данные в удобном формате.


📎 Статья

🎙 Новости

📝 База вопросов
More from @yeahub_tech
  1. Oct 9, 2026#Собес #pipeline #ci #stage 🤔 Что происходит при автоматической сборке feature-ветки на s…
  2. Oct 8, 2026#course #задачи #тесты 📚 JavaScript. A3 Задачи Задачи на программирования на языке JavaSc…
  3. Oct 7, 2026#course #начинающие 📚 Твой Golang Твой Golang — это идеальный старт для освоения языка. П…
  4. Oct 5, 2026🧑‍💻 Вопросы с собесов для Node.js Разработчика 1. Как использовать Service Workers для р…
  5. Oct 2, 2026#Собес #transaction #propagation #required 🤔 Что такое propagation у транзакций и какие т…
  6. Oct 1, 2026#book #book 📚 Библия C#. 6-е изд. Автор: Михаил Фленов Это настольная книга программиста,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →