Skip to content

Official Telegram bot πŸ€– of PowerKids Kindergarten. Handles communication to parents from the school.

Notifications You must be signed in to change notification settings

chuangcaleb/powerkids-telegram-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– PowerKids Bot

PowerKids Kindergarten logo

Official Telegram bot of PowerKids Kindergarten. Handles communication to parents from the school.

🎯 Goals

  • Admins/Teachers can send broadcast messages or weekly pictures (from the convenience of their own mobile devices) and select relevant student names
  • The bot will match the each selected student to their parents' Telegram account via the school's internal database
  • Parents will receive those pictures, sent by the bot, instantly notified by Telegram's mobile push notifications
  • Users can effortlessly authenticate their unique identity & role with deeplinks

βœ… Benefits

  1. No need for school staff to pass around a single company phone for communication
    • Parallel communication increases efficiency
    • School staff can handle their tasks according to their own schedule, not based on the common phone's availability
  2. Database replaces the manual record of parents' contacts to students' names
    • Enforces two-way anonymity and privacy because personal devices are obscured by the database layer,
    • Reduces chance for human error, sending message to the wrong parent
    • Centralizes single source of data
    • Ensures freshest data from database
  3. Instant push notifications on parents' mobile phones
    • Quicker time-to-notification
  4. Flexible target listing
    • Old system with WhatsApp was to either manually select contacts, or to send into a fixed group chat
    • Now, any custom combination of targets can be selected per-message

🏁 Usage

  1. Install Telegram on mobile or Web
  2. Enter your unique (deeplink) URL in your web browser, as provided by your Administrator
  3. As a parent, you will now automatically receive messages and pictures for your child(ren) by the school from the chatbot
  4. As a school staff, you can now use /sendmsg to write out a message/attach a picture, select students, and the parents of those selected students will receive your message.

🎨 Design

Auth Deeplink

telegram auth deeplink flowchart

Pre-generating the deeplinks

  • Administrators trigger manual Flow in Directus
    • Uses a custom Operation extension
  • Plaintext includes:
    • single-char prefix to identify between parent or admin auth
    • unique identifying field of the record
    • local secret (explained below)
  • Plaintext is encrypted for the payload, to prevent malicious users from authenticating
    • initialization vector, if exists, may be prefixed before the ciphertext in the payload
  • Stores deeplink into an auth_deeplinks field for each record
  • Administrator can distribute the deeplinks according to a CMS view or export with the necessary fields

Using deeplinks

  • Telegram has an inbuilt deeplink feature
  • We don't want bad actors to spam the /start route with random payloads, causing excessive CMS API calls and DB access
    • We use a LOCAL_SECRET, shared between Directus CMS and the Bot
    • When generating the deeplinks, we include the LOCAL_SECRET in the plaintext
    • Later, when the bot receives a deeplink payload, it can locally decrypt and validate the LOCAL_SECRET segment before ever calling the CMS API
    • Basically ensures that the deeplink payload is genuinely created by us, even if the other segments of the plaintext are invalid
  • Telegram's deeplinks only allow a base64url-charset & maximum 64-character payload
    • This severely limits the entropy of our payload, and thus limits the length of our plaintext
    • Have to be very economical to be able to derive a unique record and enforce tight security, while adhering to the 64-character payload limit
  • Invalidating deeplinks is just a matter of regenerating the LOCAL_SECRET value
    • This invalidates all deeplinks, globally
    • Current implementation has not enough entropy to fit Telegram's payload limitations while having a unique Initialization Vector field for each user, in order to invalidate a specific user's link β€” this is currently outside MVP, may be enhanced later

Note: This isn't the exact implementation, certain details are tweaked for obscurity purposely

Send Message

Process

  • Admin initiates the flow with /sendmsg command
    • Checks for admin status
  • Admin attaches a message or picture with caption
  • Admin selects a list of students
    • Bot communicates with the database to pull records of the parents' Telegram ID of the queried student
    • Bot gives error feedback if:
      • if query is not found in database
      • if student has no parents who have already registered
  • Admin sends /done to finish the input
  • The bot forwards the message to each target on the list
  • The bot returns feedback on the operation

Considerations

  • by simply forwarding the message, we don't need to store the message in memory
  • each child may have multiple parents, and each parent may have multiple children
    • when selecting a child, it should send to both parents
    • when selecting siblings, it should deduplicate calls

πŸ—οΈ Architecture / Tech Stack

system architecture

πŸ”§ Developing

