Giter VIP home page Giter VIP logo

telegram-bot-ruby's Introduction

telegram-bot-ruby

Ruby wrapper for Telegram's Bot API.

Gem Version Build Status Maintainability Say Thanks!

🚧 Upgrading to 1.0

Since v1.0 telegram-bot-ruby uses dry-struct instead of virtus. This means that type objects are now immutable and you can't change them after initialization:

# This won't work
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new
kb.remove_keyboard = true

# You have to set attributes in constructor instead
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true)

Please make sure it doesn't break your existing code before upgrading to 1.0.

Installation

Add following line to your Gemfile:

gem 'telegram-bot-ruby', '~> 1.0'

And then execute:

bundle

Or install it system-wide:

gem install telegram-bot-ruby

Usage

First things first, you need to obtain a token for your bot. Then create your Telegram bot like this:

require 'telegram/bot'

token = 'YOUR_TELEGRAM_BOT_API_TOKEN'

Telegram::Bot::Client.run(token) do |bot|
  bot.listen do |message|
    case message.text
    when '/start'
      bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}")
    when '/stop'
      bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}")
    end
  end
end

Note that bot.api object implements Telegram Bot API methods as is. So you can invoke any method inside the block without any problems. All methods are available in both snake_case and camelCase notations.

If you need to start a bot in development mode you have to pass environment: :test:

Telegram::Bot::Client.run(token, environment: :test) do |bot|
  # ...
end

Same thing about message object: it implements Message spec, so you always know what to expect from it.

To gracefully stop the bot, for example by INT signal (Ctrl-C), call the bot.stop method:

bot = Telegram::Bot::Client.new(token)

Signal.trap('INT') do
  bot.stop
end

bot.listen do |message|
  # it will be in an infinity loop until `bot.stop` command
  # (with a small delay for the current `fetch_updates` request)
end

Webhooks

If you are going to use webhooks instead of long polling, you need to implement your own webhook callbacks server. Take a look at this repo as an example.

Proxy

As some countries block access to Telegram, you can set up your own proxy and use it to access Telegram API. In this case you need to configure API URL:

Telegram::Bot::Client.run(token, url: 'https://proxy.example.com') do |bot|
  # ...
end

Custom keyboards

You can use your own custom keyboards. Here is an example:

bot.listen do |message|
  case message.text
  when '/start'
    question = 'London is a capital of which country?'
    # See more: https://core.telegram.org/bots/api#replykeyboardmarkup
    answers =
        Telegram::Bot::Types::ReplyKeyboardMarkup.new(
          keyboard: [
            [{ text: 'A' }, { text: 'B' }],
            [{ text: 'C' }, { text: 'D' }]
          ],
          one_time_keyboard: true
        )
    bot.api.send_message(chat_id: message.chat.id, text: question, reply_markup: answers)
  when '/stop'
    # See more: https://core.telegram.org/bots/api#replykeyboardremove
    kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true)
    bot.api.send_message(chat_id: message.chat.id, text: 'Sorry to see you go :(', reply_markup: kb)
  end
end

Furthermore, you can ask user to share location or phone number using KeyboardButton:

bot.listen do |message|
  kb = [[
    Telegram::Bot::Types::KeyboardButton.new(text: 'Give me your phone number', request_contact: true),
    Telegram::Bot::Types::KeyboardButton.new(text: 'Show me your location', request_location: true)
  ]]
  markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(keyboard: kb)
  bot.api.send_message(chat_id: message.chat.id, text: 'Hey!', reply_markup: markup)
end

Inline keyboards

Bot API 2.0 brought us new inline keyboards. Example:

bot.listen do |message|
  case message
  when Telegram::Bot::Types::CallbackQuery
    # Here you can handle your callbacks from inline buttons
    if message.data == 'touch'
      bot.api.send_message(chat_id: message.from.id, text: "Don't touch me!")
    end
  when Telegram::Bot::Types::Message
    kb = [[
      Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Go to Google', url: 'https://google.com'),
      Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Touch me', callback_data: 'touch'),
      Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Switch to inline', switch_inline_query: 'some text')
    ]]
    markup = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: kb)
    bot.api.send_message(chat_id: message.chat.id, text: 'Make a choice', reply_markup: markup)
  end
end

Inline bots

If you are going to create inline bot, check the example below:

bot.listen do |message|
  case message
  when Telegram::Bot::Types::InlineQuery
    results = [
      ['1', 'First article', 'Very interesting text goes here.'],
      ['2', 'Second article', 'Another interesting text here.']
    ].map do |arr|
      Telegram::Bot::Types::InlineQueryResultArticle.new(
        id: arr[0],
        title: arr[1],
        input_message_content: Telegram::Bot::Types::InputTextMessageContent.new(message_text: arr[2])
      )
    end

    bot.api.answer_inline_query(inline_query_id: message.id, results: results)
  when Telegram::Bot::Types::Message
    bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}!")
  end
end

Now, with inline mode enabled, your message object can be an instance of Message, InlineQuery or ChosenInlineResult. That's why you need to check type of each message and decide how to handle it.

Using answer_inline_query you can send query results to user. results field must be an array of query result objects.

File upload

Your bot can even upload files (photos, audio, documents, stickers, video) to Telegram servers. Just like this:

bot.listen do |message|
  case message.text
  when '/photo'
    path_to_photo = File.expand_path('~/Desktop/jennifer.jpg')
    bot.api.send_photo(chat_id: message.chat.id, photo: Faraday::UploadIO.new(path_to_photo, 'image/jpeg'))
  end
end

Logging

By default, bot doesn't log anything (uses NullLoger). You can change this behavior and provide your own logger class. See example below:

Telegram::Bot::Client.run(token, logger: Logger.new($stderr)) do |bot|
  bot.logger.info('Bot has been started')
  bot.listen do |message|
    # ...
  end
end

Connection adapters

Since version 0.5.0 we rely on faraday under the hood. You can use any of supported adapters (for example, net/http/persistent):

require 'net/http/persistent'

Telegram::Bot.configure do |config|
  config.adapter = :net_http_persistent
end

Boilerplates

If you don't know how to setup database for your bot or how to use it with different languages here are some boilerplates which can help you to start faster:

Contributing

  1. Fork it.
  2. Create your feature branch (git checkout -b my-new-feature).
  3. Commit your changes (git commit -am 'Add some feature').
  4. Push to the branch (git push origin my-new-feature).
  5. Create a new Pull Request.

telegram-bot-ruby's People

Contributors

alepore avatar alexwayfer avatar amogil avatar atipugin avatar biow0lf avatar d4mk0 avatar frostmark avatar gl-pv avatar hostgame avatar ivanovaleksey avatar keeakita avatar l-eugene avatar maksimabramchuk avatar mamal72 avatar mendab1e avatar omichkun avatar seorgiy avatar smaximov avatar sudakov-eugene avatar sven-strothoff avatar valovm avatar vladislav-yashin avatar vsevolod 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  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

telegram-bot-ruby's Issues

code example not working

I wanted to play with your ruby wrapper for telegram's bot api so I created a new telegram bot, copy/pasted one of your code example (https://github.com/democratech/bot) but when I run the code, I get the following error:

$ bundle exec ruby bot.rb
/var/lib/gems/1.9.1/gems/httparty-0.13.5/lib/httparty/response.rb:71:in `method_missing': undefined method `to_h' for #<HTTParty::Response:0x00000001e481c0> (NoMethodError)
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/api.rb:34:in `call'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/api.rb:27:in `method_missing'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:27:in `block in listen'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:26:in `loop'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:26:in `listen'
    from bot.rb:5:in `block in <main>'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:22:in `run'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:10:in `run'
    from bot.rb:4:in `<main>'

Am I doing something wrong here ? It would be good to add a section in your README.md to guide people on how to have a fully working example running on their machine.

Get Chat Id/title

Hi guys, i am new in ruby and i was trying to get the chat id or chat title of the group where the message is send...

Is it possible?

i tried message.chat.id and some stuff but didnt work

thanks

How do i use the edit_message_text method

I believe the correct syntax should be as follows;

bot.api.edit_message_text(chat_id: message.from.id, message_id: message.message_id, text: 'Hello Ruby', reply_markup: kbmarkup)

What should the message_id: be? Because I get the following error;

undefined method `message_id' for # Telegram::Bot::Types::CallbackQuery:0x007f867a1efae8 (NoMethodError)

Send bulk messages to "subscribers"?

First thanks for the gem. I had my first nonsense bot up and running within a hour.

I would like to send notifications to all "subscribed" users/channels. As in any who have my bot in their channel and/or wrote /subscribe to him. Is that possible? I checked the code and the examples and did not really find a solution that looks like it would work without initial trigger from Telegram itself.

Uninitialized constant Net::ReadTimeout (NameError)

ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
on Elementary OS Freya

