Git Product home page Git Product logo

node-telegram-bot's Introduction

node-telegram-bot

Join the chat at https://gitter.im/depoio/node-telegram-bot build statusdependenciesnode versionnpm version

Changelog

  • 0.1.9 Improved error 409 by kaminoo
  • 0.1.8 Timeout defaults to 60000ms
  • 0.1.7 Supports splitting command target (#45)
  • 0.1.6 Fixes #53
  • 0.1.5 Add analytics botan.io
  • 0.1.4 Fixes #48
  • 0.1.2 Merge #40, Use debug for logging
  • 0.1 Setwebhook, disable command parsing & maxattempts
  • 0.0.19 Added webhook support instead of polling
  • 0.0.18 Merged bug fix
  • 0.0.17 support multiple command arguments
  • 0.0.16 support file id for audio, document, sticker and video
  • 0.0.15 emit command (message that starts with '/')
  • 0.0.14 sendLocation
  • 0.0.13 getUserProfilePhotos
  • 0.0.12 sendDocument
  • 0.0.9 sendAudio
  • 0.0.8 sendPhoto
  • 0.0.7 forwardMessage
  • 0.0.6 sendChatAction
  • 0.0.3 Longpoll
  • 0.0.2 getMessage
  • 0.0.1 getMe

Documentation

Documentation is built using jsdoc with DocStrap. More to come (including examples)! Documentation Link

Sending files (including photo, audio, document, video and sticker)

Now only require filepath,

bot.sendPhoto({
  chat_id: USER_ID,
  caption: 'Telegram Logo',
  files: {
    photo: './examples/logo.png'
  }
}, function (err, msg) {
  console.log(err);
  console.log(msg);
});

Previously,

bot.sendPhoto({
  chat_id: USER_ID,
  caption: 'Telegram Logo',
  files: {
    photo: {
      filename: './examples/logo.png',
      stream: fs.createReadStream('./examples/logo.png')
    }
  }
}, function (err, msg) {
  console.log(err);
  console.log(msg);
});

Here's an example:

var Bot = require('node-telegram-bot');

var bot = new Bot({
  token: 'TOKEN HERE'
})
.on('message', function (message) {
  console.log(message);
})
.start();

How to use Botan.io analytics:

var bot = new Bot({
  token: 'Telegram token'
})
.enableAnalytics('Botan.io token')
.on('message', function (message) {
  console.log(message);
})
.start();

Credits

Sample sound

node-telegram-bot's People

Contributors

alberto-bottarini avatar cgrs avatar cngan avatar cojad avatar denisx avatar gitter-badger avatar jasperalgra avatar longstone avatar luchanso avatar mrhug avatar sebastianarena avatar shernshiou avatar syrenity avatar tailot avatar theshaun avatar transitive-bullshit avatar vacero 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  avatar  avatar  avatar

node-telegram-bot's Issues

Check access token integration

Would it be possible to check the bots access token and throw an error if the token is wrong?
If you want, I could develop this little extension and submit it as Pull request.
Are you interested?

Multipart stream parameter

I noticed you removed the stream parameter from the multipart method. Filepath as parameter is more user friendly but I am missing the stream parameter since I download files and forward it to Telegram.

I quick and dirty patched it like this for now:

//    var file = options.files[key]
//     , filename = path.basename(file)
//      , stream = fs.createReadStream(file);

var file = options.files[key];
var stream = file.stream;
var filename = file.filename;

A nicer way to handle stream as parameter would be great

Quick fix for a problem with edited messages (no `msg.message`; but messages include a `msg.edited_message`)

There is a problem with _poll when messages are edited before being read.

msg.message is missing when a message is edited, msg.edited_message is available

I've provided a very quick fix. But you might want to do something more comprehensive.

Bot.prototype._poll = function () {
  var self = this;

/* Some Code */
              if (self.parseCommand) {
////////////////////////////////////////////////////////////
// QUICK FIX HERE
////////////////////////////////////////////////////////////
// a quick fix because msg.message is missing when a message is edited, ...
// but msg.edited_message is available
// put this where you think it makes sense
if (!!msg.edited_message) {
  msg.message = msg.edited_message;
  console.log("Monkey Patch for Edited Messages:", msg);
}
////////////////////////////////////////////////////////////
                if (msg.message.text && msg.message.text.charAt(0) === '/') {
                  /**
/* Some Code */

Here's what a msg.edited_message looks like:

   { message_id: 869,
     from: { id: 179442020, first_name: 'xxx', username: 'xxxx' },
     chat: 
      { id: 0000,
        first_name: 'xxx',
        username: 'xxxx',
        type: 'private' },
     date: 1463978414,
     edit_date: 1463978429,
     text: 'f' },

Still possible to use streams instead of filepath?

Is it still possible to use streams instead of the file path when sending images/videos/etc?
I get the images off another server, which is why I need it :/

bot.sendPhoto({
  chat_id: USER_ID,
  caption: 'Telegram Logo',
  files: {
    photo: {
      filename: './examples/logo.png',
      stream: fs.createReadStream('./examples/logo.png')
    }
  }
}, function (err, msg) {
  console.log(err);
  console.log(msg);
});

sendMessage with ReplyKeyboardMarkup question

Hi !

I try to send a message with custom keyboard as reply.

bot.sendMessage({chat_id: myid,
                             text: "Who to write ?",
                             reply_markup: {
                                 keyboard: [ ["hello"], ["world"] ],
                             }
                                    }, function(err, ret) {
                                        if(err) return console.error(err);
                                    })

I get the message "Who to write ?" and I see that the client is waiting a command but none of the options are shown.
Am i doing something wrong ?

Somebody broke my argument parsing

On line 218 it should be self.emit(command, msg.message, arg);
Now it's self.emit(command, msg.message, arguments); and is doing crazy things.

pulling and http 409 error

I'm still at 0.1.2 and can't upgrade to latest version.
I have 2 servers which share the same token and use pulling.
From time to time they get 409 error.
with 0.1.2 the pulling continues.
with 0.1.9 pulling stops on 409 error.

getFile without dir parameter

If dir is not set on getFile method the returned url is null.

Apparently the url is only set inside the options.dir conditional.

Move to bluebird

Compared to Q which we are using now, bluebird has better performance and compatibility.

Error: read ECONNRESET

Some times my bot fails with the following error:

Error: read ECONNRESET
    at errnoException (net.js:905:11)
    at TCP.onread (net.js:559:19)

PS: I do not work with network using some libraries exception node-telegram-bot.

sendPhoto method

Hello,
thank you for your library, I need help about the use of the method sendPhoto because I see that there's only one parameter, but, how can I use photo option?
Thank you.

sendPhoto throwing error

I do as said in one of closed issues:

bot.sendPhoto({
    chat_id: message.chat.id,
    files: {
        photo: {
            filename: 'test.jpg',
            stream: fs.createReadStream('test.jpg')
        }
    }
});
 if (options.filename || value.path) {
                                 ^
TypeError: Cannot read property 'path' of undefined

What am I doing wrong?

Send gif

Hello I want to send a gif file like this:

bot.sendDocument({
    chat_id: id,
    document: request(original_url).pipe(fs.createReadStream("image.gif"))
});

But I keep getting this message:

.../node_modules/node-telegram-bot/lib/Bot.js:700
    if (options.files.stream) {
                     ^

TypeError: Cannot read property 'stream' of undefined

How do you handle incoming audio messages?

When an audio message is received, how do you save it or open it or do anything with it? The JSON message just has meta data like duration, mime, file_id, file_size.

TypeError: Cannot call method 'split' of undefined

I have a problem with app which was deployed on the OpenShift (node-telegram-bot version 0.0.16):

TypeError: Cannot call method 'split' of undefined
    at /var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/lib/Bot.js:90:44
    at Array.forEach (native)
    at Request._callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/lib/Bot.js:87:21)
    at Request.self.callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:197:22)
    at Request.emit (events.js:98:17)
    at Request.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:1050:14)
    at Request.emit (events.js:117:20)
    at IncomingMessage.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:996:12)
    at IncomingMessage.emit (events.js:117:20)
    at _stream_readable.js:944:16

Command parsing

Hi!
Love the library.
Could you make some sort of config parameter to enable/disable command parsing?
I'm currently handling this on my own, and if for every message you parse it, it would allow for a loss in performance.
If needed I can contribute with a pull-request for this.
Thanks.
Sebastian

.on fired twice

Hi there,

I started bot from example:

var Bot = require('node-telegram-bot');

var bot = new Bot({
  token: 'bla bla token'
})
.on('message', function (message) {
  console.log(message);
})
.start();

Every time I send msg to bot I got .on fired twice;

{ message_id: 12,
  from: 
   { id: 000,
     first_name: 'first',
     last_name: 'last',
     username: 'usr' },
  chat: 
   { id: 135648167,
     first_name: 'first',
     last_name: 'last',
     username: 'usr',
     type: 'private' },
  date: 1453575130,
  text: 'test' }
{ message_id: 12,
  from: 
   { id: 135648167,
     first_name: 'first',
     last_name: 'last',
     username: 'usr' },
  chat: 
   { id: 135648167,
     first_name: 'first',
     last_name: 'last',
     username: 'usr',
     type: 'private' },
  date: 1453575130,
  text: 'test' }

Handle Telegram outage gracefully

Telegram was under DDOS yesterday and my bots got this error:

{ [Error: socket hang up] code: 'ECONNRESET' }

I think the best place to handle this is in your library. Maybe retry until connectable again? Is there a on-error event?

Bot had no response to messages and crashed with TypeError

    } else if(res.statusCode === 401){
                 ^
TypeError: Cannot read property 'statusCode' of undefined
  at Request._callback (/Users/xavieryao/gengbot/node_modules/node-telegram-bot/lib/Bot.js:203:18)
  at self.callback (/Users/xavieryao/gengbot/node_modules/node-telegram-bot/node_modules/request/request.js:198:22)
  at Request.emit (events.js:107:17)
  at Request.onRequestError (/Users/xavieryao/gengbot/node_modules/node-telegram-bot/node_modules/request/request.js:877:8)
  at ClientRequest.emit (events.js:107:17)
  at TLSSocket.socketErrorListener (_http_client.js:271:9)
  at TLSSocket.emit (events.js:129:20)
  at net.js:459:14
  at process._tickCallback (node.js:355:11)

release 0.1.4 - bug with BOT /getUpdates

Bot.prototype._poll is used to poll message to the bot.

the HTTP response in most cases is 409 (timeout).
New code (0.1.4) is raising an error for that.

works perfectly with 0.1.2

Error: Gateway error.

2016-08-24T11:49:37.598Z - info:  Error: Gateway error.
    at Request._callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/lib/Bot.js:273:28)
    at Request.self.callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:187:22)
    at Request.emit (events.js:98:17)
    at Request.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:1044:10)
    at Request.emit (events.js:95:17)
    at IncomingMessage.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:965:12)
    at IncomingMessage.emit (events.js:117:20)
    at _stream_readable.js:944:16
    at process._tickCallback (node.js:442:13)

Command not parsed if containing '@'

Code:

    }).on('stats', function (message) {
    // do something
    }).on('message',function(msg){
        send(msg.chat.id,'unprocessable command: '+msg.text);
    }).start();

Request
/stats@myBot
Response:
unprocessable command: /stats@myBot

Can someone confirm this is a bug? I'm running V0.1.2

Bot analytics integration

Hello!
I`m a developer of the analytics service for telegram bots https://github.com/botanio/sdk

I want to offer integrate our sdk to this wrapper, so bot developer can get some analytics without much efforts. Is anyone interested in such enhancement?

Commands on group chats

Hi, I'm new here (also started to learn how to code a few weeks ago) and I have a doubt (maybe newbie question, but still):

How can I set my bot to answer group chat commands? Because when I send a command /help on a private chat it works correctly, but when my bot is in a group with another bots, the message is sent as: /help@MyBotUsername, and it doesn't answer.

Any help or explanation would be appreciated, thanks and sorry for any mistake. :)

got error

Got this error when trying send photo in telegram -> bot

/home/ubuntu/workspace/FacebookBot/node_modules/node-telegram-bot/node_modules/q/q.js:155
throw e;
^

TypeError: Cannot read property 'destination' of undefined
at callback (/home/ubuntu/workspace/FacebookBot/facebookbot.js:95:83)
at /home/ubuntu/workspace/FacebookBot/node_modules/node-telegram-bot/node_modules/q/q.js:2031:17
at runSingle (/home/ubuntu/workspace/FacebookBot/node_modules/node-telegram-bot/node_modules/q/q.js:137:13)
at flush (/home/ubuntu/workspace/FacebookBot/node_modules/node-telegram-bot/node_modules/q/q.js:125:13)
at doNTCallback0 (node.js:417:9)
at process._tickCallback (node.js:346:13)

Sending stickers to bot is crashing

When sending stickers to bot app is crashing with the below error. I guess the problem occurs when there is not text in message.

var command = msg.message.text.split(' ')[0]; TypeError: Cannot read property 'split' of undefined at Array.forEach (native) at /app/node_modules/node-telegram-bot/lib/Bot.js:90:43

"/error" crashes the bot

When you send "/error" the bot crashes with following error message:

Error: Uncaught, unspecified "error" event. ([object Object])
    at Bot.emit (events.js:144:17)
    at /home/tobias/gem-dev/node_modules/node-telegram-bot/lib/Bot.js:238:24
    at Array.forEach (native)
    at Request._callback (/home/tobias/gem-dev/node_modules/node-telegram-bot/lib/Bot.js:216:23)
    at Request.self.callback (/home/tobias/gem-dev/node_modules/node-telegram-bot/node_modules/request/request.js:198:22)
    at emitTwo (events.js:87:13)
    at Request.emit (events.js:172:7)
    at Request.<anonymous> (/home/tobias/gem-dev/node_modules/node-telegram-bot/node_modules/request/request.js:1035:10)
    at emitOne (events.js:82:20)
    at Request.emit (events.js:169:7)

Edited messages causes library to break

When the server sends a message like (personal information redacted and user id modified):

{ update_id: 404781694,
  edited_message: 
   { message_id: 11,
     from: 
      { id: 152564221,
        first_name: 'REDACTED',
        last_name: 'Redacted',
        username: 'redacted' },
     chat: 
      { id: 152564221,
        first_name: 'Redacted',
        last_name: 'Redacted',
        username: 'redacted',
        type: 'private' },
     date: 1471044047,
     edit_date: 1471044102,
     text: '/asignatura ean',
     entities: [ [Object] ] } }

The following error is raised:

/home/fcanela/workspace/lab/silly_motivational_bot/node_modules/node-telegram-bot/lib/Bot.js:221
                if (msg.message.text && msg.message.text.charAt(0) === '/') {
                               ^

TypeError: Cannot read property 'text' of undefined
    at /home/fcanela/workspace/lab/silly_motivational_bot/node_modules/node-telegram-bot/lib/Bot.js:221:32
    at Array.forEach (native)
    at Request._callback (/home/fcanela/workspace/lab/silly_motivational_bot/node_modules/node-telegram-bot/lib/Bot.js:216:23)
    at Request.self.callback (/home/fcanela/workspace/lab/silly_motivational_bot/node_modules/request/request.js:187:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (/home/fcanela/workspace/lab/silly_motivational_bot/node_modules/request/request.js:1044:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
    at IncomingMessage.<anonymous> (/home/fcanela/workspace/lab/silly_motivational_bot/node_modules/request/request.js:965:12)

This behaviour can be reproduced this way:

  1. Sending a command using Linux client
  2. Pressing up key in the text area, an "Edit message" label will appear
  3. Resending the command or writing a new one

A dirty and quick fix that solved my issue was referencing msg.message to msg.edited_message. Starting from line 216:

          body.result.forEach(function (msg) {
                        if (msg.edited_message) msg.message = msg.edited_message;

There should be probably a better option, but I have no time to validate it right now. I hope this help.

Thanks for the library.

WHAT IS THIS PROBLEM - ECONNRESET?

events.js:85 │·······················
throw er; // Unhandled 'error' event │·······················
^ │·······················
Error: read ECONNRESET │·······················
at exports._errnoException (util.js:746:11) │·······················
at Pipe.onread (net.js:559:26) │·······················

TypeError: Cannot read property 'text' of undefined

TypeError: Cannot read property 'text' of undefined
    at /var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/lib/Bot.js:221:32
    at Array.forEach (native)
    at Request._callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/lib/Bot.js:216:23)
    at Request.self.callback (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:198:22)
    at Request.emit (events.js:98:17)
    at Request.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:1035:10)
    at Request.emit (events.js:117:20)
    at IncomingMessage.<anonymous> (/var/lib/openshift/55a967bc500446e3a9000060/app-root/runtime/repo/node_modules/node-telegram-bot/node_modules/request/request.js:962:12)
    at IncomingMessage.emit (events.js:117:20)
    at _stream_readable.js:944:16

Error HTTP 409

Hi everyone.
Am I the only one getting a ton of 409 errors from Telegram?
It's stated somewhere on the web that this is probably when trying to use multiple bots at the same time, but the case is I'm only running one instance of each one that I have.
Every couple of minutes I get this error and restart the polling.

I did find a probable bug on the Bot, that in the polling the getUpdates gets a 60 seconds timeout, but the actual request call is only 6 seconds (6000ms). I increased to 70000ms to make sure Telegram times out first, but I still get the same problems.

I run at least 10 bots at the same time.

Anyone else having this problem?
Seba

Handling response error crashes

Hi there, me again.
I have your library running 24x7 with a couple of bots on a server.
Last week I updated to your latest revision and some crashes started to appear.
Sure enough are easy to fix. Seems like the response object is null on some cases.
Here are two different errors:

First reported issue

TypeError: Cannot read property 'statusCode' of undefined
File "/node_modules/node-telegram-bot/lib/Bot.js", line 203, in Request._callback
} else if(res.statusCode === 401){
File "/node_modules/request/request.js", line 198, in self.callback
self._callback.apply(self, arguments)
File "events.js", line 107, in Request.emit
File "/node_modules/request/request.js", line 877, in Request.onRequestError
self.emit('error', error)
File "events.js", line 107, in ClientRequest.emit

Second reported issue
TypeError: Cannot read property 'statusCode' of undefined
File "/node_modules/node-telegram-bot/lib/Bot.js", line 159, in Request._callback
console.log("Failed to set webhook with code" + res.statusCode);
File "/node_modules/request/request.js", line 198, in self.callback
self._callback.apply(self, arguments)
File "events.js", line 107, in Request.emit
File "/node_modules/request/request.js", line 877, in Request.onRequestError
self.emit('error', error)
File "events.js", line 107, in ClientRequest.emit

Any extra help I can provide, let me know!

process._tickCallback

/node_modules/node-telegram-bot/node_modules/q/q.js:155
throw e;
^
TypeError: Cannot read property 'file_id' of undefined
at /commands/dl.js:36:56
at /node_modules/node-telegram-bot/node_modules/q/q.js:2031:17
at runSingle (/node_modules/node-telegram-bot/node_modules/q/q.js:137:13)
at flush (/node_modules/node-telegram-bot/node_modules/q/q.js:125:13)
at process._tickCallback (node.js:355:11)

setwebhook with self-signed certificate

Telegram new updates :

  • Added support for self-signed certificates: upload your certificate using the certificate parameter in the setWebhook method.

Is there any way I can use self-signed cert? Thanks.

Bot Termination and Startup Issue

Hello,

I am trying to use the Library to be able to Stop the BOT app from Node if needed.
However next time when I start the bot again it fails to start up.

Here is a code snippet:

case message.text == '/stop':
      bot.sendMessage({
        chat_id: message.chat.id,
        text: 'Goodbye',
      });
      bot.stop();
    break;

This inside the command parser instantiated by:

// Attach event on every received message 
bot.on('message', function (message) {
  parseMessage(message);
});

Where parseMessage(message) is the function that is used to interpret the message as a command.

The package is running normally when there is no /stop command sent.
However ones this is sent from Telegram it causes the BOT to stop.
Next time when I try to start the application it does not allow the BOT application to start.

Kindly help regarding this.

Warm Regards,
Boseji

Bot silently stops pulling/responding

Hi there!

I am running this bot on my Raspberry Pi and it always just stops pulling the messages after a period of time.

I am running it with nohup to daemonize it like this:

nohup node app.js &

The nohup.out never throws an error, it just stops pulling the messages until I kill and restart the bot. Then it processes all missed messages and goes on for a few hours.
My Raspberry Pi is running rock solid for more than 120 days straight now.

Any idea?

Improve documentation on use of Bot commands

I see here that it's possible to parse commands with this library, but there are no documentation/examples of it. Can you please provide some detailed doc?

The example only mentions .on('message', function (message) { ... } where message.text has the command and the text. Is it possible to do something like .on('start', function (message) { ... } or .on('help', function (message) { ... }?

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.