Follow these steps to set up and run your bot using this template:

  1. Clone New Repository

  2. Environment Variables Setup

    Create an environment variables file by copying the provided example file:

    cp .env.example .env

    Open the newly created .env file and set the BOT_TOKEN environment variable.

  3. Launching the Bot

    You can run your bot in both development and production modes.

    Development Mode:

    Install the required dependencies:

    pnpm install

    Start the bot in watch mode (auto-reload when code changes):

    pnpm run dev

    Production Mode:

    Install only production dependencies (no development dependencies):

    pnpm install --only=prod

    Set the NODE_ENV environment variable to "production" in your .env file. Also, make sure to update BOT_WEBHOOK with the actual URL where your bot will receive updates.

    NODE_ENV=production
    BOT_WEBHOOK=<your_webhook_url>

    Start the bot in production mode:

    pnpm start
    # or
    pnpm run start:force # if you want to skip type checking

List of Available Commands

  • pnpm run lint β€” Lint source code.
  • pnpm run format β€” Format source code.
  • pnpm run typecheck β€” Run type checking.
  • pnpm run dev β€” Start the bot in development mode.
  • pnpm run start β€” Start the bot.
  • pnpm run start:force β€” Starts the bot without type checking.

Directory Structure

project-root/
  β”œβ”€β”€ api
  β”‚   └── server # Serverless entry point
  β”œβ”€β”€ locales # Localization files (currently unused)
  └── src
      β”œβ”€β”€ bot # Contains the code related to the bot
      β”‚   β”œβ”€β”€ callback-data # Callback data builders
      β”‚   β”œβ”€β”€ features      # Implementations of bot features
      β”‚   β”‚     └── (feature)
      β”‚   β”‚            β”œβ”€β”€ composer.ts # entry point for the directory
      β”‚   β”‚            └── conversation.ts # conversation handler
      β”‚   β”œβ”€β”€ handlers      # Update handlers
      β”‚   β”œβ”€β”€ helpers       # Utility functions
      β”‚   β”œβ”€β”€ keyboards     # Keyboard builders (currently unused)
      β”‚   β”œβ”€β”€ middlewares   # Middleware functions
      β”‚   β”œβ”€β”€ i18n.ts       # Internationalization setup
      β”‚   β”œβ”€β”€ context.ts    # Context object definition
      β”‚   └── index.ts      # Bot entry point
      β”‚
      β”œβ”€β”€ server # Contains the code related to the web server
      β”‚   └── index.ts # Web server entry point
      β”œβ”€β”€ lib    # Utility modules
      β”‚   β”œβ”€β”€ directus # Directus SDK abstractions
      β”‚   └── *        # Whatever other utility modules
      β”œβ”€β”€ config.ts # Application config
      β”œβ”€β”€ logger.ts # Logging setup
      └── main.ts   # Application entry point (local)

Environment Variables

Variable Type Description
NODE_ENV String Specifies the application environment. (development or production)
BOT_TOKEN String Telegram Bot API token obtained from @BotFather.
LOG_LEVEL String Optional. Specifies the application log level.
For example, use info for general logging. View the Pino documentation for more log level options.
Defaults to info.
BOT_MODE String Optional. Specifies method to receive incoming updates. (polling or webhook) Defaults to polling. (You should use webhook in production environment)
BOT_WEBHOOK String Optional in polling mode. Webhook endpoint URL, used to configure webhook in production environment.
BOT_SERVER_HOST String Optional. Specifies the server hostname.
Defaults to 0.0.0.0.
BOT_SERVER_PORT Number Optional. Specifies the server port.
Defaults to 80.
BOT_ALLOWED_UPDATES Array of String Optional. A JSON-serialized list of the update types you want your bot to receive. See Update for a complete list of available update types.
Defaults to an empty array (all update types except chat_member).
DIRECTUS_STATIC_TOKEN String Static token from the Telegram dummy user in Directus, configured with appropriate limited permissions
DIRECTUS_URL String Public base URL to access the Directus API
ENCRYPTION_METHOD String An algorithm from Web Cryptography API: SubtleCrypt supported algorithms
ENCRYPTION_KEY String Shared decryption key between bot and CMS to decode deeplink payloads
LOCAL_SECRET String Shared secret between bot and CMS to validate deeplink payloads (locally)

πŸ—ΊοΈ Future Work

  1. Select a group of students with a filter defined in Directus Presets
  2. Screening system for principals to vet quality of messages before they go out
  3. Send more than one message, a series of messages
  4. Accountability logs in CMS
    • messages sent out
    • error logs

About

Official Telegram bot πŸ€– of PowerKids Kindergarten. Handles communication to parents from the school.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published