+31

Nhắc các cuộc họp trên Google Calendar với Bot Telegram sử dụng NodeJS

Hôm nay là ngày 25/09/2022, khoảng 8h sáng đang mơ mơ màng màng trên chiếc giường ngủ, và có những tiếng chuông điện thoại reo lên từ đám bạn rủ rê đi bơi, đi cà phê:

"Sao chủ nhật nào cũng phải gọi mày dậy vậy ? lười như cờ hó, tự giác đi chứ mậy".

Và từ đó tôi trong tôi bừng nắng hạ, cũng tự nhận ra lòng tự giác bên trong mình trỗi dậy =))).

Sau đó tôi cũng liên tưởng tới những cuộc họp trong công ty, thường bị các đồng nghiệp và síp nhắc nhở vào phòng họp chậm vì tôi là người hay không check mail (mong síp thấy đừng chửi tội em) 😀. đa số chỉ đọc các tin nhắn từ slack và telegram.

Lúc đó thoáng qua tôi mới nghĩ rằng: "phải chi telegram có con bot để nhắc vào phòng họp thì hay biết mấy !".

Và sau đây mình sẽ hiện thực hoá nó nào.

1. Tạo Bot Telegram

Trước tiên, để có ai đó tương tác với mình qua telegram thì cần phải có 1 chú bé BOT 😘. Mà để tạo được một chú bé BOT các bạn phải có tài khoản telegram nhe =))).

Sau khi đăng nhập telegram các bạn vào thanh search để tìm chúa tể của những con BOT được gọi là "BotFather" (các bạn nhớ chọn con có tick xanh nhé).

Các bạn lần lượt gõ câu lệnh như sau:

/newbot

Để yêu cầu BotFather tạo cho mình một con BOT. Sau đó BotFather sẽ lần lượt hỏi bạn để thiết lập cho BOT của bạn.

Đặt tên cho BOT
Đặt username cho BOT

Sau khi thiết lập xong BotFather sẽ sinh ra cho bạn một access token như hình bên dưới mình có được:

1AWDSD2i5625616482:AAG872AMAmYpeqeeR5tjjGvugTCbMEJQqQo3MUqqE

Vậy là xong phần tạo một con BOT từ telegram.

2.Tương tác với BOT (Nodejs)

Ở đây mình sẽ sử dụng Nodejs làm Backend để BOT nhận command từ người dùng và tương tác. Bạn có thể cài đặt Nodejs tại đây.

Và mình sẽ sử dụng thư viện node-telegram-bot-api sẵn có của nodejs để giao tiếp với Bot telegram:

Bây giờ mình sẽ tạo nodejs project và tương tác với BOT như sau. Các bạn tạo một folder và mở terminal gõ lần lượt các dòng lệnh:

npm install dotenv --save
npm install node-telegram-bot-api

Tạo một file .env để cài đặt biến môi trường với access token ở bước 1.

TELEGRAM_TOKEN=1AWDSD2i5625616482:AAG872AMAmYpeqeeR5tjjGvugTCbMEJQqQo3MUqqE

Hoàng Phúc

Tiếp theo là tạo một file index.js trong folder và paste đoạn code bên dưới vào.

require("dotenv").config();
const TelegramBot = require('node-telegram-bot-api');

// replace the value below with the Telegram token you receive from @BotFather
const token = process.env.TELEGRAM_TOKEN;

// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});

// Matches "/echo [whatever]"
bot.onText(/\/echo (.+)/, (msg, match) => {
  // 'msg' is the received Message from Telegram
  // 'match' is the result of executing the regexp above on the text content of the message
  const chatId = msg.chat.id;
  const resp = match[1]; // the captured "whatever"

  // send back the matched "whatever" to the chat
  bot.sendMessage(chatId, resp);
});

Gõ lệnh node index.js vào Terminal.

Bây giờ quay trờ lại BotFather và click vào vùng khoanh đỏ bên dưới hình để "trò chuyện" với bé BOT.

image.png

Và gõ:

/start
/echo {something}

Ok vậy là bé BOT đã nhận được tin nhắn và phản hồi lại câu lệnh mà chúng ta gõ.

3.Google Canlendar Service API

Tiếp theo chúng ta sẽ đăng nhập và đăng ký Google Console.

Tại Menu bar > IAM & Admin > Service Accounts > CREATE PROJECT.

Điền thông tin của bạn và nhấn CREATE.

Tiếp theo nhấn CREATE SERVICE ACCOUNT.

Điền tiếp thông tin của bạn và nhấn CREATE AND CONTINUE.

Ở bước 2 mình chọn Role Owner và tiếp tục nhấn CONTINUE.

g

Tại bước 3 mình không chọn account nào nên nhấn luôn DONE.

Tiếp theo chọn Manage keys.

Tại tab KEYS chọn ADD KEY > Create new key.

Ở đây mình sẽ chọn private key dạng JSON và nhấn CREATE.

Sau đó file private key sẽ được download xuống máy của bạn.

File private key của ta có dạng như sau:

Ta có thể làm 2 cách:

  • Copy file này vào project node của chúng ta và dùng fs đọc file.
  • Copy đoạn json trong file chuyển thành text để làm biến môi trường.

Nhưng do ở đây mình lười quá nên làm cách số 2 như hình bên dưới nha nha 😌

Screen Shot 2022-09-26 at 00.18.52.png

Kế tiếp chúng ta sẽ đi tìm Calendar Client ID. Truy cập vào Google Calendar. Tìm tên của bạn ở góc trái bên dưới và click vào button 3 chấm.

Chọn Settings and sharing.

image.png

Scroll xuống và tìm mục Share with specific people.

image.png

Paste client_email trong file private key json của bạn vào input và click Send.

Screen Shot 2022-09-25 at 23.17.20.png

Scroll xuống và tìm ở mục Calendar ID.

image.png

Copy đoạn text và gắn vào biến môi trường trong project node.

Screen Shot 2022-09-25 at 23.19.30.png

Quay trở lại Google Console, tại menu bar chọn APIs & Services > Enabled APIs & services

Screen Shot 2022-09-25 at 22.41.41.png

Chọn tiếp ENABLE APIS AND SERVICES.

image.png

Search từ khoá google calendar api và chọn cái đầu tiên.

image.png

Click ENABLE.

Screen Shot 2022-09-25 at 22.46.19.png

Quay trở lại project node tại Terminal thêm câu lệnh:

npm install googleapis@105 @google-cloud/local-auth@2.1.0 --save

Thêm đoạn code này lên đầu file index.js

const {google} = require('googleapis');
...

Và paste đoạn code dưới đây vào nơi bất kì trong file index.js

...
const CREDENTIALS = JSON.parse(process.env.GOOGLE_CREDENTIALS);
const calendarId = process.env.CALENDAR_CLIENT_ID;
const SCOPES = 'https://www.googleapis.com/auth/calendar';
const calendar = google.calendar({version : "v3"});
const auth = new google.auth.JWT(
    CREDENTIALS.client_email,
    null,
    CREDENTIALS.private_key,
    SCOPES
);

// Get all the events between two dates
const getEvents = async (dateTimeStart, dateTimeEnd) => {
    try {
        let response = await calendar.events.list({
            auth: auth,
            calendarId: calendarId,
            timeMin: dateTimeStart,
            timeMax: dateTimeEnd,
            timeZone: 'Asia/Ho_Chi_Minh'
        });
        console.log(response['data']);
        let items = response['data']['items'];
        return items;
    } catch (error) {
        console.log(`Error at getEvents --> ${error}`);
        return 0;
    }
};

Ok bây giờ mình sẽ hardcode thời gian bằng đoạn code bên dưới để testing Google Calendar API nhé.

let start = '2022-09-25T00:00:00.000Z';
let end = '2022-09-25T23:59:59.000Z';

getEvents(start, end)
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

Mở Terminal và gõ lệnh nodex index.js

Screen Shot 2022-09-25 at 22.53.20.png

Vậy response ta nhận được một mảng rỗng. Bây giờ chúng ta vào calendar tạo và test lại thử nhé

Screen Shot 2022-09-25 at 22.55.16.png

Và mình đã tạo thời gian từ 11pm-12am ngày 25/09/2022 với tiêu đề 'Có chắc yêu là đây ?'. Bật Terminal và test lại nhé.

Screen Shot 2022-09-25 at 23.20.56.png

Và bây giờ chúng ta đã thấy lịch vừa tạo ở trên với summary 'Có chắc yêu là đây ?' 😁

4.Tạo schedule chat bằng telegram BOT

Để tạo 1 schedule mình sẽ sử dụng thư viện Node Schedule. Tại Terminal project node gõ câu lệnh để cài Node Schedule:

npm install node-schedule

Thêm đoạn code bên dưới vào đầu file index.js

const schedule = require('node-schedule');
...

Để tạo một job schedule ta sử dụng đoạn code bên dưới:

const job = schedule.scheduleJob('07 * * * *', function(){
  console.log('Xin chào nè he');
});

Với Cron-style được giải thích như sau: Screen Shot 2022-09-25 at 23.28.48.png

Bây giờ mình sẽ viết một đoạn code convert time từ google calendar API trả về để tạo thành cron job.

function createJob(googleCalendarList, chatId) {
	googleCalendarList.forEach(function(item, index) {
		if (item?.start?.dateTime) {
			let time = new Date(item.start.dateTime);
			let minutes = time.getMinutes();
			let hours = time.getHours();
			let date = time.getDate();
			let month = time.getMonth() + 1;
			let cron = `${minutes} ${hours} ${date} ${month} *`;
			console.log(cron);
			let job = schedule.scheduleJob(cron, function() {
				//Để nhấn mạnh mình cho nó chat tới 3 lần :)))
				bot.sendMessage(chatId, `Cuộc họp có tiêu đề '${item.summary}' sắp diễn ra !!!`);
				bot.sendMessage(chatId, `Cuộc họp có tiêu đề '${item.summary}' sắp diễn ra !!!`);
				bot.sendMessage(chatId, `Cuộc họp có tiêu đề '${item.summary}' sắp diễn ra !!!`);
				//sau khi chạy xong thì xoá luôn cron job này.
				job.cancel();
			});
		}
	});
}

Mình sẽ bọc đoạn code testing phía trên và hàm convert time lại để telegram BOT có thể nhận được tín hiệu và set schedule với command là calendar_start.

bot.onText(/\/calendar_start/, (msg, match) => {
	const chatId = msg.chat.id;
    
    //khoảng thời gian mà bạn muốn lấy lịch ở đây mình lấy trong 1 ngày 0h - 23h59
    let start = '2022-09-26T00:00:00+07:00';
	let end = '2022-09-26T23:59:59+07:00';

	getEvents(start, end)
		.then((res) => {
			createJob(res,chatId);
		})
		.catch((err) => {
			console.log(err);
		});
});

Hiện tại bây giờ là 23:54 phút mình sẽ tạo lịch vào lúc 00:15 ngày 26/09/2022 để xem telegram BOT có báo cho mình không nha.

Screen Shot 2022-09-26 at 00.02.08.png

Tiếp vào Telegram BOT dùng câu lệnh calendar_start để ra lệnh cho BOT lấy dữ liệu từ google calendar API về để testing.

Screen Shot 2022-09-25 at 23.59.16.png

Sau khi đợi 15 phút sau thì nhận được tin nhắn lúc 00:15.

image.png

Bước cuối cùng là set schedule mỗi 7h sáng để kéo dữ liệu Google Calendar Data về và set schedule.

