atipugin / telegram-bot-ruby

Ruby wrapper for Telegram's Bot API
https://core.telegram.org/bots/api
Do What The F*ck You Want To Public License
1.35k stars 218 forks source link

undefined method 'from' for nil:NilClass #226

Closed TheStu closed 1 year ago

TheStu commented 3 years ago

Started seeing undefined method 'from' for nil:NilClass about 12 hours ago. Any message to the bot seems to trigger it. Doesn't correspond to any code changes on our implementation of the bot. It does however seem to correspond to the latest release of the Telegram Bot API (https://core.telegram.org/bots/api#march-9-2021). We're running an implementation of the bot that has the same basic structure as the example in the readme:

Telegram::Bot::Client.run(ENV['TELEGRAM_AUTHORIZATION_TOKEN_V2']) do |bot|
  bot.listen do |message|
    begin
      case message.text
      ...
    end
  end
end

All calls to from are coded like this: message.from.present? ? message.from.first_name : 'Telegram User'

This code has been successfully working for years, basically untouched. Not entirely sure what went wrong. The error would imply that message is nil, but to get to any calls to message.from, the call to message.text would have to evaluate to something.

Any insights are much appreciated!

TheStu commented 3 years ago

I fixed this by adding next if message.nil? to the top of the message block. I don't know if this is a bug or if some messages are expected to be nil. If this is expected behavior, feel free to close this.

ivanovaleksey commented 3 years ago

Hi @TheStu, Could you provide any logs? It would be nice to see what exactly the bot is receiving from Telegram Bot API.

Logging incoming message is already supported. You can pass a logger implementation as an option like here.

TheStu commented 3 years ago

Sure I've added logging, will update if / when another nil message appears.

atipugin commented 3 years ago

Hi @TheStu, Hard to say without actual logs, but feels like it somehow related to recent API update. Please post collected logs if issue occurs again

TheStu commented 3 years ago

Had 3 more of these nil messages in the last 24 hours. From logs, all 3 look like this: INFO -- : Incoming message: text="" uid=

If there's anything else you want me to try, happy to do it.

ivanovaleksey commented 3 years ago

Thanks @TheStu. I think it would be interesting to see an update itself. Maybe you can log data here?

ldebortoli commented 3 years ago

https://core.telegram.org/bots/api#chatmemberupdated

Some examples

JSON: {"update_id"=>800375404, "my_chat_member"=>{"chat"=>{"id"=>1686360252, "first_name"=>"Baki Hanma", "type"=>"private"}, "from"=>{"id"=>1686360252, "is_bot"=>false, "first_name"=>"Baki Hanma", "language_code"=>"es"}, "date"=>1615359651, "old_chat_member"=>{"user"=>{"id"=>666864939, "is_bot"=>true, "first_name"=>"Dankie", "username"=>"dankiebot"}, "status"=>"member"}, "new_chat_member"=>{"user"=>{"id"=>666864939, "is_bot"=>true, "first_name"=>"Dankie", "username"=>"dankiebot"}, "status"=>"kicked", "until_date"=>0}}}

{"update_id"=>800341877, "my_chat_member"=>{"chat"=>{"id"=>-1001190057467, "title"=>"Chat Black Clover", "username"=>"Chat_BlackClover", "type"=>"supergroup"}, "from"=>{"id"=>1424079759, "is_bot"=>false, "first_name"=>"ℳ𝒾ℊ𝓊ℯ𝓁", "username"=>"Yami_Sukehiro23", "language_code"=>"es"}, "date"=>1615346331, "old_chat_member"=>{"user"=>{"id"=>666864939, "is_bot"=>true, "first_name"=>"Dankie", "username"=>"dankiebot"}, "status"=>"administrator", "can_be_edited"=>false, "can_manage_chat"=>true, "can_change_info"=>true, "can_delete_messages"=>true, "can_invite_users"=>true, "can_restrict_members"=>true, "can_pin_messages"=>true, "can_promote_members"=>false, "can_manage_voice_chats"=>true, "is_anonymous"=>false}, "new_chat_member"=>{"user"=>{"id"=>666864939, "is_bot"=>true, "first_name"=>"Dankie", "username"=>"dankiebot"}, "status"=>"restricted", "until_date"=>0, "can_send_messages"=>false, "can_send_media_messages"=>false, "can_send_polls"=>false, "can_send_other_messages"=>false, "can_add_web_page_previews"=>false, "can_change_info"=>false, "can_invite_users"=>false, "can_pin_messages"=>false, "is_member"=>true}}}

TheStu commented 3 years ago

data that triggered a nil message:

INFO -- : {"update_id"=>488112826, "my_chat_member"=>{"chat"=>{"id"=>817383630, "first_name"=>"Shubham", "username"=>"Shubhamp17", "type"=>"private"}, "from"=>{"id"=>817383630, "is_bot"=>false, "first_name"=>"Shubham", "username"=>"Shubhamp17"}, "date"=>1615441774, "old_chat_member"=>{"user"=>{"id"=>1073977886, "is_bot"=>true, "first_name"=>"TradrPro™ Alerts", "username"=>"tradr_pro_alerts_bot"}, "status"=>"member"}, "new_chat_member"=>{"user"=>{"id"=>1073977886, "is_bot"=>true, "first_name"=>"TradrPro™ Alerts", "username"=>"tradr_pro_alerts_bot"}, "status"=>"kicked", "until_date"=>0}}}

ivanovaleksey commented 3 years ago

@ldebortoli @TheStu thanks for the examples. I am not sure about the initial problem

the call to message.text would have to evaluate to something

but I think we need to add support for the new fields in Update type: my_chat_member and chat_member.

I have opened #228 thought I don't have time right now to test it. It would be great if you could try to use this version to ensure it fixes the problem.

P.S. I have done a quick testing in the console. It is parsing provided examples correctly. So now current_message will be not nil but ChatMemberUpdated instance.

atipugin commented 3 years ago

@TheStu #228 was merged into master, please give it a try

TheStu commented 3 years ago

Great thanks, I've got it running, seems good. I'll update if I see any more nil messages.

TheStu commented 3 years ago

One thing, newly added types / fields don't respond to .text, so the basic example in the readme no longer works. Don't know if a code change makes sense, or just adding next unless message.respond_to?(:text) to the readme examples does.

undefined method 'text' for #<Telegram::Bot::Types::ChatMemberUpdated:0x00000009f5a448>

atipugin commented 3 years ago

I suggest you to check message type before doing anything with it, because message can be an instance of any of these classes - https://github.com/atipugin/telegram-bot-ruby/blob/master/lib/telegram/bot/types/update.rb#L6-L18. Something like this:

Telegram::Bot::Client.run(ENV['TELEGRAM_AUTHORIZATION_TOKEN_V2']) do |bot|
  bot.listen do |message|
    case message
    when Telegram::Bot::Types::Message
      process_message(message)
    when Telegram::Bot::Types::PollAnswer
      process_poll_answer(message)
    else
      bot.logger.info('Not sure what to do with this type of message')
    end
  end
end
github-actions[bot] commented 1 year ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.