Git Product home page Git Product logo

micro-bot's Introduction

logo

telegraf.js

Modern Telegram Bot API framework for Node.js

Bot API Version install size GitHub top language English chat

For 3.x users

Introduction

Bots are special Telegram accounts designed to handle messages automatically. Users can interact with bots by sending them command messages in private or group chats. These accounts serve as an interface for code running somewhere on your server.

Telegraf is a library that makes it simple for you to develop your own Telegram bots using JavaScript or TypeScript.

Features

Example

const { Telegraf } = require('telegraf')
const { message } = require('telegraf/filters')

const bot = new Telegraf(process.env.BOT_TOKEN)
bot.start((ctx) => ctx.reply('Welcome'))
bot.help((ctx) => ctx.reply('Send me a sticker'))
bot.on(message('sticker'), (ctx) => ctx.reply('👍'))
bot.hears('hi', (ctx) => ctx.reply('Hey there'))
bot.launch()

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'))
process.once('SIGTERM', () => bot.stop('SIGTERM'))
const { Telegraf } = require('telegraf')

const bot = new Telegraf(process.env.BOT_TOKEN)
bot.command('oldschool', (ctx) => ctx.reply('Hello'))
bot.command('hipster', Telegraf.reply('λ'))
bot.launch()

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'))
process.once('SIGTERM', () => bot.stop('SIGTERM'))

For additional bot examples see the new docs repo.

Resources

Getting started

Telegram token

To use the Telegram Bot API, you first have to get a bot account by chatting with BotFather.

BotFather will give you a token, something like 123456789:AbCdefGhIJKlmNoPQRsTUVwxyZ.

Installation

$ npm install telegraf

or

$ yarn add telegraf

or

$ pnpm add telegraf

Telegraf class

Telegraf instance represents your bot. It's responsible for obtaining updates and passing them to your handlers.

Start by listening to commands and launching your bot.

Context class

ctx you can see in every example is a Context instance. Telegraf creates one for each incoming update and passes it to your middleware. It contains the update, botInfo, and telegram for making arbitrary Bot API requests, as well as shorthand methods and getters.

This is probably the class you'll be using the most.

Shorthand methods

import { Telegraf } from 'telegraf'
import { message } from 'telegraf/filters'

const bot = new Telegraf(process.env.BOT_TOKEN)

bot.command('quit', async (ctx) => {
  // Explicit usage
  await ctx.telegram.leaveChat(ctx.message.chat.id)

  // Using context shortcut
  await ctx.leaveChat()
})

bot.on(message('text'), async (ctx) => {
  // Explicit usage
  await ctx.telegram.sendMessage(ctx.message.chat.id, `Hello ${ctx.state.role}`)

  // Using context shortcut
  await ctx.reply(`Hello ${ctx.state.role}`)
})

bot.on('callback_query', async (ctx) => {
  // Explicit usage
  await ctx.telegram.answerCbQuery(ctx.callbackQuery.id)

  // Using context shortcut
  await ctx.answerCbQuery()
})

bot.on('inline_query', async (ctx) => {
  const result = []
  // Explicit usage
  await ctx.telegram.answerInlineQuery(ctx.inlineQuery.id, result)

  // Using context shortcut
  await ctx.answerInlineQuery(result)
})

bot.launch()

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'))
process.once('SIGTERM', () => bot.stop('SIGTERM'))

Production

Webhooks

import { Telegraf } from "telegraf";
import { message } from 'telegraf/filters';

const bot = new Telegraf(token);

bot.on(message("text"), ctx => ctx.reply("Hello"));

// Start webhook via launch method (preferred)
bot.launch({
  webhook: {
    // Public domain for webhook; e.g.: example.com
    domain: webhookDomain,

    // Port to listen on; e.g.: 8080
    port: port,

    // Optional path to listen for.
    // `bot.secretPathComponent()` will be used by default
    path: webhookPath,

    // Optional secret to be sent back in a header for security.
    // e.g.: `crypto.randomBytes(64).toString("hex")`
    secretToken: randomAlphaNumericString,
  },
});

Use createWebhook() if you want to attach Telegraf to an existing http server.

import { createServer } from "http";

createServer(await bot.createWebhook({ domain: "example.com" })).listen(3000);
import { createServer } from "https";

createServer(tlsOptions, await bot.createWebhook({ domain: "example.com" })).listen(8443);

Error handling

If middleware throws an error or times out, Telegraf calls bot.handleError. If it rethrows, update source closes, and then the error is printed to console and process terminates. If it does not rethrow, the error is swallowed.

Default bot.handleError always rethrows. You can overwrite it using bot.catch if you need to.

⚠️ Swallowing unknown errors might leave the process in invalid state!

ℹ️ In production, systemd or pm2 can restart your bot if it exits for any reason.

Advanced topics

Working with files

Supported file sources:

  • Existing file_id
  • File path
  • Url
  • Buffer
  • ReadStream

Also, you can provide an optional name of a file as filename when you send the file.

bot.on('message', async (ctx) => {
  // resend existing file by file_id
  await ctx.replyWithSticker('123123jkbhj6b')

  // send file
  await ctx.replyWithVideo(Input.fromLocalFile('/path/to/video.mp4'))

  // send stream
  await ctx.replyWithVideo(
    Input.fromReadableStream(fs.createReadStream('/path/to/video.mp4'))
  )

  // send buffer
  await ctx.replyWithVoice(Input.fromBuffer(Buffer.alloc()))

  // send url via Telegram server
  await ctx.replyWithPhoto(Input.fromURL('https://picsum.photos/200/300/'))

  // pipe url content
  await ctx.replyWithPhoto(
    Input.fromURLStream('https://picsum.photos/200/300/?random', 'kitten.jpg')
  )
})

Middleware

In addition to ctx: Context, each middleware receives next: () => Promise<void>.

As in Koa and some other middleware-based libraries, await next() will call next middleware and wait for it to finish:

import { Telegraf } from 'telegraf';
import { message } from 'telegraf/filters';

const bot = new Telegraf(process.env.BOT_TOKEN);

bot.use(async (ctx, next) => {
  console.time(`Processing update ${ctx.update.update_id}`);
  await next() // runs next middleware
  // runs after next middleware finishes
  console.timeEnd(`Processing update ${ctx.update.update_id}`);
})

bot.on(message('text'), (ctx) => ctx.reply('Hello World'));
bot.launch();

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

With this simple ability, you can:

Usage with TypeScript

Telegraf is written in TypeScript and therefore ships with declaration files for the entire library. Moreover, it includes types for the complete Telegram API via the typegram package. While most types of Telegraf's API surface are self-explanatory, there's some notable things to keep in mind.

Extending Context

The exact shape of ctx can vary based on the installed middleware. Some custom middleware might register properties on the context object that Telegraf is not aware of. Consequently, you can change the type of ctx to fit your needs in order for you to have proper TypeScript types for your data. This is done through Generics:

import { Context, Telegraf } from 'telegraf'

// Define your own context type
interface MyContext extends Context {
  myProp?: string
  myOtherProp?: number
}

// Create your bot and tell it about your context type
const bot = new Telegraf<MyContext>('SECRET TOKEN')

// Register middleware and launch your bot as usual
bot.use((ctx, next) => {
  // Yay, `myProp` is now available here as `string | undefined`!
  ctx.myProp = ctx.chat?.first_name?.toUpperCase()
  return next()
})
// ...

micro-bot's People

Contributors

agudulin avatar dotcypress avatar mkrhere avatar shrynx avatar sogit avatar wojpawlik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

micro-bot's Issues

Vercel support

micro-bot is easily configurable with Now. Given that Vercel replaced Now, will you also update micro-bot accordingly?

Thanks!

μ-bot: Failed to start: Error: 404: Not Found

Whenever I try to run or deploy the bot y got the error "μ-bot: Failed to start: Error: 404: Not Found". I've been also trying using the examples but it gives me the same error. However this error only happens on windows environments because it works when I do it on Mac. Hope you guys can help me if there's a solution or if it just doesn't work on windows.

reply and replyWithMarkdown doesn't work in prod

I have quite an unusual bot behaviour. I have a simple bot which was scaffolded with create-bot/micro-bot. It listens for a few commands and does some API calls. It was working fine, and yesterday, but since this morning it stopped responding on the prod servers (now).

yarn dev work perfectly, everything as expected. When pushed to prod; bot doesn't respond to any reply or replyWithMarkdown. Yet I can see all console.log statements, logs in the now dashboard, database being updated, but still, no bot replies.

