Забываете отмечать рабочее время? Делаем простой бот на 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!
→ 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 строк кода, работает везде, данные в удобном формате.
📎 Статья
🎙 Новости
📝 База вопросов
