'nodeJS - How to run cron job to send telegram bot messages
I have this code in my telegram bot:
const fs = require('fs/promises');
const keyFile = 'luminous-re1c7.json'
const { Storage } = require('@google-cloud/storage')
const storage = new Storage()
const bucket = storage.bucket('bakekabot-storage')
bucket.file(keyFile).download({
destination: keyFile
}).then( response => {
console.log(response)
})
const { Datastore } = require('@google-cloud/datastore');
const datastore = new Datastore({
projectId: 'lumi13',
keyFile: keyFile
});
const cron = require('node-cron');
cron.schedule('* 1 * * * *', () => {
console.log('Sending alert to subscribers each minute!TEST MODE ON')
datastore.get(['bakekabot_subscribers']).then(console.log)
}).start()
//task.start();
const puppeteer = require('puppeteer');
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('541070:A', {
polling: true,
// webHook: {
// port: process.env.PORT
// }
})
const baseURL = 'https://www.example.com/'
let chatId = Number
let cityList = Array
let urlList = Array
let announces = Array
let type = String
let city = String
const regex = /[\[\],"]/
fs.readFile('city-list', { encoding: 'utf-8'}).then( (content) => {
let splittedContent = content.split(regex).filter( el => el.length > 0 )
cityList = splittedContent.map( el => {
let cbdata = `{"place":"${el.toLowerCase()}","command":"/place"}`
return [{text: el, callback_data: cbdata}]
})
})
fs.readFile('url-list', { encoding: 'utf-8' }).then( (content) => {
let splittedContent = content.split(regex).filter( el => el.length > 0 )
urlList = splittedContent.map( (el) => {
return el
})
})
bot.on('polling_error', err => console.log(err) )
/* */
bot.onText(/\/start/, async (message, match) => {
chatId = message.chat.id
await bot.sendMessage(chatId, `Hello ${message.chat.first_name}!What are you looking for?`, {
protect_content: true,
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [
[{text: 'IC', callback_data: '{"type":"ic","command":"/start"}'}],
[{text: 'WvM', callback_data: '{"type":"wvm","command":"/start"}'}],
[{text: 'MvM', callback_data: '{"type":"mvm","command":"/start"}'}],
[{text: 'C', callback_data: '{"type":"c","command":"/start"}'}]
]
}
})
})
bot.on('callback_query', (answer) => {
chatId = answer.message.chat.id
let data = JSON.parse(answer.data)
console.log(data)
bot.sendChatAction(chatId, 'typing')
if( data.command === '/start' ){
type = data.type
console.log(type)
bot.sendMessage(chatId, `You selected category ${data.type.split('-').join(' ')}. Available city list below`, {
protect_content: true
})
bot.sendChatAction(chatId, 'typing')
bot.sendMessage(chatId, `Select a city:`, {
protect_content: true,
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: cityList
}
})
bot.answerCallbackQuery(answer.id).then(console.log)
}
if( data.command === '/place' ){
city = data.place
console.log(city)
const searched = urlList.find( el => el.includes( city.toLowerCase() ) )
const url = new URL(searched)
const announcesURL = `https://${url.host}/${type}/`
console.log(searched ,searched.length, announcesURL)
puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox'
]
}).then( async (browser) => {
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation({
waitUntil: 'networkidle0'
})
await page.goto(announcesURL)
await page.waitForSelector('.bakecaincontri > #app > .alert > .btn')
await page.click('.bakecaincontri > #app > .alert > .btn')
await navigationPromise
await page.waitForSelector('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.click('#lightbox-vm18 > .modal-dialog > .modal-content > .modal-footer > .btn-primary')
await page.waitForSelector('#app > main > .container > .item-card')
await page.waitForSelector('.item-heading > .item-title > a')
announces = await page.$$eval('.item-heading > .item-title > a', (el) => {
return el.map( (item) => {
return {
title: item.innerHTML,
link: item.getAttribute('href')
}
})
})
await browser.close()
let responseMessage = `Available announces for ${city}:\n`;
announces.forEach( (announce, i) => {
responseMessage += `${i+1}) <a href="${announce.link}">${announce.title}</a>\n\n`
})
await bot.sendMessage(chatId, responseMessage, {
protect_content: true,
parse_mode: 'HTML',
disable_web_page_preview: true
})
await bot.sendChatAction(chatId, 'typing')
await bot.sendMessage(chatId, `Do you want an alert for ${city} ${type.split('-').join(' ')}?`, {
protect_content: true,
reply_markup: {
inline_keyboard: [
[{text: 'Yes', callback_data: '{"action":"subscribe","command":"/alert"}'}],
[{text: 'No', callback_data: '{"action":"ignore","command":"/alert"}'}]
]
}
})
})
bot.answerCallbackQuery(answer.id).then(console.log)
}
if(data.command === '/alert' && data.action === 'subscribe'){
let key = datastore.key(['bot_subscribers', `subscriber_${chatId}`])
let subscriber = {
key: key,
data: {
userID: chatId,
announces_category: type,
location: city
}
}
datastore.save(subscriber)
console.log(`subscriber_${chatId} saved into database!`)
bot.sendMessage(chatId, 'Alert activated!')
bot.answerCallbackQuery(answer.id).then(console.log)
}
if(data.command === '/alert' && data.action === 'ignore'){
console.log('notifiche ignorate')
bot.answerCallbackQuery(answer.id).then(console.log)
}
})
I want to setup a cron job that will run daily and that will load from the database all the available subscribers and send them a message. I'm using node-cron but I've noticed that the cron job will run only once also if I've set it for test to run every minute. How I can correctly shedule a daily cron job? Maybe the bot is blocking the cron execution?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