I'm genuinely confused, did someone came across this issue?

Some code examples:

  • now.json
{
  "version": 1
}
  • package.json(i'm using secrets to store bot token, and it worked very well yesterday)
"scripts": {
  "dev": "supervisor -x micro-bot index.js",
  "start": "micro-bot",
  "lint": "eslint .",
  "now-start": "micro-bot -d ${NOW_URL}",
  "now-deploy": "now -e BOT_TOKEN=@token_bot --public"
}
  • index.js
// Register "/start" command
bot.start(ctx => {
  const currentUsername = ctx.update.message.from.username;
  const chatId = ctx.update.message.chat.id;
  const formattedChatId = chatId.toString();

  let activeUsernames;

  if (currentUsername && formattedChatId) {
    // Query to target the correct document in the chats collection
    const chatInstance = db.collection("chats").doc(formattedChatId);

    // Read document data
    chatInstance
      .get()
      .then(doc => {
        if (!doc.exists) {
          // No such document with this formattedChatId
          // so we create a new chat record in db
          // and pass a currentUsername

          services.createNewChatRecord(chatInstance, currentUsername);
        } else {
          activeUsernames = doc.data().usernames;

          if (!activeUsernames.includes(currentUsername)) {
            // currentUsername is not included in the active username list
            // so we update the current record in db
            // and pass already activeUsernames list and currentUsername.

            services.updateUsernamesRecord(
              chatInstance,
              activeUsernames,
              currentUsername
            );
          }
        }
      })
      .then(() => {
        ctx.replyWithMarkdown(messages.INIT_START_COMMAND);
      })
      .catch(err => {
        ctx.replyWithMarkdown(messages.ERROR_MESSAGE);

        console.log("Error getting data", err);
      });
  }
});

Loading enviroment variables

Hi,

I was wondering how can I load the environment variables from a file using dotenv or any other package. This is because even though I load them before even requiring themicro-bot module, it won't let me:

μ-bot: Please supply Bot token

Is it possible to do this? I tried with the following code while having a .env file in the root directory with the BOT_TOKEN:

'use strict';

// Configure enviroment variables.
require('dotenv').config();

console.log(process.env.BOT_TOKEN);

// Telegraf based framework.
const { Composer } = require('micro-bot');
const app = new Composer();

Thanks.

fetching Bot info from telegram

Hi !
Thanks for making telegraf and micro bot, makes bot development extremely simple.
i have one issue, i am not sure how to get botInfo (the one from telegram.getInfo()).
I don't want to instantiate telegram again as it is automatically done by microbot.

It would be extremely helpful if i could access it from micro-bot.

const { Composer, botInfo } = require('micro-bot');

If this is valuable for you, i will try making a PR for it.

μ-bot: Failed to start: Error: 404: Not Found (Now 1.0, webhook)

I've been getting this error while trying to deploy to Now 1.0:

npm run now-start
> [email protected] now-start /home/nowuser/src
> micro-bot -t {BOT_TOKEN}

μ-bot: Failed to start: Error: 404: Not Found
More details: https://err.sh/now-cli/no-open-port-found
signal: 9

I've been trying to deploy a simple telegram bot. For debugging purposes, it just says "Hello" on start and some stuff on a "help" command. I'm using Now 1.0 and webhook.

What puzzles me is that it's not the first time developing with micro-bot (the previous time worked perfectly). Also used Webhook.

As per with my previous working bot, my start scripts are:

"scripts":{
    "now-start": "micro-bot -t {BOT_TOKEN}",
    "start": "now -e BOT_TOKEN=<api-key> --public"
}

I've tried using micro-bot -t {BOT_TOKEN} -d {NOW_URL} -p 3000 to force setup the webhook, but that didn't work either.

From the error thrown, it seems to be something to do with lack of listening to port, but since I'm using a webhook why is this still a problem?

Error: next(ctx) called with invalid context

Tried:

npm install micro-bot
npm init bot smart-bot
yarn create bot smart-bot
micro-bot -t TOKEN index.js

Bot started but got error:

Output:

Failed to fetch updates. Waiting: 1s request to https://api.telegram.org/tokenhere/getUpdates?offset=340740293&limit=100&timeout=30 failed, reason: connect ETIMEDOUT 149.154.167.220:443
μ-bot: Unhandled error Error: next(ctx) called with invalid context
    at execute (D:\dev\temp\rtumireaprofkombot\node_modules\telegraf\composer.js:301:33)
    at D:\dev\temp\rtumireaprofkombot\node_modules\telegraf\composer.js:298:14
    at execute (C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\composer.js:313:13)
    at Promise.resolve.handler (C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\composer.js:313:49)
    at C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\composer.js:114:56
    at execute (C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\composer.js:313:13)
    at C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\composer.js:298:14
    at Telegraf.handleUpdate (C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\telegraf.js:155:29)
    at Promise.all.updates.map (C:\Users\Фёдор\AppData\Roaming\npm\node_modules\micro-bot\node_modules\telegraf\telegraf.js:140:65)
    at Array.map (<anonymous>)

Connect to NOW

I create a simple Micro-Bot following the ReadMe,
I tried to deploy it using Now but I don't get it :
My Bot is deployed, I used now -e BOT_TOKEN='YOUR BOT TOKEN'
When I go to https://api.telegram.org/bot/getWebhookinfo I see this :
image

My bot in just not responding unless I type BOT_TOKEN='TOKEN' npm start how can I make it running without having to do this ?
Thanks for your help

Now Platform 2.0

The following warning is currently displayed during deployment:

WARN! You are using an old version of the Now Platform. More: https://zeit.co/docs/v1-upgrade

Do you plan to adapt the micro-bot for the new version of Now Platform?

Access Telegram API

Is it possible to access Telegram API such as bot.telegram.sendMessage via micro-bot?

Unable to start smart-bot from example in readme.md

Hi,
Thanks for making micro-bot, this looks like a really cool project! I am having some trouble getting it started, however.

I went through the readme.md instructions, but when I try to run the bot, the following happens:

$ BOT_TOKEN=<token> npm start

> [email protected] start /home/ubuntu/smart-bot
> micro-bot

μ-bot :: Starting @OpenFaasYoutubeBot
μ-bot: Failed to start bot: TypeError: function resolve() { [native code] } called on non-object
$ micro-bot -t <token> index.js 
micro-bot: command not found

my package.json looks like:

{
  "name": "smart-bot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "micro-bot"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "micro-bot": "^1.4.0"
  }
}

