Google Script là gì?
Google Script – đọc qua cái tên thì ta cũng có thể mường tượng được chức năng của nó: là 1 ngôn ngữ lập trình dựa trên Javascript với trình biên tập, biên dịch đều nằm trên máy chủ của Google. Với công cụ này bạn có thể lập trình để thao tác, can thiệp trực tiếp đến các dịch vụ của Google. Ngoài ra còn cơ số các chức năng hay ho khác nữa, trong số đó thì có việc thực thi một function với thời gian nhất định trong một ngày, mình đã lợi dụng điểm này để đẩy thông báo lịch học.
Bắt đầu viết code thôi
Giao diện của Google App Script sẽ trông như thế này
Nhấn vào nút Dự án mới để tiến hành viết Code
Ban đầu tất nhiên là phải xây dựng database cho con Bot rồi. Ở đây mình sử dụng google sheet để làm database.
Nội dung của sheet này như sau:
Vì đây là thời khóa biểu học kì một của mình nên chỉ có từ tháng 8 đến tháng 12 thôi.
Có database rồi vậy làm thế nào để có thể đọc được dữ liệu từ sheet đây? Đây chính là lúc phát huy thế mạnh của Google Script. Chúng ta có thể đọc file sheet với function sau
1 2 | SpreadsheetApp<span class="token punctuation">.</span><span class="token function">openById</span><span class="token punctuation">(</span>file_tkb<span class="token punctuation">)</span> |
Các bạn có thể xem chi tiết tại đây https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
Trong đó file_tkb
là id
của sheet database nó được lấy như trong hình ở bên dưới
Tiếp theo chúng ta sẽ đi xây dựng logic đọc sheet để có thể lấy đúng dữ liệu mong muốn:
1 2 3 4 | <span class="token keyword">var</span> today <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> first <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>today<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">29</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> theDay <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>today <span class="token operator">-</span> first<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">1000</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">.5</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Ở đoạn code trên mình lấy ra ngày hiện tại (today
), ngày đầu tiên của tuần đầu tiên học kì mới (first
ở đây là ngày 29 tháng 7), sau đó tính xem ngày hôm nay cách ngày đầu tiên đi học bao nhiêu ngày (theDay
).
Tiếp theo lần lượt tạo ra các biến sau
1 2 3 4 5 6 | <span class="token keyword">var</span> week_1 <span class="token operator">=</span> theDay<span class="token operator">/</span><span class="token number">7</span><span class="token punctuation">;</span> <span class="token keyword">var</span> week_mod <span class="token operator">=</span> theDay<span class="token operator">%</span><span class="token number">7</span><span class="token punctuation">;</span> <span class="token keyword">var</span> week_col<span class="token punctuation">;</span> <span class="token keyword">var</span> week_row<span class="token punctuation">;</span> <span class="token keyword">var</span> message<span class="token punctuation">;</span> |
Trong đó:
- Nếu
week_mod == 0 || week_mod == 6
thì ngày hôm nay là cuối tuần gán
message = "Hôm nay là cuối tuần chịu khó tập thể dục đi";
- Ngược lại ta có:
1 2 3 4 5 | week_col <span class="token operator">=</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>week_1<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span> week_row <span class="token operator">=</span> week_mod<span class="token punctuation">;</span> <span class="token keyword">var</span> real_col <span class="token operator">=</span> week_col<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">var</span> real_row <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>week_row<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">*</span><span class="token number">3</span><span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Ví dụ cho dễ hiểu một chút:
Giả sử hôm nay là ngày 20/12/2019
thì ta có theDay = 145
, week_mod = 5
vậy có nghĩa là thứ 6. real_col = 23 ; real_row = 14
chúng ta sẽ bắt đầu lấy dât trong sheet ở cột 23, dòng 14.
Để lấy data mình sử dụng đoạn code như sau:
1 2 3 4 5 6 | <span class="token keyword">var</span> file_tkb <span class="token operator">=</span> <span class="token constant">YOUR_SHEET_ID</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ss <span class="token operator">=</span> SpreadsheetApp<span class="token punctuation">.</span><span class="token function">openById</span><span class="token punctuation">(</span>file_tkb<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> url <span class="token operator">=</span> ss<span class="token punctuation">.</span><span class="token function">getUrl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> a <span class="token operator">=</span> ss<span class="token punctuation">.</span><span class="token function">getSheets</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getSheetValues</span><span class="token punctuation">(</span>real_row<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> real_col<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> study_code <span class="token operator">=</span> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> |
Khi đã có vị trí của data trong sheet thì lấy dữ liệu ra bằng function getSheetValues
, các bạn có thể xem chi tiết tại đây nhé https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
Ở đây dữ liệu trả về là một mảng 2 chiều, ta thu được study_code = a[0][0]
, đây chính là mã môn học mà chúng ta cần.
Tạo từ điển tương ứng cho mã môn học vừa nhận được
1 2 3 4 5 6 7 8 | <span class="token keyword">var</span> <span class="token constant">DICTIONARY</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"AT6"</span><span class="token punctuation">:</span> <span class="token string">"An toàn điện toán đám mây"</span><span class="token punctuation">,</span> <span class="token string">"TM5"</span><span class="token punctuation">:</span> <span class="token string">"Chứng thực điện tử"</span><span class="token punctuation">,</span> <span class="token string">"TM6"</span><span class="token punctuation">:</span> <span class="token string">"Phòng chống và điều tra tội phạm máy tính"</span><span class="token punctuation">,</span> <span class="token string">"TM7"</span><span class="token punctuation">:</span> <span class="token string">"An toàn Internet & TM điện tử"</span><span class="token punctuation">,</span> <span class="token string">"AT5"</span><span class="token punctuation">:</span> <span class="token string">"Quản trị an toàn hệ thống"</span> <span class="token punctuation">}</span> |
Vậy là đã có đủ thông tin để gửi tin nhắn rồi format lại message gửi đi một chút cho hợp lý
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">if</span><span class="token punctuation">(</span>study_code <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> study_name <span class="token operator">=</span> <span class="token constant">DICTIONARY</span><span class="token punctuation">[</span>study_code<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>study_name <span class="token operator">==</span> undefined<span class="token punctuation">)</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Opps!!!nLát nữa cậu phải học môn có mã là "</span><span class="token operator">+</span> study_code <span class="token operator">+</span><span class="token string">" từ 18h đến 21h đấy nhé!!"</span><span class="token punctuation">;</span> message <span class="token operator">=</span> message <span class="token operator">+</span> <span class="token string">"nVui lòng update lại từ điển để mình có thể biết được tên môn"</span><span class="token punctuation">;</span> message <span class="token operator">=</span> message <span class="token operator">+</span> <span class="token string">"nNếu mã môn trên là sai, hãy xem lại thời khóa biểu tại: "</span><span class="token operator">+</span> url<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Hê lô mai phen :))nLát nữa cậu phải học môn "</span><span class="token operator">+</span> study_name <span class="token operator">+</span> <span class="token string">" từ 18h đến 21h đấy nhé!!"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Hôm nay cậu được nghỉ đấy (tunghoa)"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>week_mod <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> message <span class="token operator">+</span> <span class="token string">"nHôm nay cũng là thứ 4, 21h đi đá bóng nhé"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Tiếp theo là bước gửi tin nhắn với message
ở trên. Ở đây mình sử dụng Chatwork, Messenger Facebook, Telegram để nhận tin nhắn thông báo.
Gửi tin nhắn về Chatwork
Để có thể gửi tin nhắn về chatwork thì trước tiên chúng ta phải có API_KEY của Chatwork. Mình đã document của chatwork thì thấy để có thể mention một người vào tin nhắn thì phải sử dụng webhook, tuy nhiên function của mình đang không hoạt động theo cơ chế này, vì thế mà mình sử dụng một mẹo nhỏ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">function</span> <span class="token function">send_to_chatwork</span><span class="token punctuation">(</span>textMessage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> room_id <span class="token operator">=</span> <span class="token string">"170443428"</span> <span class="token keyword">var</span> <span class="token constant">API_TOKEN</span> <span class="token operator">=</span> <span class="token constant">YOUR_API_CHATWORK</span> <span class="token keyword">var</span> baseText <span class="token operator">=</span> <span class="token string">"[toall] Boss n"</span> <span class="token operator">+</span> textMessage <span class="token comment">//private user [To:3797875]</span> <span class="token keyword">var</span> headers <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"X-ChatWorkToken"</span><span class="token punctuation">:</span> <span class="token constant">API_TOKEN</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> payload <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"body"</span><span class="token punctuation">:</span> baseText <span class="token punctuation">}</span> <span class="token keyword">var</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"method"</span><span class="token punctuation">:</span> <span class="token string">"post"</span><span class="token punctuation">,</span> <span class="token string">"headers"</span><span class="token punctuation">:</span> headers<span class="token punctuation">,</span> <span class="token string">"payload"</span><span class="token punctuation">:</span> payload<span class="token punctuation">,</span> <span class="token string">"muteHttpExceptions"</span><span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> UrlFetchApp<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.chatwork.com/v2/rooms/"</span> <span class="token operator">+</span> room_id <span class="token operator">+</span> <span class="token string">"/messages?force=0"</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span> Logger<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Send Chatwork ok"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Tạo riêng cho mình và Bot một room chat, sau đó add hai người vào trong đoạn tin nhắn gửi đến thì thê đoạn text [toall]
vậy là tất cả thành viện trong room đã được mention vào message
Gửi tin nhắn qua Messenger và Telegram
Telegram:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">function</span> <span class="token function">send_to_telegram</span><span class="token punctuation">(</span>textMessage<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> payload <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"method"</span><span class="token punctuation">:</span> <span class="token string">"sendMessage"</span><span class="token punctuation">,</span> <span class="token string">"chat_id"</span><span class="token punctuation">:</span> <span class="token constant">YOUR_CHAT_ID</span><span class="token punctuation">,</span> <span class="token string">"text"</span><span class="token punctuation">:</span> textMessage<span class="token punctuation">,</span> <span class="token string">"parse_mode"</span><span class="token punctuation">:</span> <span class="token string">"HTML"</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"method"</span><span class="token punctuation">:</span> <span class="token string">"post"</span><span class="token punctuation">,</span> <span class="token string">"payload"</span><span class="token punctuation">:</span> payload <span class="token punctuation">}</span> <span class="token keyword">var</span> <span class="token constant">API_TOKEN</span> <span class="token operator">=</span> <span class="token constant">YOUR_API_BOT_TELEGRAM</span><span class="token punctuation">;</span> UrlFetchApp<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'https://api.telegram.org/bot'</span> <span class="token operator">+</span> <span class="token constant">API_TOKEN</span> <span class="token operator">+</span> <span class="token string">'/'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">;</span> Logger<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Send Telegram ok"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Messenger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token keyword">function</span> <span class="token function">send_to_facebook</span><span class="token punctuation">(</span>textMessage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> recipient_ids <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token constant">YOUR_CHAT_ID</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">var</span> <span class="token constant">API_TOKEN</span> <span class="token operator">=</span> <span class="token constant">YOUR_GRAPH_API_FACEBOOK</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> recipient_ids<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> messageData <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"recipient"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">"id"</span><span class="token punctuation">:</span> recipient_ids<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">"text"</span><span class="token punctuation">:</span> textMessage <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> JSONdMessageData <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> messageData<span class="token punctuation">)</span><span class="token punctuation">{</span> JSONdMessageData<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>messageData<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> payload <span class="token operator">=</span> JSONdMessageData <span class="token comment">// payload.access_token = API_TOKEN</span> <span class="token keyword">var</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"method"</span><span class="token punctuation">:</span> <span class="token string">"post"</span><span class="token punctuation">,</span> <span class="token string">"payload"</span><span class="token punctuation">:</span> payload <span class="token punctuation">}</span> UrlFetchApp<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"https://graph.facebook.com/v5.0/me/messages?access_token="</span> <span class="token operator">+</span> <span class="token constant">API_TOKEN</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> Logger<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Send Facebook ok"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Đối với Telegram chúng ta phải tạo một con Bot Telegram và lấy YOUR_CHAT_ID
thông qua YOUR_API_BOT_TELEGRAM
của con bot đó các bạn có thể xem hướng dẫn tại đây
Đối với Messenger thì chúng ta cần tạo ra một Page cho Bot, sau đó gửi cho Page một tin nhắn để có thể lấy được YOUR_CHAT_ID
thông qua YOUR_GRAPH_API_FACEBOOK
, còn về chi tiết thì mình không hướng dẫn nữa để tránh dài dòng, nếu thực sự quan tâm thì có thể tham khảo các bài viết khác liên quan đến Graph API Facebook
Cuối cùng là việc setting cho function của mình chạy hàng ngày vào một khung giờ nhất định
Ở đây chọn tên function cần thực thi để chạy hàng ngày
Vậy là các bạn đã hiểu về cách hoạt động của Bot rồi nhỉ ).
Tùy vào sự sáng tạo mà có thể viết được Bot có chức năng khác nhau, ở đây mình có viết thêm chức năng báo thời tiết nữa.
Và đây là thành quả
Bài viết của mình đến đây là kết thúc hy vọng sẽ giúp ích và mang lại niềm vui cho mọi người.
Tuy nhiên khi viết xong bài này khái niệm về ChatBot của mình có vẻ như đang bị lẫn lộn , bởi vì ChatBot có thể reply message tự động khi mà nhận được message đến, hiện tại thì Bot của mình chưa làm được điều đó, thực chất nó chỉ là một Function có chức năng đẩy message trong một khoảng thời gian thôi.
Vậy bạn hiểu khái niệm ChatBot là như thế nào, nếu mình đang hiểu sai thì comment cho mình biết nhé