function getGoogleCalendarAPI(chatId) {
	let currentTime = new Date();
	let start = `${currentTime.getFullYear()}-${currentTime.getMonth() + 1}-${currentTime.getDate()}T00:00:00+07:00`;
	let end = `${currentTime.getFullYear()}-${currentTime.getMonth() + 1}-${currentTime.getDate()}T23:59:59+07:00`;
	getEvents(start, end)
		.then((res) => {
			createJob(res, chatId);
		})
		.catch((err) => {
			console.log(err);
		});
}

let jobEveryDay = schedule.scheduleJob('0 7 * * *', function() {
    let chatId = //Bạn có thể set cứng chatId của telegram user của bạn hoặc 1 group để BOT gửi tin nhắn vào.
	getGoogleCalendarAPI(chatId);
});

Vậy với thao tác chỉ với tầm ~30 phút ta có thể tạo một con BOT tương tác qua Telegram một cách dễ dàng.

Ở đây mình chỉ hướng dẫn cách tạo một con BOT, Google Calendar API và cách hoạt động của nó là chính (nếu muốn thực hiện hoá luôn thì bạn nên trừ thêm 5~10 phút trước khi vào phòng họp nhé) còn các chức năng khác các bạn có thể tự suy nghĩ và tuỳ biến nó nhé 😁.

Các chức năng BOT của mình:

Screen Shot 2022-09-26 at 00.35.20.png

Chúc các bạn nhiều sức khoẻ ❤️.

Mục tìm kiếm đồng đội

Hoàng Phúc

Team công nghệ Hoàng Phúc của bọn mình được thành lập với nhiệm vụ là xây dựng một hệ thống công nghệ nội bộ cho công ty, Hoàng Phúc là một công ty bán lẻ trong lĩnh vực thời trang và có hơn 30 năm tuổi đời, với chuỗi cửa hàng rất nhiều trên toàn quốc, nên việc vận hành của Hoàng Phúc là rất lớn và việc xây dựng được một hệ thống công nghệ để đáp ứng việc vận hành nội bộ cho công ty là một công việc rất thử thách, đây là một quá trình chuyển đổi số và team bọn mình đã làm được những bước ban đầu.

Thứ mà team mình thấy cấn duy nhất là cái website, đây là trang web mà trước khi team mình được thành lập đã có một đội outsource khác làm, và những gì họ để lại cho bọn mình là một trang web với đống bùi nhùi, với số điểm từ google là 1 trên 100. Vậy bọn mình sẽ làm gì với trang web này đây, nản chí sao? Điều đó không có trong từ điển của hai sếp mình, và với sự dẫn dắt của hai sếp team mình sẽ biến đống website bùi nhùi đó thành kim cương, như cách bọn mình đã cải thiện hệ thống nội bộ. Bọn mình đang cải thiện trang web hằng ngày và hằng ngày, từ 1 điểm bọn mình đã cải thiện nó lên 70 điểm, và mục tiêu là trên 90 điểm.

Hiện tại team bọn mình đang cần các đồng đội tham gia để cải thiện lại trang web với số lượng người dùng truy cập khá lớn, đây là một thử thách rất thú vị, có bao giờ các bạn được tham gia thiết kế một hệ thống lớn từ đầu chưa, mình khá chắc là số lượng đó rất ít. Bọn mình đã có khách hàng, những gì còn lại là cần những đồng đội để cùng nhau phát triển một hệ thống để phục vụ rất nhiều người dùng. Mục tiêu của công ty Hoàng Phúc là trở thành nhà bán lẻ về thời trang lớn nhất Việt Nam, hãy tham gia với bọn mình nhé. Một thành viên trong team mình không yêu cần phải giỏi, chỉ cần hòa đồng, hợp tác và sẵn sàng hợp tác với nhau. Có thể bạn không là giỏi nhất nhưng nếu gia nhập với bọn mình thì bạn sẽ tạo ra được những thứ giá trị nhất.

Đồng đội Senior Backend Engineer.

Đồng đội Senior Frontend Engineer.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí