Skip to content

Instantly share code, notes, and snippets.

@NoCtrlZ1110
Last active March 29, 2025 09:58
Show Gist options
  • Save NoCtrlZ1110/6bc7dd58d9512a4710c151c6e20478ca to your computer and use it in GitHub Desktop.
Save NoCtrlZ1110/6bc7dd58d9512a4710c151c6e20478ca to your computer and use it in GitHub Desktop.
Telegram to Google Sheet || Subscribe to my channel: https://bit.ly/van-huy-dev-youtube
// Constants
const TOKEN = `<YourTokenHere>`;
const BASE_URL = `https://api.telegram.org/bot${TOKEN}`;
const CHAT_ID = '<ChatId>';
const DEPLOYED_URL = '<YourScriptDeployedURL>';
const SUM_CELL = 'G2';
const METHODS = {
SEND_MESSAGE: 'sendMessage',
SET_WEBHOOK: 'setWebhook',
GET_UPDATES: 'getUpdates',
}
// Utils
const toQueryParamsString = (obj) => {
return Object.keys(obj)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
.join('&');
}
// Telegram APIs
const makeRequest = async (method, queryParams = {}) => {
const url = `${BASE_URL}/${method}?${toQueryParamsString(queryParams)}`
const response = await UrlFetchApp.fetch(url);
return response.getContentText();
}
const sendMessage = (text) => {
makeRequest(METHODS.SEND_MESSAGE, {
chat_id: CHAT_ID,
text
})
}
const setWebhook = () => {
makeRequest(METHODS.SET_WEBHOOK,{
url: DEPLOYED_URL
})
}
const getChatId = async () => {
const res = await makeRequest(METHODS.GET_UPDATES);
console.log("ChatId: ", JSON.parse(res)?.result[0]?.message?.chat?.id)
}
// Google Sheet
const addNewRow = (content = []) => {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const Avals = sheet.getRange("A1:A").getValues();
const Alast = Avals.filter(String).length;
const columnNumber = content.length;
const newRow = sheet.getRange(Alast + 1, 1, 1, columnNumber);
newRow.setValues([content]);
}
// Extract label & price
const getMultiplyBase = (unitLabel) => {
switch (unitLabel) {
case 'k':
case 'K':
case 'nghìn':
case 'ng':
case 'ngàn':
return 1000;
case 'lít':
case 'lit':
case 'l':
return 100000;
case 'củ':
case 'tr':
case 'm':
case 'M':
return 1000000;
default:
return 1;
}
};
const addExpense = (text) => {
const regex = /(.*)\s(\d+)\s*(.*)/g;
const label = text.replace(regex, '$1');
const priceText = text.replace(regex, '$2');
const unitLabel = text.replace(regex, '$3');
const time = new Date().toLocaleString();
const price = Number(priceText) * getMultiplyBase(unitLabel);
addNewRow([time, label, price]);
}
// Webhooks
const doPost = (request) =>{
const contents = JSON.parse(request.postData.contents);
const text = contents.message.text;
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
addExpense(text);
const totalExpenses = sheet.getRange(SUM_CELL).getValue().toLocaleString('vi-VN', {style : 'currency', currency : 'VND'});
sendMessage(`Tổng chi tiêu: ${totalExpenses}`);
}
@lebathang
Copy link

Nice 👍

@mhqb365
Copy link

mhqb365 commented Feb 9, 2024

Tks bro ❤

@os24ultra004
Copy link

Thanks

@thiendt2k1
Copy link

cảm ơn anh ạ

@Quynh4
Copy link

Quynh4 commented Nov 2, 2024

cảm ơn anh ạ, quá hữu ích <3

@Big4rest
Copy link

Big4rest commented Feb 4, 2025

nice- sogoood!

@lc-thanh
Copy link

Trong hàm getMultiplyBase() em thấy anh có chia trường hợp đơn vị tiền là "củ", "lít".
Nhưng em thử thì thấy Bot chạy sai, em nghĩ do pattern của anh là /(.*)\s(\d*)(\w*)/g nó không tách đúng các phần text, nên em có sửa lại là như này: /(.*)\s(\d+)\s*(.*)/ thì thấy chạy được.
Em góp ý ạ, mong anh đọc được :v

@NoCtrlZ1110
Copy link
Author

Có vẻ regex \w không match được các ký tự tiếng Việt mà chỉ match với [a-zA-Z0-9_].
Mình chưa test kỹ nên bị sót case này, mình sẽ cập nhật regex của bạn vào gist.
Cảm ơn b @lc-thanh nhiều nha. 💯

@leo1in88
Copy link

Có cách nào sao cho chi phí mình nhập vào mỗi tháng sẽ tách biệt cho từng sheet con trong sheet lớn không bạn nhỉ? chẳng hạn chi phí mình nhập vào tháng 3 sẽ nằm trong tab sheet March, hay tháng tư sẽ rơi vào sheet con April.

@leo1in88
Copy link

Nếu dữ liệu mình nhập vào không có số nào, có thể mình quên số, thì dữ liệu trả về là #NUM!, mình sửa lỗi này mãi mà không được, có cách nào để chặn dữ liệu nhập vào hoặc báo lỗi nếu thông tin không có số tiền không bạn nhỉ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment