Coder Social home page Coder Social logo

slimbot's Introduction

Build Status Coverage Status MIT licensed

Slimbot

A fuss-free, thin wrapper around Telegram Bot API for Node.js. No frills.

Updated for Telegram Bot API 5.1. Works with Node 15.12.0. Runs on latest Node version 15.12.0. Tested on 10.16.0 and 12.10.0 as well.

Note: Slimbot patch versions (e.g. x.y.Z) do not track or reflect Telegram Bot API changes.

Resources

Getting started

npm i slimbot
const Slimbot = require('slimbot');
const slimbot = new Slimbot('123456789:AA...');

// Register listeners

slimbot.on('message', message => {
  slimbot.sendMessage(message.chat.id, 'Message received');
});

// Call API

slimbot.startPolling();

Now go ahead and type a message to your bot in Telegram. It should reply you with 'Message received' in the chat. Check out all other events you can listen to in the wiki.

How it works

All methods return a promise. This means you can inspect the returned objects if you want to:

slimbot.sendMessage('123456789', 'Message received')
  .then(message => {
    console.log(message);
  });

In this case, the sendMessage method returns a Message object as stated in the documentation.

You can also use callbacks instead of promises:

const Slimbot = require('./src/slimbot');
const slimbot = new Slimbot(process.env['TELEGRAM_BOT_TOKEN']);

function callback(err, obj) {
  if (err) {
    // handle error
    console.log(err);
  }
  // handle returned object
  console.log(obj);
};

slimbot.on('message', message => {
  slimbot.sendMessage(message.chat.id, 'Message received', callback);
});

slimbot.startPolling(callback);

Examples

Documentation (Wiki)

Learn more about the implementation details in the Wiki. Feel free to contribute to the Wiki or add more examples.

Contributing

Heartfelt thanks to the following folks for making Slimbot better: @lgg @ago @rpaskin @matteocontrini @jakimenko @nahanil

The guiding principle for this library is to be as simple as possible. I put serious thought into adding features to guard against bloat. Nonetheless, I am very open to dialogue and contributions are most welcome.

If you have built a public bot using this library, send me a PM and I'll feature it here.

slimbot's People

Contributors

ago avatar edisonchee avatar jakimenko avatar lgg avatar matteocontrini avatar maxhq avatar nahanil avatar rpaskin 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

slimbot's Issues

package.json "engine" constraint breaks yarn

Heya

Just noticed that yarn will die with the following when trying to install with node 12/13 as ^10.x.x only matches major version 10. npm doesn't seem to care.

error [email protected]: The engine "node" is incompatible with this module. Expected version "^10.16.0". Got "13.10.1"
error Found incompatible module.

I think >=10.x.x could do the business

Error: Please provide a Telegram Bot Token when instantiating

So.. I've added the first sample code. I've requested the Telegram Bot API Key via the BotFather and added it in there. Now I get the error:
Error: Please provide a Telegram Bot Token when instantiating

My Key looks like:

123456789:Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op8Qr9

I'm using Node v8.1.2

Nothing found in the web
1
2
PS: Anyway you whole project looks good

Slimbot support commands ?

Sorry my english not well.
Does slimbot support commands feature ?
I can't find that in slimbot documents.

sendMessage within other chat bot

Hi,

Can I run slimbot.sendMessage alone? Does slimbot.sendMessage need the slimbot.startPolling(); to be working? Ref:
https://github.com/edisonchee/slimbot/wiki#getting-started

For e.g., I have this simple script:

const Slimbot = require('slimbot');
const slimbot = new Slimbot(process.env['TELEGRAM_BOT_TOKEN']);
const chatID = process.env['TELEGRAM_CHAT_ID'];

slimbot.sendMessage(chatID, 'Message received')

If I ran it, would it work? How come I got the following?

Unhandled rejection Error: 400:
{"ok":false,"error_code":400,"description":"Bad Request: chat not found"}
    at Request.then.resp (/path/to/node_modules/slimbot/src/telegram.js:43:15)
    at tryCatcher (/path/to/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/path/to/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/path/to/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/path/to/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/path/to/node_modules/bluebird/js/release/promise.js:694:18)
    at _drainQueueStep (/path/to/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/path/to/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/path/to/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/path/to/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:696:18)
    at tryOnImmediate (timers.js:667:5)
    at processImmediate (timers.js:649:5)

