Create Telegram Alerts with Cloudflare Workers and ScheduledEvent

Create Telegram Alerts with Cloudflare Workers and ScheduledEvent

Introduction

Motivations

Creating notifications on real events in the world is a very common scenario for developers.

Telegram Bot provides a convenient API for sending messages, enabling users to program cron jobs to monitor events of their interest and trigger push notifications without the knowledge of iOS or Android development.

There are many ways to host such cron jobs:

Running on a Raspberry Pi (or other forms of home server)

Home internet can face some stability issues such as internet connection. As recently as last Friday, Rogers experienced a Canada-wide outage affecting mobile and broadband users.

Electricity bills, or even a friend tripping over power cables (this happened to me), can also prevent you from building a reliable service.

Running on a cloud provider

Virtual machines from cloud providers can incur a non-trivial cost. The cheapest VPS hosting services can cost from $2.50 to $5.00 monthly. The CPUs on these machines could be almost idle since most cron jobs wait for network responses, which is wasteful.

In addition, using a static IP address for web scraping will likely trigger a CAPTCHA.

What makes Cloudflare Workers special

Cloudflare has a serverless edge computing platform called Workers.

It chose the V8 JavaScript engine built by the Google Chrome team instead of traditional virtualization and containerization technologies like Kubernetes and Docker to power a sandboxed multi-tenant execution environment.

The V8 engine introduced the concept of Isolates in 2011. An isolate is a VM instance with its own heap. A single process can run hundreds or thousands of Isolates. This saves tremendous overhead compared to containerized applications that occupy one process each.

image.png

As a result, Cloudflare is able to offer a free plan for Workers, where the first 100,000 requests per day are free.

What is even more incredible, Cron Triggers, which allows developers to run Workers on a schedule, are provided at no additional cost. This is because cron jobs are less sensitive to latency as no users are waiting for them to finish. This gives Cloudflare more flexibility on where and when to schedule the Cron Triggers.

Cloudflare is not the only company that utilizes V8 isolates for serverless computing. Deno Deploy and Vercel Edge Functions offer similar services, with minor differences in their runtime APIs.

Get Started

Create a Telegram bot

Creating a Telegram bot is as simple as sending /newbot to @BotFather.

You will get an authentication token by doing so. It is the only information you need to talk to the Telegram Bot API.

Find out your Telegram user ID

This blog post assumes that you only need to send notifications to yourself or a list of known users. If you want more complex interactions, check out these examples.

Your bot needs your user ID to send a message to you. This information can be retrieved by sending /start to @userinfobot.

Create a Cron Trigger

  1. Create a new Worker project called cron in the Cloudflare dashboard
  2. Under the Triggers tab, configure the interval that you want your Worker to execute, or use the cron syntax image.png

Configure credentials

Under Settings -> Variables, save your Telegram Bot token as TELEGRAM_BOT_TOKEN and your user id as TELEGRAM_CHAT_ID.

Hit Encrypt when you enter these values, they will no longer be viewable once saved. image.png

Write the code

  1. Click Quick Edit to open an online IDE to edit your Worker script image.png

  2. Create a sendMessage function. Your credentials can be accessed via global variables in the Worker script

    async function sendMessage(message) {
        const response = await fetch('https://api.telegram.org/bot' + TELEGRAM_BOT_TOKEN + '/sendMessage', {
            method: 'POST',
            headers: {  'Content-Type': 'application/json' },
            body: JSON.stringify({
                chat_id: TELEGRAM_CHAT_ID,
                text: message.toString().substring(0, 4096)
            })
        })
        return response
    }
    
  3. Use addEventListener to subscribe to the scheduled event. It will be invoked by the Workers runtime at a schedule you configured

    addEventListener('scheduled', event => {
        event.waitUntil(sendMessage("Hello, World!"))
    })
    
  4. You can trigger a scheduled event within the web editor. Your bot will send you a Hello, World! if everything is configured correctly image.png

Once you click Save and Deploy, the Worker will run on the schedule behind the scene.

Use the Fetch API from the Workers runtime to monitor interesting things on the internet. You can set up a stock alert, or send daily weather every day in the morning. The possibility is unlimited.

Notes

  1. Cron only has a 1-minute granularity. In other words, a Worker can only be triggered every minute at most.

    A workaround to this is to use setTimeout to schedule multiple events within a minute.

    For example, if you want to schedule a Worker to send a message every 30 seconds, start the Worker by sending a message, and do setTimeout(sendMessage, 30000) immediately after.

  2. If a Worker is managed with Wrangler, Cron Triggers should be exclusively managed through the wrangler.toml file.