Getting "uninitialized constant Net::ReadTimeout (NameError)" error on my script startup

Full message reads:

/var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.0/lib/telegram/bot/client.rb:34:in `rescue in listen': uninitialized constant Net::ReadTimeout (NameError)
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.0/lib/telegram/bot/client.rb:23:in `listen'
    from find.rb:16:in `block in <main>'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.0/lib/telegram/bot/client.rb:19:in `run'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.0/lib/telegram/bot/client.rb:7:in `run'
    from find.rb:15:in `<main>'

bot.listen throws Net::ReadTimeout

Since bot.listen uses long polling, read timeouts are to be expected when there's no activity.

In that regard, this should be hidden from the user of the library and poll request automatically restarted.

Was expecting this behaviour initially, and learned it wasn't, the hard way — bot crashed when nobody was looking at it and it stayed down for 8 hours until I woke up to see the Net::ReadTimeout got thrown from bot.listen.

To make my bot persistent, I had to update the main loop to look like this:

while true
    begin
        bot.listen do |message|
            logfrom message
            case message.text
            when /^\/pony\b/
                derpibooru_bot.pony(message)
            when /^\/(start|help)\b/
                derpibooru_bot.sendtext(message, "Hello! I'm a bot by @hmage ...")
            end
        end
    rescue Net::ReadTimeout => e
        logerror e
    end
end

If adding automatic restart is not an option, update all examples to handle Net::ReadTimeout exception, because it will happen after a while when bot is supposed to be 24/7.

It would be nice to be able to stop the bot gracefully

I did not find a way to stop the bot gracefully. When you stop the bot today (via CTRL-C or any UNIX standard signal), it just spits an error:

^C/usr/lib/ruby/1.9.1/net/protocol.rb:143:in `select': Interrupt
    from /usr/lib/ruby/1.9.1/net/protocol.rb:143:in `rescue in rbuf_fill'
    from /usr/lib/ruby/1.9.1/net/protocol.rb:140:in `rbuf_fill'
    from /usr/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
    from /usr/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
    from /usr/lib/ruby/1.9.1/net/http.rb:2563:in `read_status_line'
    from /usr/lib/ruby/1.9.1/net/http.rb:2552:in `read_new'
    from /usr/lib/ruby/1.9.1/net/http.rb:1320:in `block in transport_request'
    from /usr/lib/ruby/1.9.1/net/http.rb:1317:in `catch'
    from /usr/lib/ruby/1.9.1/net/http.rb:1317:in `transport_request'
    from /usr/lib/ruby/1.9.1/net/http.rb:1294:in `request'
    from /var/lib/gems/1.9.1/gems/persistent_http-1.0.6/lib/persistent_http.rb:304:in `block in request'
    from /var/lib/gems/1.9.1/gems/gene_pool-1.4.1/lib/gene_pool.rb:137:in `with_connection'
    from /var/lib/gems/1.9.1/gems/persistent_http-1.0.6/lib/persistent_http.rb:299:in `request'
    from /var/lib/gems/1.9.1/gems/httparty-0.13.5/lib/httparty/request.rb:101:in `perform'
    from /var/lib/gems/1.9.1/gems/httparty-0.13.5/lib/httparty.rb:522:in `perform_request'
    from /var/lib/gems/1.9.1/gems/httmultiparty-0.3.16/lib/httmultiparty.rb:124:in `post'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/api.rb:32:in `call'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/api.rb:27:in `method_missing'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/client.rb:27:in `block in listen'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/client.rb:26:in `loop'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/client.rb:26:in `listen'
    from bot.rb:34:in `block in run'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/client.rb:22:in `run'
    from /var/lib/gems/1.9.1/gems/telegram-bot-ruby-0.3.2/lib/telegram/bot/client.rb:10:in `run'
    from bot.rb:33:in `run'
    from bot.rb:43:in `<main>'

It would be nice to be able to do something like for webrick (see the following example) so that the bot can be stopped without crashing :

require 'webrick'
server = WEBrick::HTTPServer.new :Port => 1234
server.mount "/", WEBrick::HTTPServlet::FileHandler, './'
trap('INT') { server.stop }
server.start

How do we pin a message?

Hi @atipugin
Not really an issue, but asking for some advice. How do we pin a message using pinned_message.
This is my unsuccessful attempt
bot.api.send_message(chat_id: message.chat.id, parse_mode: 'html', text: "Message to be pinned", pinned_message: message.message_id)

markdown square bracket characters [ ] dont work

dont work:

bot.api.sendMessage(chat_id: message.chat.id, text: "\[dont show in brackets\]", parse_mode: "Markdown")

work, but why?:

bot.api.sendMessage(chat_id: message.chat.id, text: "\\[show in brackets\]", parse_mode: "Markdown")

regards,
Luis

I can't connect botan

Connected botan as written in the instructions. When you run displays an error:

C:/dev/Ruby22/lib/ruby/2.2.0/net/http.rb:923:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

Here is my code:

require 'telegram/bot'
require 'telegram/bot/botan'

token = 'myBotToken'

Telegram::Bot::Client.run(token) { |bot|
  bot.enable_botan!('myBotanAPIkey')
  bot.listen { |message|
    case message.text
      when '/start'
        bot.track('Started', message.from.id, type_of_chat: message.chat.class.name)
    end
  }
}

What did I do wrong?

Maybe a silly question, how to send gifs

Hi, I have been using this tool for some time and although I don't know much about http communication it made making a simple bot really easy. Now I have updated the tool and I don't know anymore how to send documents with the Faraday support. I am trying to mimic what I see but haven't had any success.

I am trying to do something like this:
bot.api.send_document(chat_id: dest, document: Faraday::UploadIO.new("file.gif","THING"))

but I don't know what to put in THING, or if it is the way to do it. Before I just plugged in a File and it worked perfectly. What is the right way of doing it?

Issue in updated message logging

Looks like it can't log updated messages.

Traceback:
/usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:61:in log_incoming_message': undefined methodfrom' for nil:NilClass (NoMethodError)
from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:39:in block in fetch_updates' from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:35:ineach'
from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:35:in fetch_updates' from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:27:inlisten'
from /root/Serialtimerbot/main_bot.rb:61:in block in <top (required)>' from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:20:inrun'
from /usr/local/rvm/gems/ruby-2.2.3/gems/telegram-bot-ruby-0.5.1/lib/telegram/bot/client.rb:8:in run' from /root/Serialtimerbot/main_bot.rb:55:in<top (required)>'
from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/application.rb:218:in load' from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/application.rb:218:instart_load'
from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/application.rb:297:in start' from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/controller.rb:56:inrun'
from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons.rb:144:in block in run' from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:incall'
from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:in catch_exceptions' from /usr/local/rvm/gems/ruby-2.2.3/gems/daemons-1.2.3/lib/daemons.rb:143:inrun'

Expose error codes in exceptions (502 Bad Gateway)

Right now there doesn't appear to be a good way to tell specifically what error code Telegram returns in the case of an error, other than looking at the string coming from Telegram::Bot::Exceptions::ResponseError. This approach seems kind of fragile. It would be nice it exposed the numeric code.

My use case for this is that once in a while the Telegram API returns a 502, which is just some temporary gateway error. I'd like my bot to restart itself in this case, but not if the error is a 4xx as it indicates the bot did something wrong and should stop.

I can submit a pull request that implements this, but I was wondering what the best way of doing this is. I could:

  1. Expose the data method that is currently private. This would allow objects to inspect the actual response and take actions based on it. This might have design implications.
  2. Expose a new method, error_code that contains only the error code.
  3. Raise a specific error type for each known Telegram response (one for 409, one for 502, etc). It'd be a lot of new classes.
  4. Code the bot by default to keep trying in case of 502 or even 5xx errors, instead of throwing an exception. This is what the Golang telegram bindings do.

I'm curious to what your thoughts are on this. Like I said, I'm happy to take this and work on it, just want to make sure I'm going in the right direction.

How resend a photo that is already on the Telegram servers?

The official docs in https://core.telegram.org/bots/api#sendphoto says:

Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo using multipart/form-data.

In this regard, I have a question: how to make by telegram-bot-Ruby.
I have not found a solution in the source code.

Maybe I missed something, I have only recently started to learn Ruby.
Waiting for your reply.

InlineQueryResultArticle changed in new version

On the previous version you could do:

Telegram::Bot::Types::InlineQueryResultArticle .new(id: 1, title: 'First article', message_text: 'Very interesting text goes here.')

now the new version requires a InputMessageContent object:

input_message_content = Telegram::Bot::Types::InputTextMessageContent.new(message_text: 'Very interesting text goes here'
)

Telegram::Bot::Types::InlineQueryResultArticle.new(id: 1, title: 'First article', input_message_content: input_message_content)

However, when I do that... I get the following error:

Telegram API has returned the error. (ok: "false", error_code: "400", description: "[Error]: Bad request: Field "input_message_content" must be of type Object")

Am I doing anything wrong? And also, the example in Inline Bots is outdated.

remember

hi ;)
how send message to remember or group with telegram-bot-ruby ?

Bot kick from chat exception

Hi
When some users add bot to chat and after that chat admins remove bot , script stop working and show error "bot kick from chat" . how can i resolve this issue? this is showstopper for me and my bot is going down.

Please assist me.

The unhandled exception with supergroups

After update group to supergroup with bot:
ruby/2.2.0/gems/telegram-bot-ruby-0.4.2/lib/telegram/bot/api.rb:56:incall': Telegram API has returned the error. (ok: "false", error_code: "400", description: "[Error]: Bad Request: group chat is migrated to supergroup chat", parameters: "{"migrate_to_chat_id"=>-*****************}") (Telegram::Bot::Exceptions::ResponseError)`

HTTP persistent connections and connection pool for a multithread bot

Hi Alexander
this is not a issue, just a note / maybe a suggestion for a README update, in the paragraph:
https://github.com/atipugin/telegram-bot-ruby#connection-pool-size

In your previous mail you kindly clarified to me the meaning of increasing the connection pool size. re-reading again your sentences, I feel very clear and I so propose to maybe share here and maybe it could be useful to update README with yourself words :-).

I quote yourself:

Connection pool is intended to handle situations when you need to do some heavy job (i.e. do some db queries, save/upload files etc) in a response to incoming message. So, instead of blocking main thread, you can do all your stuff in a separate thread and send response right from there. But you can't do it without having pool size > 1 because your main thread with #getUpdates has held one connection already. Increasing pool size in single-threaded code won't improve performance.

So, in case of subthreading, if I well understood you suggest to set Connection pool size = number of subthreads +1 (the main thread). That's correct ?

BTW, thinking about a real case of managing updates with separated threads, I have difficulties to establish a run-time metric to decide how to serve updates requests. I mean: suppose the chatbot is doing at the same time some "dialogs" with N users. And also suppose that in the context of each dialog, the bot may possibly access a DB or does a long task as a natural language processing...
In these scenario is not so easy to preemptly decide if an update processing will be fast or slow...

Maybe an idea could be to open a thread for each incoming request (=update), I mean using T threads pool and doing some round-robing routing ... but in this way I'm re-inventing the wheel, with a web server logic ;-) and I'd conclude that one have to adopt the webhooks approach (as I presented in my very draft BOTServer project) could be the right solution.

In general, my gist is that long polling is the way to dev and test bot application logic, possibly moving on a webhook update server to manage concurrent requests (many users chatting at the same time with a single bot). Please let me know if my reasoning fail, that's generally absolutely possible :-) !

Another topic slightly related: In my previous post I pointed out httprb gem library could be more performant than HTTPYparty + HTTP persisten gema dependencies. Maybe, to get best performances (and we have this performance obsession :-) ) maybe curb could be the final solution. I'll propose in future a possible migration on https://github.com/taf2/curb (ok there are pros and cons because in that way there is a dependency from libcurl).

Last but not list, I share here, under your suggestion, to maybe see comments by other peopl.
Again: not an issue so feeel free to close/whatever.

BTW, I just wrote to Telegram support https://web.telegram.org/#/im?p=@BotSupport, asking to add your gem in the Ruby language list: https://core.telegram.org/bots/samples#other-languages
because your gem is the more voted on github

Thanks for your work & time!
giorgio

What's the best way to check 502 response error?

Sometimes I get a 502 error response from telegram server and my bot terminates.
I've seen this commit 3f566b8 hence I was wondering if the following code is a good solution for my problem so that the bot just restarts (prints the error message) instead of closing the process.

Telegram::Bot::Client.run(token) do |bot|
  begin
    bot.listen do |message|
      case message.text
      when '/start'
        bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}")
      when '/stop'
        bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}")
      end
    end
  rescue Telegram::Bot::Exceptions::ResponseError => e
    if e.error_code.to_s == '502'
      puts 'telegram stuff, nothing to worry!'
    end
  end
end

send message with markdown

try this code:

            bot.api.send_message(chat_id: message.chat.id,
                               text: "~~some sample text~~",
                               parse_mode: 'Markdown')

with no affect.

PersistentHTTP::Error too many connection resets

Hello, I'm facing the following error with versions 0.3.2 and 0.3.4 of your gem (didn't try version 0.3.3), any idea? The error seems to occur randomly to me.

/home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:335:in `rescue in block in request': too many connection resets (due to end of file reached - EOFError) after 709 requests on 3292704 (PersistentHTTP::Error)
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:300:in `block in request'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:137:in `with_connection'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:299:in `request'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/httparty-0.13.5/lib/httparty/request.rb:101:in `perform'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/httparty-0.13.5/lib/httparty.rb:522:in `perform_request'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/httmultiparty-0.3.16/lib/httmultiparty.rb:124:in `post'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/api.rb:33:in `call'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/api.rb:28:in `method_missing'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:30:in `fetch_updates'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:26:in `block in listen'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:26:in `loop'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:26:in `listen'
        from cippabot.rb:36:in `block in <main>'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:22:in `run'
        from /home/cippaciong/telegrambot/.bundle/ruby/2.2.0/gems/telegram-bot-ruby-0.3.4/lib/telegram/bot/client.rb:10:in `run'
        from cippabot.rb:35:in `<main>'

get photo of user

Hi, I'm trying to get the user's photo URL using this bot.
Telegram Bot API has a UserProfilePhotos object for this. does the bot support this?
Thanks.

Connection type towards Telegram

How can I choose the connection protocol towards Telegram?
The gem try to establish a connection through ipv6 in a dual stack environment (ipv4 + ipv6) but I need to use ipv4. It's possibile choose?

Error on photo sending (400)

My bot can't send a photo.

#initialization above
image_file = File.new('selection.png')
p "BeforeBot"
Telegram::Bot::Client.run(token) do |bot|
  bot.listen do |message|
    case message.text
    when '/fetch'
      p "BeforeResponse"
      bot.api.send_photo(chat_id: message.chat.id, photo: image_file)
      p "AfterResponse"
    end
  end
end
p "AfterBot"

It sticks on "BeforeResponse" stage. Then after 1-2 minutes console says:

/home/vova/.rvm/gems/ruby-2.2.1/gems/telegram-bot-ruby-0.4.0/lib/telegram/bot/api.rb:49:in `call': Telegram API has returned the error. (ok: "false", error_code: "400", description: "[Error]: Bad Request: Wrong persistent file_id specified: contains wrong characters or have wrong length"(Telegram::Bot::Exceptions::ResponseError)

Cannot send files anymore (version 0.5.0)

Hello,
after the 0.5.0 release I'm not able to send files anymore.

bot.api.send_voice(chat_id: message.chat.id, voice: File.new(path), caption: caption)

I'm getting error 400 from telegram's API, telling that the file_id is too long or contains not allowed chars (I don't specify a file_id).

Downgrading to version 0.4.2 fixes the issue.

Some arguments

Is there anyway to create commands like
"/photo (custom_value) (custom_value)"
And arguments like that?

Sorry for my bad english

Loop Error "403 - Bot was blocked by the user"

Hello, I've got a problem with my bot described by this scenario:

  1. The bot is inactive on my server (nothing is running).
  2. I send a message to my bot (like /start) and then i stop it (block) through Android Telegram.
  3. I start the bot on the server.
  4. The bot gets the /start request, sends its reply and of course it receives a "403 Bot was blocked by the user" error.
  5. The /start request is not removed from getUpdates and the bot keeps getting the 403 error in a loop.

I reported the error to the BotSupport channel and they told to increase the offset by 1 to solve the issue but looking at the gem code it seems that the offset variable is not exposed by any method (am I wrong?)

How can I solve this problem? Is there a way to handle the exception with a retry increasing the offset at the same time?

(might be related to #29 )

too many connection resets (due to end of file reached - EOFError) PersistentHTTP::Error

Hi,
My bot crashed with this error. From the look of it, it does not seem like it is coming from my code. It happened after my bot was running for 1 or 2 days.

/var/lib/gems/2.0.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:335:in `rescue in block in request': too many connection resets (due to end of file reached - EOFError) after 1729 requests on 27144020 (PersistentHTTP::Error)
        from /var/lib/gems/2.0.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:300:in `block in request'
        from /var/lib/gems/2.0.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:137:in `with_connection'
        from /var/lib/gems/2.0.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:299:in `request'
        from /var/lib/gems/2.0.0/gems/httparty-0.13.5/lib/httparty/request.rb:101:in `perform'
        from /var/lib/gems/2.0.0/gems/httparty-0.13.5/lib/httparty.rb:522:in `perform_request'
        from /var/lib/gems/2.0.0/gems/httmultiparty-0.3.16/lib/httmultiparty.rb:124:in `post'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/api.rb:36:in `call'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/api.rb:31:in `method_missing'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/client.rb:34:in `fetch_updates'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/client.rb:29:in `listen'
        from bot.rb:62:in `block in run'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/client.rb:22:in `run'
        from /var/lib/gems/2.0.0/gems/telegram-bot-ruby-0.3.6/lib/telegram/bot/client.rb:10:in `run'
        from bot.rb:61:in `run'
        from bot.rb:72:in `<main>'

Answers ReplyKeyboardMarkup

How can I get the ReplyKeyboardMarkup answer to interact with the user?
I've tried something like

puts answers

for the given code

option = 'What you wanna do?'
        answers =
            Telegram::Bot::Types::ReplyKeyboardMarkup
                .new(keyboard: [%w(Add Remove), %w(Search)], one_time_keyboard: true)
        bot.api.send_message(chat_id: message.chat.id, text: option, reply_markup: answers)

but just returned an object.

Thanks

problem with InlineQueryResultArticle

Got an error while trying to use inline queries, particularly InlineQueryResultArticle from readme
/Library/Ruby/Gems/2.0.0/gems/telegram-bot-ruby-0.4.2/lib/telegram/bot/api.rb:80:inblock in jsonify_inline_query_results': undefined method to_h' for #<Telegram::Bot::Types::InlineQueryResultArticle:0x007fd8ebb90db8> (NoMethodError)

Faraday Exception on 502

Hi,
I've got two bots running, with one using the old version (before Telegram API 2.0) and one using the new one (using Faraday).

I handle exceptions by

rescue StandardError => e
  puts e.message
  puts e.backtrace.select{ |err| err =~ /tulul/ }.join(', ')
  retry
end

The old one showed this error message:

Telegram API has returned the error. (error_code: "502", uri: "https://api.telegram.org/bot168860534:AAHux5hMU96avnuCcSvJaMF84F8Nnzw9-i0/getUpdates")
/home/araishikeiwai/lycantulul_bot/lib/lycantulul_bot/lycantulul_bot.rb:4:in `block in start', /home/araishikeiwai/lycantulul_bot/lib/lycantulul_bot/lycantulul_bot.rb:3:in `start', /home/araishikeiwai/lycantulul_bot/Rakefile:19:in `block (2 levels) in <top (required)>'

When the new one showed:

NoMethodError: undefined method `request' for #<Faraday::Response:0x9609a24>
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:26:in `rescue in data'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:23:in `data'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:13:in `to_s'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:83:in `message'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:83:in `rescue in start'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:5:in `start'
/home/araishikeiwai/tulul_stats_bot/Rakefile:17:in `block (2 levels) in <top (required)>'
JSON::ParserError: 757: unexpected token at '<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `parse'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `parse'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:24:in `data'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:13:in `to_s'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:83:in `message'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:83:in `rescue in start'
/home/araishikeiwai/tulul_stats_bot/lib/tulul_stats_bot/tulul_stats_bot.rb:5:in `start'
/home/araishikeiwai/tulul_stats_bot/Rakefile:17:in `block (2 levels) in <top (required)>'
/home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:26:in `rescue in data': undefined method `request' for #<Faraday::Response:0x9609a24> (NoMethodError)
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:23:in `data'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/telegram-bot-ruby-0.5.0.beta2/lib/telegram/bot/exceptions/response_error.rb:13:in `to_s'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:222:in `message'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:222:in `display_exception_message_details'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:209:in `display_exception_details'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:211:in `display_exception_details'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:211:in `display_exception_details'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:198:in `display_error_message'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:185:in `rescue in standard_exception_handling'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:176:in `standard_exception_handling'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/lib/rake/application.rb:75:in `run'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/gems/rake-11.1.2/bin/rake:33:in `<top (required)>'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/bin/rake:23:in `load'
        from /home/araishikeiwai/.rvm/gems/ruby-2.1.0/bin/rake:23:in `<main>'

Is there a way to restrict the acces to the bot savely?

I want to be able to share inforamtion to certain users.
Is it safe enough to do something like:

Telegram::Bot::Client.run(token) do |bot|
  bot.listen do |message|

    case message.text
      if message.from.id == "My super secret id"
    when '/start'
      puts message.from.inspect
      bot.api.sendMessage(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}")
    when '/stop'
      bot.api.sendMessage(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}")
    end
    else
      bot.api.sendMessage(chat_id: message.chat.id, text: "Not authorized")
    end
  end
end

Any better/safer way?

File Upload not working

The file upload code is not working and causing bots to hang. The following code in my bots on OpenShift & Heroku was working until about 3 days ago. There are no error messages being thrown to log files

bot.api.send_photo(chat_id: message.from.id, photo: Faraday::UploadIO.new('creative.png', 'image/jpeg'))

Has something changed?

SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)

Can't connect to telegram API. This answer can possibly help resolve the issue: http://stackoverflow.com/questions/25814210/opensslsslsslerror-ssl-connect-syscall-returned-5-errno-0-state-sslv3-read

SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)
(Ubuntu 12.04, ruby 2.0.0p481 (2014-05-08 revision 45883) [x86_64-linux])

/usr/local/lib/ruby/2.0.0/net/http.rb:918:in `connect': SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)
    from /usr/local/lib/ruby/2.0.0/net/http.rb:918:in `block in connect'
    from /usr/local/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
    from /usr/local/lib/ruby/2.0.0/net/http.rb:918:in `connect'
    from /usr/local/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
    from /usr/local/lib/ruby/2.0.0/net/http.rb:857:in `start'
    from /usr/local/lib/ruby/gems/2.0.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:253:in `block in initialize'
    from /usr/local/lib/ruby/gems/2.0.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:194:in `call'
    from /usr/local/lib/ruby/gems/2.0.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:194:in `renew'
    from /usr/local/lib/ruby/gems/2.0.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:102:in `checkout'
    from /usr/local/lib/ruby/gems/2.0.0/gems/gene_pool-1.4.1/lib/gene_pool.rb:134:in `with_connection'
    from /usr/local/lib/ruby/gems/2.0.0/gems/persistent_http-1.0.6/lib/persistent_http.rb:299:in `request'
    from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.13.5/lib/httparty/request.rb:101:in `perform'
    from /usr/local/lib/ruby/gems/2.0.0/gems/httparty-0.13.5/lib/httparty.rb:522:in `perform_request'
    from /usr/local/lib/ruby/gems/2.0.0/gems/httmultiparty-0.3.16/lib/httmultiparty.rb:124:in `post'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/api.rb:32:in `call'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/api.rb:27:in `method_missing'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:27:in `block in listen'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:26:in `loop'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:26:in `listen'
    from radiokpi-bot.rb:18:in `block in runbot'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:22:in `run'
    from /usr/local/lib/ruby/gems/2.0.0/gems/telegram-bot-ruby-0.3.1/lib/telegram/bot/client.rb:10:in `run'

Keep getting a QUERY_ID_INVALID exception

Hey I keep receiving this error when trying to make Inline work

#<Telegram::Bot::Exceptions::ResponseError: Telegram API has returned the error. (ok: "false", error_code: "400", description: "[Error]: Bad Request: QUERY_ID_INVALID")>

And this is my stacktrace

C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/api.rb:49:in `call'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/api.rb:40:in `method_missing'
main.rb:135:in `block (2 levels) in <main>'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:43:in `block in fetch_updates'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:38:in `each'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:38:in `fetch_updates'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:30:in `listen'
main.rb:121:in `block in <main>'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:23:in `run'
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/telegram-bot-ruby-0.4.1/lib/telegram/bot/client.rb:11:in `run'
main.rb:15:in `<main>'

With my own lines of code looking like this:

135: bot.api.answer_inline_query(inline_query_id: message.id, results: results)
121: bot.listen do |message|
15: Telegram::Bot::Client.run(token) do |bot|

As far as I can see it has something to do with the getting update part. The query_id changes when new updates are gathered which means that request take are a bit slow will continue to be computed while the id changes.

EDIT: sorry for the close, reopen - was a mistake
Now I have tried parsing an overwriting timeout var to the Client.run method like so:

Telegram::Bot::Client.run(token, timeout: 100) do |bot|

But it doesn't seem to help.

getBot()

Привет.
На сколько я смог понять, бот стартует и "слушает" сообщения от пользователей. Таким образом, есть возможность "отвечать" им. Но что, если необходимо просто напрямую написать что-то? Например, отправить новость. Для этого мне нужно получить объект bot и, зная chat_id, отправить сообщение. Так как можно реализовать это используя твой gem?
Спасибо.

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.