And this is deployed on a machine which is exposed to the internet, so the telegram API should be able to reach it.

Thanks in advance for any help!
-Eric

External endpoint to get my own webhooks

I'm using micro-bot as a backend to respond to some recurring updates coming from other nodejs service.

I like the abstraction that the micro-bot does with ssl certificates, should I not use it and instead use the integration of express.js with the telegraf directly?

file 4

Because the only thing I need is an external endpoint to get webhooks from another service, I wonder if any of this is possible by not adding a web server dependency or not.

Please shed some light.

startPolling is not a function

Hello!

Have tried to use
bot.startPolling()

however console returned that
TypeError: bot.startPolling is not a function

What am I doing wrong and how can I fix it?

Couldn't run on Now. No error and No result

Hello. I'm struggling with a micro-bot setup on Zeit Now and tried many different configs but get no result. I'm newbie on both Now and Telegraf, BTW I can run a simple echo web server on the same Now project but no success with bot code. It doesn't give any error when deploying and bot doesn't work at all. I don't know where I went wrong
This is all the code and files:

index.js: I used different codes such as this simple lines

const { mount, reply } = require('micro-bot')
module.exports = mount('sticker', reply('👍'))

packages.json

{
  "name": "mybot",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "micro-bot -t ${BOT_TOKEN} -d ${NOW_URL} index.js"
  },
  "dependencies": {
    "micro-bot": "^2.5.3"
  }
}

now.json

{
    "version": 2,
    "name": "mybot",
    "builds": [
        { "src": "*.js", "use": "@now/node" }
    ],
}

And my deploy command:

now -e BOT_TOKEN='828040278:AAG-NPbrdM5LkIUA1V5tbNxpA-yxemh5Cdc'

I don't know if the bot automatically sets Webhook, so I did it manually. https://api.telegram.org/botMYTOKEN/setWebhook?url=https://projecturl.me.now.sh

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.