All that I want is to use slimbot.sendMessage alone without the slimbot.startPolling(), because I want to send Telegram Message in another chat bot.

Thx

Photo with caption

Is it possible that photos with a caption are not received by slimbot?

Size limit of callback_data (inlineKeyboard)

Dear edisonchee,

your API keeps its promise. It's straightforward but effective. Thank you.

I experienced something (maybe) odd regarding the attribute callback_data of a button in an inlineKeyboard. In my case, every button represents an object of the class Event, which is retrieved from a database.

Obviously I want to determine which button was clicked by listening for the event callback_query. query.data is a stringified JSON object. Parsing does work but if the string contains too many characters I would get the following error.

Unhandled rejection Error: 400: {"ok":false,"error_code":400,"description":"Bad Request: BUTTON_DATA_INVALID"}

Here is my sourcecode for reference.

slimbot.on('callback_query', query => {
    const data = JSON.parse(query.data);
    switch (data.type) {
        case "info": Responser.info(data.value, query.message.chat.id); break;
        case "register": Responser.register(data.value.eId, data.value.u , query.message.chat.id);
    }
});

Creation of the buttons:

for (i = 0; i < events.length; i++) {
                    inlineKeyboard.push([{
                        text: events[i].toString(),
                        callback_data: JSON.stringify({
                            type: 'register',
                            value: {
                                eId: events[i].eventId,
                                u: user.username
                            }
                        })
                    }]);
}

This works but I actually want to store more data in value. Is there an alternative?

Thank you in advance!
Joachim

Unhandled rejection Error: 502

I created a bot that's pretty minimal, it doesn't go much beyond the simple example.
I'm pretty new to node and I can't really explain why I'm getting the following error:

Unhandled rejection Error: 502:
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>

    at Request.then.resp (/home/myself/src/node_modules/slimbot/src/telegram.js:43:15)
    at tryCatcher (/home/myself/src/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/myself/src/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/myself/src/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/myself/src/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/myself/src/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/home/myself/src/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/myself/src/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/home/myself/src/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)

Might this be a bug related to this project?

Support to answerCallbackQuery

There's some support to answerCallbackQuery when user call inline keyboard? Because when I use, the bot set a 'Loading...' on client waiting for the answerCallbackQuery call.

optionalParams in sendPhoto

Hi there
How to use optionalParams with sending(uploading) photos, for examle I need disable_notification: true
but when I use like this:

 let optionalParams = {
        disable_notification: true
    };

    slimbot.sendPhoto(TELEGRAM_CHAT_NAME, fileUpload,optionalParams)

It's not working
thanks

Error when sending Message

Hi all, I'm using Firebase and Slimbot with webhook.
I call first the function const slimbot = new Slimbot("<<my_token>>")
Then, when i do slimbot.sendMessage(chat_id, "<<my_message>>"), i receive:

RequestError: Error: getaddrinfo EAI_AGAIN api.telegram.org:443
    at new RequestError (/srv/node_modules/request-promise-core/lib/errors.js:14:15)
    at Request.plumbing.callback (/srv/node_modules/request-promise-core/lib/plumbing.js:87:29)
    at Request.RP$callback [as _callback] (/srv/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at self.callback (/srv/node_modules/request/request.js:185:22)
    at emitOne (events.js:116:13)
    at Request.emit (events.js:211:7)
    at Request.onRequestError (/srv/node_modules/request/request.js:881:8)
    at emitOne (events.js:116:13)
    at ClientRequest.emit (events.js:211:7)
    at TLSSocket.socketErrorListener (_http_client.js:401:9)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:66:8)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)

Can you help me? Do you need more logs?

Typescript support

Title says it all.

Maybe node-telegram-bot-api's types can be used as a template. Then it is not needed to model the whole Telegram API again (just the methods specific to slimbot).

bot_command handling

Hi All,

When sending commands to bots, there are two cases -

  • sending direct message to bot as friend (message.text='/start')
  • @bot in group (message.text='/start @bot_id')

