I'm developing a Telegram bot on Google Apps Script for personal purposes: entering expenses / incomes for different types.
I have several types of expenses that I record in Google Spreadsheets.
My idea
I got a problem implementing the expense input. I liked how this is implemented in the official bot @BotFather
@BotFather
How can you implement this correctly? Preferably with GAS.
Thanks.
Bot.gs
var token = "<BOT_TOKEN>";
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = "https://script.google.com/macros/s/<ID>/exec";
function getMe() {
var url = telegramUrl + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function deletWebhook() {
var url = telegramUrl + "/setWebhook";
var response = UrlFetchApp.fetch(url);
}
function doGet(e) {
return HtmlService.createHtmlOutput("Webhook is working.");
}
// Send message
function sendMessage(chat_id, text) {
var data = {
method: "post",
payload: {
method: "sendMessage",
chat_id: String(chat_id),
text: text,
parse_mode: "HTML",
disable_web_page_preview: true
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
// Delete message
function deleteMessage(chat_id, message_id) {
var data = {
method: "post",
payload: {
method: "deleteMessage",
chat_id: String(chat_id),
message_id: parseInt(message_id, 10)
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
// Edit message
function editMessage(chat_id, message_id, text) {
var data = {
method: "post",
payload: {
method: "editMessageText",
chat_id: String(chat_id),
message_id: parseInt(message_id, 10),
text: text,
parse_mode: "HTML",
disable_web_page_preview: true
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
// Send message and keyboard
function sendMessageKeyboard(chat_id, text, keyboard) {
var data = {
method: "post",
payload: {
method: "sendMessage",
chat_id: String(chat_id),
text: text,
parse_mode: "HTML",
reply_markup: JSON.stringify(keyboard)
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
// Hide keyboard
function hideKeyBoard(chat_id, message_id) {
var data = {
method: "post",
payload: {
method: "editMessageReplyMarkup",
chat_id: String(chat_id),
message_id: parseInt(message_id, 10)
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
// Replace keyboard
function replaceKeyBoard(chat_id, message_id,keyboard) {
var data = {
method: "post",
payload: {
method: "editMessageReplyMarkup",
chat_id: String(chat_id),
message_id: parseInt(message_id, 10),
reply_markup: JSON.stringify(keyboard)
}
};
UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/", data);
}
doPost.gs
function doPost(e) {
var contents = JSON.parse(e.postData.contents);
if (contents.callback_query) {
var message_id = contents.callback_query.message.message_id;
var data = contents.callback_query.data;
var multiData = data.split(" ");
var chat_id = contents.callback_query.from.id;
if (data == 'Back') {
replaceKeyBoard(chat_id, message_id, KEYBOARD_COMPANIES);
} else if (data == 'Cancel') {
deleteMessage(chat_id, message_id);
sendMessageKeyboard(chat_id, "Choose the action:", KEYBOARD_COMPANIES);
} else if (data == 'Common') {
replaceKeyBoard(chat_id, message_id, KEYBOARD_COMMON);
} else if ((multiData[1]) && (multiData[0] == 'Common')) {
deleteMessage(chat_id, message_id);
sendMessageKeyboard(chat_id, "<b>Expense: " + multiData[0] + " -> " + multiData[1] + ".</b> Input the value:", KEYBOARD_INPUT);
}
} else if (contents.message) {
var chat_id = contents.message.from.id;
var text = contents.message.text;
if (text == "/start") {
deleteMessage(chat_id, contents.message.message_id)
sendMessageKeyboard(chat_id, "Choose the action:", KEYBOARD_COMPANIES);
} else if (!isNaN(parseFloat(text)) && isFinite(text)) {
for (var i = 0; i < logins.length; i++) {
if (chat_id == logins[i]) {
sBot.getRange("C" + (i + 2)).setValue(text);
replaceKeyBoard(chat_id, sBot.getRange("D" + (i + 2)).getValue());
}
}
}
}
}
Keyboard.gs
// 1 Companies
var KEYBOARD_COMPANIES = {
"inline_keyboard": [
[{ "text": "Common", 'callback_data': 'Common' }],
[{ "text": "Smoky Unicorn", 'callback_data': 'Smoky Unicorn' }],
[{ "text": "Pussy Stuff", 'callback_data': 'Pussy Stuff' }],
[{ "text": "Trash Seller", 'callback_data': 'Trash Seller' }]
]
};
// 1.1 Common
var KEYBOARD_COMMON = {
"inline_keyboard": [
[{ "text": "Back", 'callback_data': 'Back' }],
[{ "text": "Taxi", 'callback_data': 'Common Taxi' }],
[{ "text": "Food", 'callback_data': 'Common Food' }],
[{ "text": "Party", 'callback_data': 'Common Party' }]
]
};
// Reply
var FORCE_REPLY = {
"force_reply": true
};
// Input the value
var KEYBOARD_INPUT = {
"inline_keyboard": [
[{ "text": "Cancel", 'callback_data': 'Cancel' }]
]
};
Functions.gs
// Global
var todayMonth = getMonthToday();
var NEWL = String.fromCharCode(10); // newline
var accId = "<Spreadsheet_ID"; // Accounting Spreadsheet
var acc = SpreadsheetApp.openById(accId);
var sAcc = acc.getSheetByName(todayMonth);
var sBot = acc.getSheetByName("Bot");
// @usernames who have access to the bot
var andreyChatId = sBot.getRange("B2").getValue();
var donyChatId = sBot.getRange("B3").getValue();
// chat_id who have access to the bot
var logins = ["99587408", "155390785"];
// Get current month
function getMonthToday() {
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var todayDate = new Date();
var todayMonth = months[todayDate.getMonth()];
return todayMonth;
}

