Nighttime Possum Meandering

    telegram-bot-api-c

    19.5.0 • Public • Published

    Codacy NodeSecurity

    npm -g install telegram-bot-api-c
    git clone https://github.com/Daeren/telegram-bot-api-c.git
    
    require("telegram-bot-api-c").call("TK", "sendMessage", [0, "+"])
    require("telegram-bot-api-c")("TK").api.sendMessage({chat_id: 0, text: "+"})
    require("telegram-bot-api-c")("TK").polling(bot => bot.answer().html("+").send())
    > tg-bot --token TK --method sendMessage --chat_id 0 --text "+"

    Telegram Bot API, Bot API 2.x, Bot API 3.5

    • Proxy: +
    • Array and Map as a data source (.call, .callJson, .api[method]): +
    • Analytics: tgb-pl-botanio
    • Added: tgBot.api[sendMethod] => error.retryAfter
    • Added: sendMediaGroup (doesn't support "attach://")
    - All methods in the Bot API are case-insensitive (method: .call, .callJson)
    
    - message:                                             buffer, stream, string
    - location|venue|contact:                              buffer, string
    - photo|audio|voice|video|document|sticker|video_note: buffer, stream, file_id, path, url
    - certificate:                                         buffer, stream, path, url
    

    Goals:

    1. High stability;
    2. Low memory usage;
    3. Maximum performance;
    4. Flexibility.

    Index

    architecture

    const rTgBot    = require("telegram-bot-api-c");
     
    const gBot      = rTgBot(process.env.TELEGRAM_BOT_TOKEN),
          gApi      = gBot.api;
     
    //----------------------------]>
     
    gBot.promise(require("bluebird"));
     
    //----------------------------]>
     
    gApi
        .sendMessage(["0", "Hi"])
        .then(console.info, console.error);
        
    gApi.sendMessage(["0", "Hi"], (e, data) => console.log(|| data));
     
    // e    - Error: request/JSON.parse/response.ok
    // data - JSON: response.result or null
     
    //-------]>
     
    gBot.callJson("sendMessage", ["0", "Hi"], (e, data, res) => console.log(|| data));
     
    // e    - Error: request/JSON.parse
    // data - JSON: response or null
    // res  - Class: http.IncomingMessage or null
     
    //-------]>
     
    gBot.call("sendMessage", ["0", "Hi"], (e, data, res) => console.log(|| data));
     
    // e    - Error: request
    // data - Buffer: response or null
    // res  - Class: http.IncomingMessage or null
     
    //------------]>
     
    /*
      e.code           - gApi.sendMessage( ...
      data.error_code  - callJson("sendMessage" ...
     
      rTgBot or gBot
     
      gBot.ERR_INTERNAL_SERVER
      gBot.ERR_NOT_FOUND
      gBot.ERR_FORBIDDEN
      gBot.ERR_MESSAGE_LIMITS
      gBot.ERR_USED_WEBHOOK
      gBot.ERR_INVALID_TOKEN
     
      gBot.ERR_BAD_REQUEST
      gBot.ERR_BAD_PROXY
      gBot.ERR_FAILED_PARSE_DATA
    */
     
    //----------------------------]>
     
    gBot
        .polling(onDefault)
        .catch(onError)
        
        .use(bot => "syncGotoMyMenu")
        .use((bot, data, next) => next(new Error("never get")))
        .use("/start", bot => { })
     
        .on("/start", onCmdStart_1)
        .on("/start", onCmdStart_2)
        .on("/start", onCmdStart_3)
     
        .on("enterChat", onEnterChat)
        .on("text:syncGotoMyMenu", onText)
        .on("photo document", onPhotoOrDoc)
        .on("pinnedMessage", onPinnedMessage)
     
        .on(/^id\s+(\d+)/i, onTextRegEx)
        .on(/^(id)\s+(\d+)/i, "type id", onTextRegEx)
        .on(/^(login)\s+(\w+)/i, ["type", "login"], onTextRegEx);
     
     
    function onDefault(bot) { }
    function onError(error) { }
     
    function onCmdStart_1(bot, params, next) { next(); } // <-- Async
    function onCmdStart_2(bot, params) { }               // <-- Sync
    function onCmdStart_3(bot, params) { }               // <-- Sync | end
     
    function onEnterChat(bot, member) { }
    function onText(bot, text) { }
    function onPhotoOrDoc(bot, data) { }
    function onPinnedMessage(bot, message) { }
     
    function onTextRegEx(bot, data) { }
     
    //-----------]>
     
    /*
      bot                               | gBot -> Sugar -> CtxPerRequest
      bot instanceof gBot.constructor   | true
      
      bot.command.type                  | common or private
      
      /start [text]         -> common
      /start@bot [text]     -> private
      @bot /start [text]    -> private
    */

    Proxy

    const gBot      = rBot(process.env.TELEGRAM_BOT_TOKEN);
     
    const gProxyStr = "127.0.0.1:1337", // <-- Only HTTPS
          gProxyArr = ["127.0.0.1", "1337"],
          gProxyObj = {
              "host": "127.0.0.1",
              "port": 1337
          };
     
    //------------------]>
     
    function getMe(callback) { gBot.api.getMe(callback); }
     
    //------------------]>
     
    gBot.proxy(gProxyObj);
     
    getMe(t => {
        objBot.proxy(gProxyStr);
     
        getMe(t => {
            objBot.proxy(); // <-- Remove
            getMe();
        });
    });
     
    rBot.callJson({
        "token":    process.env.TELEGRAM_BOT_TOKEN,
        "method":   "getMe",
        "proxy":    gProxyArr
    }, (e, d) => {});
     
    rBot.callJson(process.env.TELEGRAM_BOT_TOKEN, "getMe", (e, d) => {}, gProxyObj);

    Polling

    const gBot      = rBot(process.env.TELEGRAM_BOT_TOKEN);
     
    const gOptions  = {
        "limit":    100,
        "timeout":  0,
        "interval": 2 // <-- Default / Sec.
    };
     
    //------------------]>
     
    const gSrv = gBot
        .polling(gOptions, onMsg)
        .on("/stop", onCmdStop);
        
    //------------------]>
     
    function onMsg(bot) {
        const msg = bot.isGroup && bot.isReply ? ">_>" : "Stop me: /stop";
        bot.answer().isReply().text(msg).send();
    }
     
    function onCmdStop(bot, params) {
        gSrv.stop();
        bot.answer().text(JSON.stringify(params)).send();
    }

    HTTP

    const rBot = require("telegram-bot-api-c");
     
    //-----------------------------------------------------
     
    const gSrvOptions   = {
        // For Self-signed certificate, you need to upload your public key certificate
        // "selfSigned":  "fullPath/stream/buffer",  // <-- If you use Auto-Webhook
     
        "certDir":  "/www/site",
     
        "key":       "/3_site.xx.key",
        "cert":      "/2_site.xx.crt",
        "ca":       [
            "/AddTrustExternalCARoot.crt",
            "/COMODORSAAddTrustCA.crt",
            "/COMODORSADomainValidationSecureServerCA.crt"
        ],
     
        "host":     "site.xx"
    };
     
    //------------------]>
     
    const gBotFather    = rBot();
     
    const gMyBot        = rBot(process.env.TG_BOT_TOKEN_MY),
          gOtherBot     = rBot(process.env.TG_BOT_TOKEN_OTHER);
     
    const gSrv          = gBotFather.http(gSrvOptions);
     
    gSrv
        .bot(gMyBot)                                    // <-- Auto-Webhook: "/tg_bot_<sha256(token)>"
        .on("/start", onCmdStart)
        .on("/stop", onCmdStop);
     
    gSrv
        .bot(gOtherBot, "/urlOtherBot", onMsgOtherBot); // <-- Auto-Webhook
        
    //------------------]>
     
    function onMsgOtherBot(bot) { }
     
    function onCmdStart(bot, params) { }
    function onCmdStop(bot, params) { }

    Virtual

    const gBot = rBot(process.env.TELEGRAM_BOT_TOKEN);
     
    const gSrv = gBot
        .virtual(function(bot) {
            bot.answer().text("Not found!").send();
        })
        .on("photo", console.log);
     
    //----[Proxy: express]----}>
     
    gBot
        .api
        .setWebhook({"url": "https://site.xx/dev-bot"})
        .then(function(isOk) {
            const rExpress      = require("express"),
                  rBodyParser   = require("body-parser");
     
            rExpress()
                .use(rBodyParser.json())
                .post("/dev-bot", gSrv.middleware)
                .listen(3000, "localhost");
        });
        
    //----[Stress Tests]----}>
     
    gSrv.input(null, {
        "update_id": 0,
        "message": {
            "message_id": 0,
     
            "from": {
                "id": 0,
                "first_name": "D",
                "username": ""
            },
     
            "chat": {
                "id": 0,
                "first_name": "D",
                "username": "",
                "type": "private"
            },
     
            "date": 0,
            "text": "Hello"
        }
    });

    mServer

    const gBot = rBot(process.env.TELEGRAM_BOT_TOKEN);
     
    gBot
        .api
        .setWebhook({"url": "https://site.xx/myBot"})
        .then(function(isOk) {
            if(!isOk) {
                throw new Error("Oops...problem with the webhook...");
            }
     
            gBot.http(gSrvOptions, cbMsg);
        });

    NGINX + Node.js

    const gBot          = rBot();
    const gSrvOptions   = {
        "ssl":          false,
     
        "autoWebhook":  "site.xx:88", // <-- Default: (host + port); `false` - disable
     
        "host":         "localhost",
        "port":         1490
    };
     
    gBot.http(gSrvOptions, onMsg);
     
    //----[DEFAULT]----}>
     
    gBot.http();
    gBot.http(onMsg);
     
    // host: localhost
    // port: 1488
    // autoWebhook: false
    // ssl: false

    Response Builder

    objSrv
        .use(function(bot) {
            bot
                .answer() // <-- Builder + Queue
     
                .chatAction("typing") // <-- Element
     
                .text("https://google.com", "markdown") // <-- Element
                //.parseMode("markdown")
                .disableWebPagePreview() // <-- Modifier (for the last element)
                .keyboard([["X"], ["Y"]]) // <-- Modifier
                
                .markdown("*text*") // <-- Element
                .html("<a>text</a>")
     
                .chatAction("upload_photo")
                
                .photo("https://www.google.ru/images/logos/ps_logo2.png", "myCaption")
                .caption("#2EASY") // <-- Modifier
                .keyboard("old")
                .keyboard("new", "selective") // <-- Uses: bot.mid (selective)
     
                .location(69, 96)
                .latitude(13)
                .keyboard() // <-- Hide
     
                .send() // <-- Uses: bot.cid
     
                .then(console.log);  // <-- Return: array | results
            
            //------[ONE ELEMENT]------}>
            
            const customKb = {
                "keyboard":         [["1"], ["2"], ["3"]],
                "resize_keyboard":  true
            };
     
            bot
                .answer()
                .text("Hi")
                .keyboard(customKb)
                .send((e, r) => console.log(|| r));  // <-- Return: hashTable | result
     
            //------[RENDER]------}>
            
            const template = "Hi, {name}!";
            const buttons = [["{btnMenu}", "{btnOptions}"]];
            const input = {
                "name":         "MiElPotato",
     
                "btnMenu":      "Menu +",
                "btnOptions":   "Options"
            };
     
            bot
                .answer()
                .text(template)
                .keyboard(buttons, "resize")
                .render(input) // <-- text + keyboard
                .send();
                
            bot
                .answer()
                .text("Msg: {0} + {1}")
                .render(["H", "i"]) // <-- text
                .keyboard([["X: {0}", "Y: {1}"]])
                .send();
        });
    Name Args
    -
    html text, disable_web_page_preview, disable_notification, reply_to_message_id, reply_markup
    markdown text, disable_web_page_preview, disable_notification, reply_to_message_id, reply_markup
    -
    text text, parse_mode, disable_web_page_preview, disable_notification, reply_to_message_id, reply_markup
    photo photo, caption, disable_notification, reply_to_message_id, reply_markup
    audio audio, performer, title, duration, caption, disable_notification, reply_to_message_id, reply_markup
    document document, caption, disable_notification, reply_to_message_id, reply_markup
    sticker sticker, disable_notification, reply_to_message_id, reply_markup
    video video, width, height, duration, caption, disable_notification, reply_to_message_id, reply_markup
    voice voice, duration, caption, disable_notification, reply_to_message_id, reply_markup
    videoNote videoNote, duration, length, disable_notification, reply_to_message_id, reply_markup
    location latitude, longitude, disable_notification, reply_to_message_id, reply_markup
    venue latitude, longitude, title, address, foursquare_id, disable_notification, reply_to_message_id, reply_markup
    contact phone_number, first_name, last_name, disable_notification, reply_to_message_id, reply_markup
    chatAction action
    game game_short_name, disable_notification, reply_to_message_id, reply_markup
    invoice title ... ... reply_markup
    -
    inlineQuery results, next_offset, is_personal, cache_time, switch_pm_text, switch_pm_parameter
    callbackQuery text, show_alert
    shippingQuery ok, shipping_options, error_message
    preCheckoutQuery ok, error_message

    Tg Upload

    gBot.enable("tgUrlUpload");
     
    gBot
        .polling()
        .on("text", function(bot, url) {
            bot.answer().photo(url).send();
        });
        
    /*
    Added the option to specify an HTTP URL for a file in all methods where InputFile or file_id can be used (except voice messages).
    Telegram will get the file from the specified URL and send it to the user.
    Files must be smaller than 5 MB for photos and smaller than 20 MB for all other types of content.
    */

    Plugin

    gSrv
        .use(function(bot, data, next) {
            console.log("Async | Type: any");
     
            if(data === "next") {
                next();
            }
        })
        .use("text", function(bot) {
            console.log("F:Sync | Type: text");
     
            bot.user = {};
        })
        .use(function(bot) {
            bot.user.id = 1;
        });
        
    gSrv
        .on("text", function(bot, data) {
            bot.user.id;
        });

    Goto

    gSrv
        .use(function(bot, data, next) {
            next(data === "room" ? "room.menu" : "");
        })
        .use(function(bot) {
            console.log("If not the room");
            
            // return "room.menu";
        })
        
        .on("text", function(bot, data) { })
        .on("text:room.menu", function(bot, data) { });

    JS Generators

    gBot
        .polling(function* (bot) {
            const result = yield send(bot);
            console.info(result);
     
            yield error();
        })
        .catch(function* (error) {
            console.error(error);
        })
        
        .use(function* (bot) {
            yield auth("D", "13");
        })
        .use("text", function* (bot, data) {
            yield save();
     
            if(data === "key") {
                return "eventYield";
            }
        })
     
        .on("text:eventYield", function* (bot, data) {
            console.log("eventYield:", data);
        });
     
    //----------------]>
     
    function auth(login, password) {
        return new Promise(x => setTimeout(x, 1000));
    }
     
    function send(bot) {
        return bot.answer().text("Ok, let's go...").send();
    }

    Render

    //-----[EJS]-----}>
     
    gBot.engine(require("ejs"))
     
    data = {"x": "H", "y": "i"};
    bot.render("EJS | Text: <%= x %> + <%= y %>", data);
     
    //-----[DEFAULT]-----}>
     
    data = ["H", "i"];
    bot.render("Array | Text: {0} + {1}", data);
     
    data = {"x": "H", "y": "i"};
    bot.render("Hashtable | Text: {x} + {y}", data);

    Keyboard

    const rBot = require("telegram-bot-api-c");
     
    function onMsg(bot) {
        const data = {};
        
        data.chat_id = bot.cid;
        data.text = "Hell Word!";
        
        data.reply_markup = bot.keyboard(); // Or: bot.keyboard.hide()
        data.reply_markup = bot.keyboard([["1", "2"], ["3"]]);
        
        data.reply_markup = bot.keyboard.hOx();
        data.reply_markup = bot.keyboard.inline.hOx();
        
        bot.api.sendMessage(data);
    }
     
    rBot.keyboard.numpad(true); // <-- Once
    rBot.keyboard.numpad(false, true); // <-- Selective
     
    rBot.keyboard.inline.numpad();
     
    //------------------------------
     
    rBot.keyboard(buttons[, params])
    rBot.keyboard.inline(inlButtons, isVertically)
     
    /*
      buttons:    `string`, `array of array` or `false`
      inlButtons: `string`, `array of array` or `object`
      params:     "resize once selective"
      
      v - vertically; h - horizontally;
      
      vOx, hOx, vPn, hPn, vLr, hLr, vGb, hGb
      abcd, numpad, hide
      
      Normal keyboard:
       vOx(once, selective)
       numpad(once, selective)
    */
    Name Note
    -
    _Ox O / X
    _Pn + / -
    _Ud Upwards / Downwards arrow
    _Lr Leftwards / Rightwards arrow
    _Gb Like / Dislike
    -
    abcd ABCD
    numpad 0-9
    -
    hide

    Download

    gBot.download("file_id", "dir"/*, callback*/);
    gBot.download("file_id", "dir", "name.mp3"/*, callback*/);
     
     
    gBot
        .download("file_id")
        .then(function(info) {
            info.stream.pipe(require("fs").createWriteStream("./" + info.name));
        });
     
     
    gBot
        .download("file_id", function(error, info) {
            info.stream.pipe(require("fs").createWriteStream("./myFile"));
        });

    InlineQuery

    https://core.telegram.org/bots/inline

    gBot
        .polling()
        .on("inlineQuery", function(bot, data) {
            const idx = Date.now().toString(32) + Math.random().toString(24);
            const results = [
                {
                    "type":         "article",
                    "title":        "Title #1",
                    "message_text": "Text...",
     
                    "thumb_url":    "https://pp.vk.me/c627530/v627530230/2fce2/PF9loxF4ick.jpg"
                },
     
                {
                    "type":         "article",
                    "title":        "Title #2: " + data.query,
                    "message_text": "Text...yeah"
                },
     
                {
                    "type":         "photo",
     
                    "photo_width":  128,
                    "photo_height": 128,
     
                    "photo_url":    "https://pp.vk.me/c627530/v627530230/2fce2/PF9loxF4ick.jpg",
                    "thumb_url":    "https://pp.vk.me/c627530/v627530230/2fce2/PF9loxF4ick.jpg"
                }
            ]
                .map((t, i) => { t.id = idx + i; return t; });
     
            // results = {results};
     
            bot
                .answer()
                .inlineQuery(results)
                .send()
                .then(console.info, console.error);
        });
     
    //------------]>
     
    bot
        .api
        .answerInlineQuery({
            "inline_query_id": 0,
            "results":         results
        })
        .then(console.info, console.error);

    Send file as Buffer

     
    const imgBuffer = require("fs").readFileSync(__dirname + "/MiElPotato.jpg");
     
    //------------]>
     
    objSrv
        .use(function(bot, next) {
            bot
                .answer()
                .photo(imgBuffer)
                .filename("MiElPotato.jpg") // <-- It is important
                .filename("/path/MiElPotato.jpg") // <-- Same as above
                .send();
        });
        
    //------------]>
     
    api.sendPhoto({
        "chat_id":      0,
        "photo":        imgBuffer,
     
        "filename":      "MiElPotato.jpg" // <-- It is important
    });
     
    api.sendDocument({
        "chat_id":      0,
        "document":     imgBuffer
    });

    CLI

    Key Note
    -
    -j insert white space into the output JSON string for readability purposes
    -
    --token high priority
    --method high priority
    --proxy "ip:port"
    // Environment variables: low priority
     
    > set TELEGRAM_BOT_TOKEN=X
    > set TELEGRAM_BOT_METHOD=X
    > set TELEGRAM_BOT_PROXY=X
     
    ...
     
    > tg-bot --token X --method sendMessage --key val -bool
    > node telegram-bot-api---token X --method sendMessage --key val -bool
     
    ...
     
    > tg-bot --token X --method sendMessage --chat_id 0 --text "Hi" -disable_web_page_preview
    > tg-bot --token X --method sendMessage < "./examples/msg.json"
     
    > tg-bot --token X --method sendPhoto --chat_id 0 --photo "/path/MiElPotato.jpg"
    > tg-bot --token X --method sendPhoto --chat_id 0 --photo "https://www.google.ru/images/logos/ps_logo2.png"
     
    ...
     
    > tg-bot
    > {"token": "", "method": "sendMessage", "chat_id": 0, "text": "1"}
    > <enter>
     
    (result)
     
    > {"chat_id": 0, "text": "2", "j": true, "proxy": "ip:port"}
    > <enter>
     
    (result)

    Test

    npm -g install mocha
    npm install chai
     
    set TELEGRAM_BOT_TOKEN=X
    set TELEGRAM_CHAT_ID=X
    set TELEGRAM_MSG_ID=X
     
    cd <module>
     
    npm test

    npm test

    Module

    Method Arguments Note
    -
    keyboard buttons[, params] return: object; buttons: string/array; params: "resize once selective"
    parseCmd text[, strict] return: {type, name, text, cmd}; strict: maxLen32 + alphanum + underscore
    -
    call token, method[, data][, callback(error, buffer, response)][, proxy][, tgUrlUpload]
    call options{token, method, proxy, tgUrlUpload}[, data][, callback]
    callJson token, method[, data][, callback(error, json, response)][, proxy][, tgUrlUpload]
    callJson options{token, method, proxy, tgUrlUpload}[, data][, callback]

    Instance

    Attribute Type Note
    -
    api object See Telegram Bot API
    -
    keyboard function
    parseCmd function
    Method Arguments Return
    -
    -
    enable key this
    disable key this
    enabled key true/false
    disabled key true/false
    -
    engine instance this
    promise instance this
    token [token] this or token
    proxy [proxy] this
    -
    call method[, data][, callback(error, buffer, response)]
    callJson method[, data][, callback(error, json, response)]
    -
    render template, data string
    download fid[, dir][, name][, callback(error, info {id,size,file,stream})] promise or undefined
    -
    http [options][, callback(bot, cmd)] object
    polling [options][, callback(bot, cmd)] object
    virtual [callback(bot, cmd)] object

    Methods: Response Builder

    Name Args Note
    -
    inlineQuery (results)
    callbackQuery ([message])
    -
    render (data)
    keyboard (buttons[, params])
    inlineKeyboard (buttons[, isVertically])
    -
    isReply ([flag])
    send ([callback])
    -
    text
    photo Ext: jpg, jpeg, gif, tif, png, bmp
    audio Ext: mp3
    document
    sticker Ext: webp [, jpg, jpeg, gif, tif, png, bmp]
    video Ext: mp4
    voice Ext: ogg
    location
    venue
    contact
    chatAction
    game

    Methods: Server

    Name Arguments Return
    -
    POLLING
    -
    start this
    stop this
    HTTP
    -
    bot bot[, path][, onMsg(json, request)] new srvInstance
    -
    VIRTUAL
    -
    input error, data
    middleware
    -
    ALL
    -
    catch callback(error) this
    use [type], [params], callback(bot[, data, next]) this
    on type[, params], callback(data, params[, next]) this
    off [type][, callback] this

    Fields: bot | srv.on('', bot => 0)

    Name Type Note
    -
    isGroup boolean bot.isGroup = bot.message.chat.type === [super]group
    isReply boolean bot.isReply = !!bot.message.reply_to_message
    -
    cid number bot.cid = bot.message.chat.id
    mid number bot.mid = bot.message.message_id
    qid string bot.qid = bot.inlineQuery.id
    cqid string bot.cqid = bot.callbackQuery.id
    sid string bot.sid = bot.shipping_query.id
    pqid string bot.pqid = bot.pre_checkout_query.id
    -
    command object Incoming command
    -
    updateType string
    updateSubType string
    eventType string
    eventSubType string
    gotoState string
    -
    from object Persistent
    -
    message object Incoming message
    inlineQuery object Incoming inline query
    chosenInlineResult object The result of an inline query that was chosen
    callbackQuery object Incoming callback query
    -
    answer function() Response Builder; message; Uses: cid, mid
    answer function() Response Builder; inlineQuery; Uses: qid
    answer function() Response Builder; callbackQuery; Uses: cqid

    Events: use / on

    Name Args Note
    -
    message bot, message[, next]
    editedMessage bot, message[, next]
    -
    channelPost bot, post[, next]
    editedChannelPost bot, post[, next]
    -
    inlineQuery bot, data[, next]
    chosenInlineResult bot, data[, next]
    callbackQuery bot, data[, next]
    -
    pinnedMessage bot, message[, next]
    -
    invoice bot, data[, next]
    successfulPayment bot, data[, next]
    -
    enterChat bot, data[, next]
    leftChat bot, data[, next]
    -
    chatTitle bot, data[, next]
    chatNewPhoto bot, data[, next]
    chatDeletePhoto bot, data[, next]
    -
    chatCreated bot, data[, next]
    superChatCreated bot, data[, next]
    channelChatCreated bot, data[, next]
    -
    migrateToChatId bot, data[, next]
    migrateFromChatId bot, data[, next]
    -
    text bot, data[, next]
    photo bot, data[, next]
    audio bot, data[, next]
    document bot, data[, next]
    sticker bot, data[, next]
    video bot, data[, next]
    voice bot, data[, next]
    videoNote bot, data[, next]
    location bot, data[, next]
    venue bot, data[, next]
    contact bot, data[, next]
    game bot, data[, next]
    -
    * bot, data[, next]
    /[name] bot, params[, next] CMD
    -
    (regexp) bot, params[, next]

    License

    MIT


    @ Daeren @ Telegram

    Install

    npm i telegram-bot-api-c

    Homepage

    666.io

    DownloadsWeekly Downloads

    141

    Version

    19.5.0

    License

    MIT

    Last publish

    Collaborators

    • daeren