In both case, the

"entities":[{"offset":x,"length":y,"type":"bot_command"}]

part will be the same (for the /start command; however, the message.text part will be different, with the @bot in group containing that @ mention part, which pointed out by {"offset":7,"length":12,"type":"mention"}.

In summary, bot command can be of the form /help or /help @botname in message.text. Is there any builtin helper to ease command writing that, I can easily do, say message.bot_command === "/help", that can cover both above two cases?

thx

Where are the docs?

I'm really interested in this project, I wrote a basic bot in it, but I want to do more! Guys, please! Where are the docs? Only the readme.md has some info, but it's not enough to build (let's say) an inline bot

answerPreCheckoutQuery

I get an error when trying to respond to an event "pre_checkout_query".

My Code

slimbot.on('pre_checkout_query', async payment => {
    console.log(payment);
    if (payment.invoice_payload.includes('pay')){
        let user = await database.select('*').from('users').where({telegram_id: payment.from.id});
        if (user.length === 0){
            slimbot.answerPreCheckoutQuery(payment.id, true);
        } else {
            slimbot.answerPreCheckoutQuery(payment.id, false, 'Ошибка оплаты, обратитьсе в поддержку бота');
        }
    } else {
        slimbot.answerPreCheckoutQuery(payment.id, false, 'Ошибка оплаты, обратитьсе в поддержку бота');
    }
});

My Error

D:\Рабочий стол\auto-bot\node_modules\slimbot\src\telegram.js:1241
    return this._request('answerShippingQuery', params, callback);
                                                        ^

ReferenceError: callback is not defined
    at Slimbot.answerPreCheckoutQuery (D:\Рабочий стол\auto-bot\node_modules\slimbot\src\telegram.js:1241:57)
    at Slimbot.<anonymous> (file:///D:/%D0%A0%D0%B0%D0%B1%D0%BE%D1%87%D0%B8%D0%B9%20%D1%81%D1%82%D0%BE%D0%BB/auto-bot/app.js:69:21)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)

And I see strange code in your library, maybe it's a typo. Or am I misapplying your library

answerPreCheckoutQuery(preCheckoutQueryId, ok, errorMessage) {
   let params = {
     pre_checkout_query_id: preCheckoutQueryId,
     ok: ok,
     error_message: errorMessage
   };

   return this._request('answerShippingQuery', params, callback); // On this line answer is not answerPreCheckoutQuery
 }

sendMediaGroup returns error

Hi,
i'm trying to use sendMediaGroup functionality but it returns an error:

let opts = {
    parse_mode: "html",
    disable_web_page_preview: false,
    disable_notification: false,
    caption: [firstPage.subtitle, '---', secondPage.subtitle].join('\n')
  };

  await Telegram.sendMediaGroup(CHAT_ID, [article.thumb, firstPage.image, secondPage.image], opts);

( .thumb and .image are http url )

this code returns:
Error: 400:
{"ok":false,"error_code":400,"description":"Bad Request: parameter \"media\" is required"}

did I do something wrong?

Error during slimbot.sendPhoto call

Hi, I'm trying slimbot to test the scenario:

  1. I write to the bot
  2. It sends me an image in response

code:

const Slimbot = require( "slimbot" )
const fs = require( "fs" )

const socks5proxy = {
    socksHost: "174.0.79.91",
    socksPort: "9999"
}
const slimbot = new Slimbot( "<API_TOKEN>", socks5proxy )

let fileUpload = fs.createReadStream( __dirname + "/../example.png" )

slimbot.on( "message", ( message ) => {
    slimbot.sendPhoto( message.chat.id, fileUpload ).then( message => {
        console.log( message.result.photo )
    } )

} )

slimbot.startPolling()

versions:
"slimbot": "^4.8.0"
node: v14.3.0

But it crashes with this message

_http_outgoing.js:802
    this.socket._writableState.corked = 1;
                                      ^

TypeError: Cannot set property 'corked' of undefined
    at ClientRequest.end (_http_outgoing.js:802:39)
    at Request.end (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/request/request.js:1508:14)
    at FormData.onend (internal/streams/legacy.js:46:10)
    at FormData.emit (events.js:327:22)
    at FormData.CombinedStream.end (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/combined-stream/lib/combined_stream.js:163:8)
    at FormData.CombinedStream._realGetNext (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/combined-stream/lib/combined_stream.js:94:10)
    at FormData.CombinedStream._getNext (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/combined-stream/lib/combined_stream.js:82:12)
    at DelayedStream.emit (events.js:327:22)
    at DelayedStream._handleEmit (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/delayed-stream/lib/delayed_stream.js:82:15)
    at ReadStream.source.emit (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/delayed-stream/lib/delayed_stream.js:29:19)
    at ReadStream.source.emit (/Users/tznasibullin/IdeaProjects/gh/mosru-checker/node_modules/delayed-stream/lib/delayed_stream.js:30:21)
    at endReadableNT (_stream_readable.js:1224:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at runNextTicks (internal/process/task_queues.js:66:3)
    at processImmediate (internal/timers.js:429:9)

When instead of slimbot.sendPhoto I try

slimbot.sendMessage( message.chat.id, "Message received" )

it works perfectly well

Add Ability to Stop Polling

I was wondering if it would be possible to add a stopPolling function to the bot. I have a situation where I would like to have the bot stop receiving updates from telegram without having to terminate the current process.

this._timeout.refresh error on version 4.3.1

occurs a couple of seconds later after the bot is initialized

Unhandled rejection TypeError: this._timeout.refresh is not a function
    at getUpdates.then.catch.finally (notification-service\node_modules\slimbot\src\slimbot.js:66:23)
    at PassThroughHandlerContext.finallyHandler (notification-service\node_modules\bluebird\js\release\finally.js:56:23)
    at PassThroughHandlerContext.tryCatcher (notification-service\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (notification-service\node_modules\bluebird\js\release\promise.js:512:31)
    at Promise._settlePromise (notification-service\node_modules\bluebird\js\release\promise.js:569:18)
    at Promise._settlePromise0 (notification-service\node_modules\bluebird\js\release\promise.js:614:10)
    at Promise._settlePromises (notification-service\node_modules\bluebird\js\release\promise.js:693:18)
    at Async._drainQueue (notification-service\node_modules\bluebird\js\release\async.js:133:16)
    at Async._drainQueues (notification-service\node_modules\bluebird\js\release\async.js:143:10)
    at Immediate.Async.drainQueues (notification-service\node_modules\bluebird\js\release\async.js:17:14)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)

Please provide a Telegram bot token when instantiating

/data/data/com.termux/files/home/node/node_modules/slimbot/src/telegram.js:11
      throw new Error('Please provide a Telegram bot token when instantiating');
      ^

Error: Please provide a Telegram bot token when instantiating
    at new <anonymous> (/data/data/com.termux/files/home/node/node_modules/slimbot/src/telegram.js:11:13)
    at new Slimbot (/data/data/com.termux/files/home/node/node_modules/slimbot/src/slimbot.js:8:5)
    at Object.<anonymous> (/data/data/com.termux/files/home/node/main.js:3:17)
    at Module._compile (internal/modules/cjs/loader.js:958:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:994:10)
    at Module.load (internal/modules/cjs/loader.js:813:32)
    at Function.Module._load (internal/modules/cjs/loader.js:725:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1046:10)
    at internal/main/run_main_module.js:17:11

And my code is

const Slimbot = require('slimbot');
const slimbot = new Slimbot(process.env["1085044735:AAHwW_YNHpDx5ppLWp5JkreO7EFNp9UGERR"]);

// Register listeners
slimbot.on('message', message => {
  // reply when user sends a message
  slimbot.sendMessage(message.chat.id, 'Message received');
});

slimbot.on('edited_message', edited_message => {
  // reply when user edits a message
  slimbot.sendMessage(edited_message.chat.id, 'Message edited');
});

// Call API
slimbot.startPolling();

console.log('polling...');

setTimeout(() => {
  slimbot.stopPolling();
}, 10000);``

More examples to the Sending Files Please

Hey @edisonchee,

Please add more examples to the Sending Files demo.

So far it only sends Photos. When I tried to copy and use sendVideo() I got the error of:

error_code":400,"description":"Bad Request: there is no video in the request"}
    at Request.then.resp (/.../node_modules/slimbot/src/telegram.js:61:15)

Are the video/document parameter supposed to be binary strings (obtained from fs.createReadStream)?

Thx

Helper for reply_markup

Somewhat counterintuitively, reply_markup expects a JSON string:

// Works
  let optionalParams = {
    reply_markup: JSON.stringify({
      keyboard: [
        [
          {text: '/lock'},
        ],
        [
          {text: '/unlock'},
        ]
      ]
    })
  };

// Doesn't work
  let optionalParams = {
    reply_markup: {
      keyboard: [
        [
          {text: '/lock'},
        ],
        [
          {text: '/unlock'},
        ]
      ]
    }
  };

Might be worth checking to see if reply_markup is a string, and if not, stringifying it in sendMessage?

setWebhook discards url parameter?

setWebhook(url, optionalParams) {

You can see that url isn't propagated forward - which means the correct usage of setWebhook would be:

slimbot.setWebhook(null, {'url':MY_URL});

instead of

slimbot.setWebhook(MY_URL);

which actually deletes any webhooks that are set up.

code

what i do with this code?

const Slimbot = require('slimbot');
const slimbot = new Slimbot(process.env['TELEGRAM_BOT_TOKEN']);

// Register listeners

slimbot.on('message', message => {
slimbot.sendMessage(message.chat.id, 'Message received');
});

// Call API

slimbot.startPolling();

How to use “deleteMessage” method in Telegram bot api?

I adding new feature to my telegram bot, and I can`t run deleteMessage method. In this code when I or anyone in chat write message, bot must delete it.

Also bot has can_delete_messages permission in a supergroup. And I try it many times and nothing. I can easy send messages, but can't delete not bot's messages or anybody else.

Here code, which returns undefined undefined

const Slimbot = require('slimbot');
const slimbot = new Slimbot('I hide it');

    function callback(err, obj) {
    if (err) {
    // handle error
    console.log(obj);   
    }
    // handle returned object
    console.log(obj);
    };

slimbot.on('message', message => {

    if (message.text) {
    if (true){          
        slimbot.deleteMessage(message.chat.id,message.message_id, callback);
        }
    }
});


slimbot.startPolling(callback);

Questions:

1)"undefined" are from callback function, but it doesn`t provide any normal information. How make normal error feedback?

  1. How to run deleteMessage method properly?

Slimbot Webhook for TG

Is there any guide or examples of using webhooks for slimbot?

I have a simple TG bot that I used slimbot for and it runs fine locally, but when I send to a hosting provider, there isn't any connection to my bot.

Saw webhooks is something I may need to do but I can't find any examples of how to use webhooks for slimbot.

Any guidance would be much appreciated!

Thanks

Sending Photo Files from readable stream

Following up on #28,

Send methods now make requests with formData if the file you're using is a readable stream.
sendFile no longer broken; let me know if you have any issues using it.

I tried it but am still unable to make it works.

    let fileUpload = fs.createReadStream(fn);
    slimbot.sendPhoto(message.chat.id, fileUpload).then(message => {
      console.log(message.result.photo);

The above is my code, and it is not working.
Would you give a full working example please? Thx

Unhandled rejection Error

I'm getting the following exception from time to time:

Unhandled rejection Error: 400:
{"ok":false,"error_code":400,"description":"Bad Request: chat not found"}
    at Request.then.resp (/path/to/node_modules/slimbot/src/telegram.js:61:15)

which comes from here:

slimbot/src/telegram.js

Lines 58 to 62 in fea0d25

return Request(options)
.then(resp => {
if (resp.statusCode !== 200) {
throw new Error(resp.statusCode + ':\n'+ resp.body);
}

Would it be possible to provide as many relevant info as possible in the exception please?

The async chatting nature has made my effort trying to capture and understand the condition when would such exception happen fruitless so far.

thx!

How to detect bot's own messages

Hi,

I've allowed my bot to receive/access Telegram Group messages. So now I need to worry it should not be responding to its own messages, which'll cause looping.

What's the best way to tell if a message is of its own? Thx.

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.