├── .editorconfig ├── .env.sample ├── .github └── workflows │ ├── ci.yml │ └── stale.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── data └── type_attributes.json ├── examples └── bot.rb ├── lib └── telegram │ ├── bot.rb │ └── bot │ ├── api.rb │ ├── api │ └── endpoints.rb │ ├── client.rb │ ├── configuration.rb │ ├── exceptions │ ├── base.rb │ └── response_error.rb │ ├── null_logger.rb │ ├── types.rb │ ├── types │ ├── affiliate_info.rb │ ├── animation.rb │ ├── audio.rb │ ├── background_fill.rb │ ├── background_fill_freeform_gradient.rb │ ├── background_fill_gradient.rb │ ├── background_fill_solid.rb │ ├── background_type.rb │ ├── background_type_chat_theme.rb │ ├── background_type_fill.rb │ ├── background_type_pattern.rb │ ├── background_type_wallpaper.rb │ ├── base.rb │ ├── birthdate.rb │ ├── bot_command.rb │ ├── bot_command_scope.rb │ ├── bot_command_scope_all_chat_administrators.rb │ ├── bot_command_scope_all_group_chats.rb │ ├── bot_command_scope_all_private_chats.rb │ ├── bot_command_scope_chat.rb │ ├── bot_command_scope_chat_administrators.rb │ ├── bot_command_scope_chat_member.rb │ ├── bot_command_scope_default.rb │ ├── bot_description.rb │ ├── bot_name.rb │ ├── bot_short_description.rb │ ├── business_connection.rb │ ├── business_intro.rb │ ├── business_location.rb │ ├── business_messages_deleted.rb │ ├── business_opening_hours.rb │ ├── business_opening_hours_interval.rb │ ├── callback_game.rb │ ├── callback_query.rb │ ├── chat.rb │ ├── chat_administrator_rights.rb │ ├── chat_background.rb │ ├── chat_boost.rb │ ├── chat_boost_added.rb │ ├── chat_boost_removed.rb │ ├── chat_boost_source.rb │ ├── chat_boost_source_gift_code.rb │ ├── chat_boost_source_giveaway.rb │ ├── chat_boost_source_premium.rb │ ├── chat_boost_updated.rb │ ├── chat_full_info.rb │ ├── chat_invite_link.rb │ ├── chat_join_request.rb │ ├── chat_location.rb │ ├── chat_member.rb │ ├── chat_member_administrator.rb │ ├── chat_member_banned.rb │ ├── chat_member_left.rb │ ├── chat_member_member.rb │ ├── chat_member_owner.rb │ ├── chat_member_restricted.rb │ ├── chat_member_updated.rb │ ├── chat_permissions.rb │ ├── chat_photo.rb │ ├── chat_shared.rb │ ├── chosen_inline_result.rb │ ├── compactable.rb │ ├── contact.rb │ ├── copy_text_button.rb │ ├── dice.rb │ ├── document.rb │ ├── encrypted_credentials.rb │ ├── encrypted_passport_element.rb │ ├── error.rb │ ├── external_reply_info.rb │ ├── file.rb │ ├── force_reply.rb │ ├── forum_topic.rb │ ├── forum_topic_closed.rb │ ├── forum_topic_created.rb │ ├── forum_topic_edited.rb │ ├── forum_topic_reopened.rb │ ├── game.rb │ ├── game_high_score.rb │ ├── general_forum_topic_hidden.rb │ ├── general_forum_topic_unhidden.rb │ ├── gift.rb │ ├── gifts.rb │ ├── giveaway.rb │ ├── giveaway_completed.rb │ ├── giveaway_created.rb │ ├── giveaway_winners.rb │ ├── inaccessible_message.rb │ ├── inline_keyboard_button.rb │ ├── inline_keyboard_markup.rb │ ├── inline_query.rb │ ├── inline_query_result.rb │ ├── inline_query_result_article.rb │ ├── inline_query_result_audio.rb │ ├── inline_query_result_cached_audio.rb │ ├── inline_query_result_cached_document.rb │ ├── inline_query_result_cached_gif.rb │ ├── inline_query_result_cached_mpeg4_gif.rb │ ├── inline_query_result_cached_photo.rb │ ├── inline_query_result_cached_sticker.rb │ ├── inline_query_result_cached_video.rb │ ├── inline_query_result_cached_voice.rb │ ├── inline_query_result_contact.rb │ ├── inline_query_result_document.rb │ ├── inline_query_result_game.rb │ ├── inline_query_result_gif.rb │ ├── inline_query_result_location.rb │ ├── inline_query_result_mpeg4_gif.rb │ ├── inline_query_result_photo.rb │ ├── inline_query_result_venue.rb │ ├── inline_query_result_video.rb │ ├── inline_query_result_voice.rb │ ├── inline_query_results_button.rb │ ├── input_contact_message_content.rb │ ├── input_invoice_message_content.rb │ ├── input_location_message_content.rb │ ├── input_media.rb │ ├── input_media_animation.rb │ ├── input_media_audio.rb │ ├── input_media_document.rb │ ├── input_media_photo.rb │ ├── input_media_video.rb │ ├── input_message_content.rb │ ├── input_paid_media.rb │ ├── input_paid_media_photo.rb │ ├── input_paid_media_video.rb │ ├── input_poll_option.rb │ ├── input_sticker.rb │ ├── input_text_message_content.rb │ ├── input_venue_message_content.rb │ ├── invoice.rb │ ├── keyboard_button.rb │ ├── keyboard_button_poll_type.rb │ ├── keyboard_button_request_chat.rb │ ├── keyboard_button_request_users.rb │ ├── labeled_price.rb │ ├── link_preview_options.rb │ ├── location.rb │ ├── login_url.rb │ ├── mask_position.rb │ ├── maybe_inaccessible_message.rb │ ├── menu_button.rb │ ├── menu_button_commands.rb │ ├── menu_button_default.rb │ ├── menu_button_web_app.rb │ ├── message.rb │ ├── message_auto_delete_timer_changed.rb │ ├── message_entity.rb │ ├── message_id.rb │ ├── message_origin.rb │ ├── message_origin_channel.rb │ ├── message_origin_chat.rb │ ├── message_origin_hidden_user.rb │ ├── message_origin_user.rb │ ├── message_reaction_count_updated.rb │ ├── message_reaction_updated.rb │ ├── order_info.rb │ ├── paid_media.rb │ ├── paid_media_info.rb │ ├── paid_media_photo.rb │ ├── paid_media_preview.rb │ ├── paid_media_purchased.rb │ ├── paid_media_video.rb │ ├── passport_data.rb │ ├── passport_element_error.rb │ ├── passport_element_error_data_field.rb │ ├── passport_element_error_file.rb │ ├── passport_element_error_files.rb │ ├── passport_element_error_front_side.rb │ ├── passport_element_error_reverse_side.rb │ ├── passport_element_error_selfie.rb │ ├── passport_element_error_translation_file.rb │ ├── passport_element_error_translation_files.rb │ ├── passport_element_error_unspecified.rb │ ├── passport_file.rb │ ├── pattern_matching.rb │ ├── photo_size.rb │ ├── poll.rb │ ├── poll_answer.rb │ ├── poll_option.rb │ ├── pre_checkout_query.rb │ ├── prepared_inline_message.rb │ ├── proximity_alert_triggered.rb │ ├── reaction_count.rb │ ├── reaction_type.rb │ ├── reaction_type_custom_emoji.rb │ ├── reaction_type_emoji.rb │ ├── reaction_type_paid.rb │ ├── refunded_payment.rb │ ├── reply_keyboard_markup.rb │ ├── reply_keyboard_remove.rb │ ├── reply_parameters.rb │ ├── response_parameters.rb │ ├── revenue_withdrawal_state.rb │ ├── revenue_withdrawal_state_failed.rb │ ├── revenue_withdrawal_state_pending.rb │ ├── revenue_withdrawal_state_succeeded.rb │ ├── sent_web_app_message.rb │ ├── shared_user.rb │ ├── shipping_address.rb │ ├── shipping_option.rb │ ├── shipping_query.rb │ ├── star_transaction.rb │ ├── star_transactions.rb │ ├── sticker.rb │ ├── sticker_set.rb │ ├── story.rb │ ├── successful_payment.rb │ ├── switch_inline_query_chosen_chat.rb │ ├── text_quote.rb │ ├── transaction_partner.rb │ ├── transaction_partner_affiliate_program.rb │ ├── transaction_partner_chat.rb │ ├── transaction_partner_fragment.rb │ ├── transaction_partner_other.rb │ ├── transaction_partner_telegram_ads.rb │ ├── transaction_partner_telegram_api.rb │ ├── transaction_partner_user.rb │ ├── update.rb │ ├── user.rb │ ├── user_chat_boosts.rb │ ├── user_profile_photos.rb │ ├── users_shared.rb │ ├── venue.rb │ ├── video.rb │ ├── video_chat_ended.rb │ ├── video_chat_participants_invited.rb │ ├── video_chat_scheduled.rb │ ├── video_chat_started.rb │ ├── video_note.rb │ ├── voice.rb │ ├── web_app_data.rb │ ├── web_app_info.rb │ ├── webhook_info.rb │ └── write_access_allowed.rb │ └── version.rb ├── rakelib ├── parse_schema.rake ├── rebuild_types.rake └── templates │ ├── empty_type.erb │ └── type.erb ├── spec ├── cassettes │ ├── Telegram_Bot_Api │ │ ├── _call │ │ │ ├── has_result.yml │ │ │ ├── has_status.yml │ │ │ ├── returns_hash.yml │ │ │ └── when_token_is_invalid │ │ │ │ └── raises_an_error.yml │ │ ├── _getMe │ │ │ └── 1_3_1.yml │ │ ├── _getMyCommands │ │ │ └── 1_6_1.yml │ │ ├── _getMyDescription │ │ │ └── 1_5_1.yml │ │ └── _getMyName │ │ │ └── 1_4_1.yml │ ├── Telegram_Bot_Client │ │ └── _run │ │ │ └── returns_hash.yml │ └── Telegram_Bot_Exceptions_ResponseError │ │ ├── _data │ │ └── 1_3_1.yml │ │ ├── _error_code │ │ └── 1_1_1.yml │ │ ├── _to_s │ │ └── 1_2_1.yml │ │ └── has_error_code.yml ├── lib │ └── telegram │ │ └── bot │ │ ├── api_spec.rb │ │ ├── client_spec.rb │ │ ├── exceptions │ │ └── response_error_spec.rb │ │ └── types_spec.rb └── spec_helper.rb └── telegram-bot-ruby.gemspec /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | BOT_API_ENV=test 2 | BOT_API_TOKEN= 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | ruby: 15 | - 2.7 16 | - 3.2 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | - name: Set up Ruby 21 | uses: ruby/setup-ruby@v1 22 | with: 23 | ruby-version: ${{ matrix.ruby }} 24 | bundler-cache: true 25 | - name: Run Rubocop 26 | run: bundle exec rubocop 27 | 28 | test: 29 | runs-on: ubuntu-latest 30 | strategy: 31 | matrix: 32 | ruby: 33 | - 2.7 34 | - 3.2 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v3 38 | - name: Set up Ruby 39 | uses: ruby/setup-ruby@v1 40 | with: 41 | ruby-version: ${{ matrix.ruby }} 42 | bundler-cache: true 43 | - name: Run specs 44 | run: bundle exec rspec 45 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Close stale issues and PRs 3 | on: 4 | schedule: 5 | - cron: 40 * * * * 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v7 12 | with: 13 | days-before-close: 7 14 | days-before-stale: 60 15 | stale-issue-label: stale 16 | stale-issue-message: 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. 17 | stale-pr-label: stale 18 | stale-pr-message: This PR 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. 19 | operations-per-run: 500 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Gemfile.lock 2 | 3 | .bundle/ 4 | .env 5 | pkg/ 6 | tmp/ 7 | vendor/bundle/ 8 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | --color 3 | --warnings 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | require: 3 | - rubocop-rake 4 | - rubocop-rspec 5 | - rubocop-performance 6 | 7 | AllCops: 8 | NewCops: enable 9 | TargetRubyVersion: 2.7 10 | 11 | Style/Documentation: 12 | Enabled: false 13 | 14 | Metrics/BlockLength: 15 | AllowedMethods: 16 | - context 17 | - describe 18 | - task 19 | Metrics/ClassLength: 20 | Exclude: 21 | - lib/telegram/bot/api/endpoints.rb 22 | Metrics/MethodLength: 23 | Exclude: 24 | - spec/**/* 25 | 26 | Layout/LineLength: 27 | Max: 120 28 | 29 | RSpec/MultipleMemoizedHelpers: 30 | Enabled: false 31 | RSpec/NestedGroups: 32 | Enabled: false 33 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.4.0 4 | 5 | ### Added 6 | 7 | - [Bot API 8.3](https://core.telegram.org/bots/api-changelog#february-12-2025) [#323](https://github.com/atipugin/telegram-bot-ruby/pull/323) 8 | 9 | ## 2.3.0 10 | 11 | ### Added 12 | 13 | - [Bot API 8.2](https://core.telegram.org/bots/api#january-1-2025) [#322](https://github.com/atipugin/telegram-bot-ruby/pull/322) 14 | 15 | ## 2.2.0 16 | 17 | ### Added 18 | 19 | - [Bot API 8.1](https://core.telegram.org/bots/api-changelog#december-4-2024) [#319](https://github.com/atipugin/telegram-bot-ruby/pull/319) 20 | 21 | ## 2.1.0 22 | 23 | ### Added 24 | 25 | - [Bot API 8.0](https://core.telegram.org/bots/api-changelog#november-17-2024) (thx [@seorgiy](https://github.com/seorgiy)) 26 | 27 | ## 2.0.0 28 | 29 | ### Added 30 | 31 | - [Bot API 7.0](https://core.telegram.org/bots/api-changelog#december-29-2023) 32 | 33 | ### Changed 34 | 35 | - API method calls now return corresponding response objects ([#285](https://github.com/atipugin/telegram-bot-ruby/pull/285), thx [@AlexWayfer](https://github.com/AlexWayfer)) 36 | 37 | ## 1.0.0 38 | 39 | - Replace [virtus](https://github.com/solnic/virtus) with [dry-struct](https://github.com/dry-rb/dry-struct) 40 | - Use [zeitwerk](https://github.com/fxn/zeitwerk) for code loading 41 | - Implement [Bot API 6.4](https://core.telegram.org/bots/api-changelog#december-30-2022) 42 | - Implement [Bot API 6.5](https://core.telegram.org/bots/api-changelog#february-3-2023) 43 | 44 | ## 0.23.0 45 | 46 | - Rename `Telegram::Bot.configuration` options: 47 | - `timeout` to `connection_timeout` 48 | - `open_timeout` to `connection_open_timeout` 49 | - Fix issue with missing default value for long-polling timeout 50 | 51 | ## 0.21.0 52 | 53 | - Implement [Bot API 6.1](https://core.telegram.org/bots/api-changelog#june-20-2022) 54 | - Implement [Bot API 6.2](https://core.telegram.org/bots/api-changelog#august-12-2022) 55 | 56 | ## 0.20.0 57 | 58 | - Update `faraday` up to `2.0` 59 | 60 | ## 0.19.0 61 | 62 | - Implement [Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022) 63 | - Update `rubocop` up to `1.27` 64 | 65 | ## 0.18.0 66 | 67 | - Implement [Bot API 5.2](https://core.telegram.org/bots/api-changelog#april-26-2021) 68 | - Implement [Bot API 5.3](https://core.telegram.org/bots/api-changelog#june-25-2021) 69 | - Implement [Bot API 5.4](https://core.telegram.org/bots/api-changelog#november-5-2021) 70 | - Implement [Bot API 5.5](https://core.telegram.org/bots/api-changelog#december-7-2021) 71 | - Implement [Bot API 5.6](https://core.telegram.org/bots/api-changelog#december-30-2021) 72 | - Implement [Bot API 5.7](https://core.telegram.org/bots/api-changelog#january-31-2022) 73 | 74 | ## 0.17.0 75 | 76 | - Pin `faraday` to 1.0 77 | 78 | ## 0.16.0 79 | 80 | - Replace `inflecto` with `dry-inflector` 81 | - Update `virtus` up to 2.0 82 | 83 | ## 0.15.0 84 | 85 | - Implement [Bot API 5.1](https://core.telegram.org/bots/api-changelog#march-9-2021) 86 | 87 | ## 0.14.0 88 | 89 | - Implement [Bot API 5.0](https://core.telegram.org/bots/api-changelog#november-4-2020) 90 | 91 | ## 0.13.0 92 | 93 | - Implement [Bot API 4.9](https://core.telegram.org/bots/api-changelog#june-4-2020) 94 | - Implement [Bot API 4.8](https://core.telegram.org/bots/api-changelog#april-24-2020) 95 | - Implement [Bot API 4.7](https://core.telegram.org/bots/api-changelog#march-30-2020) 96 | 97 | ## 0.12.0 98 | 99 | - Implement [Bot API 4.5](https://core.telegram.org/bots/api-changelog#december-31-2019) and [Bot API 4.6](https://core.telegram.org/bots/api-changelog#january-23-2020) 100 | 101 | ## 0.11.0 102 | 103 | - Implement [Bot API 4.4](https://core.telegram.org/bots/api-changelog#july-29-2019) 104 | 105 | ## 0.10.1 106 | 107 | - Fix issue #202 with `Poll` messages and logging 108 | 109 | ## 0.10.0 110 | 111 | - Implement [Bot API 4.3](https://core.telegram.org/bots/api-changelog#may-31-2019) 112 | 113 | ## 0.9.1 114 | 115 | - Allow to configure API URL (thx [@markfrst][]) 116 | 117 | ## 0.9.0 118 | 119 | - Implement [Bot API 4.2](https://core.telegram.org/bots/api-changelog#april-14-2019) 120 | - Implement [Bot API 4.1](https://core.telegram.org/bots/api-changelog#august-27-2018) 121 | - Implement [Bot API 4.0](https://core.telegram.org/bots/api-changelog#july-26-2018) 122 | - Implement [Bot API 3.6](https://core.telegram.org/bots/api-changelog#february-13-2018) 123 | 124 | ## 0.8.6.1 125 | 126 | - Fix #163 127 | 128 | ## 0.8.6 129 | 130 | - Implement [Bot API 3.5](https://core.telegram.org/bots/api-changelog#november-17-2017) 131 | 132 | ## 0.8.5 133 | 134 | - Implement [Bot API 3.4](https://core.telegram.org/bots/api-changelog#october-11-2017) (thx [@ivanovaleksey][]) 135 | 136 | ## 0.8.4 137 | 138 | - Implement [Bot API 3.3](https://core.telegram.org/bots/api-changelog#august-23-2017) (thx [@ivanovaleksey][]) 139 | 140 | ## 0.8.3 141 | 142 | - Implement [Bot API 3.2](https://core.telegram.org/bots/api-changelog#july-21-2017) (thx [@ivanovaleksey][]) 143 | 144 | ## 0.8.2 145 | 146 | - Implement [Bot API 3.1](https://core.telegram.org/bots/api-changelog#june-30-2017) (thx [@ivanovaleksey][]) 147 | 148 | ## 0.8.1 149 | 150 | - Add [missing methods](https://github.com/atipugin/telegram-bot-ruby/pull/127) from earlier versions earlier 151 | 152 | ## 0.8.0 153 | 154 | - Implement [Bot API 3.0](https://core.telegram.org/bots/api-changelog#may-18-2017) (thx [@ivanovaleksey][]) 155 | 156 | ## 0.7.2 157 | 158 | - Bug fixes 159 | 160 | ## 0.7.1 161 | 162 | - Implement [Bot API 2.3.1](https://core.telegram.org/bots/api-changelog#december-4-2016) 163 | 164 | ## 0.7.0 165 | 166 | - Implement [Bot API 2.3](https://core.telegram.org/bots/api-changelog#november-21-2016) (thx [@ivanovaleksey][]) 167 | 168 | ## 0.6.0 169 | 170 | - Implement Bot API changes (October 3, 2016 API update) 171 | 172 | ## 0.5.2 173 | 174 | - Implement Bot API 2.1 changes 175 | 176 | ## 0.5.1 177 | 178 | - Update `Sticker` and `Message` objects (May 6, 2016 API update) 179 | 180 | ## 0.5.0 181 | 182 | - Replace [httparty](https://github.com/jnunemaker/httparty) with [faraday](https://github.com/lostisland/faraday) 183 | - Implement [Bot API 2.0](https://core.telegram.org/bots/2-0-intro) 184 | 185 | ## 0.4.2 186 | 187 | - Let `Client#logger` be overwritten later (use `attr_accessor` instead of `attr_reader`) 188 | 189 | [@ivanovaleksey]: https://github.com/ivanovaleksey 190 | [@markfrst]: https://github.com/markfrst 191 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gemspec 6 | 7 | gem 'dotenv', '~> 2.8' 8 | gem 'nokogiri', '~> 1.13' 9 | gem 'pry' 10 | gem 'rake', '~> 13.0' 11 | 12 | gem 'rspec', '~> 3.4' 13 | gem 'vcr', '~> 6.0' 14 | 15 | gem 'rubocop', '~> 1.66.1' 16 | gem 'rubocop-performance', '~> 1.18' 17 | gem 'rubocop-rake', '~> 0.6.0' 18 | gem 'rubocop-rspec', '~> 3.1.0' 19 | 20 | group :development do 21 | gem 'openapi3_parser', '~> 0.9.2' 22 | end 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | require 'bundler/setup' 5 | require 'rubocop/rake_task' 6 | require 'rspec/core/rake_task' 7 | 8 | RuboCop::RakeTask.new(:rubocop) do |task| 9 | task.fail_on_error = false 10 | task.options = %w[--force-exclusion] 11 | task.patterns = %w[{lib,spec}/**/*.rb Rakefile] 12 | task.requires << 'rubocop-rspec' 13 | end 14 | 15 | RSpec::Core::RakeTask.new(:spec) 16 | 17 | task default: :spec 18 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # frozen_string_literal: true 4 | 5 | require 'bundler/setup' 6 | require 'pry' 7 | 8 | require_relative '../lib/telegram/bot' 9 | 10 | Pry.start 11 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | 5 | bundle install 6 | -------------------------------------------------------------------------------- /examples/bot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rubygems' 4 | require 'telegram/bot' 5 | 6 | token = 'replace-me-with-your-real-token' 7 | 8 | Telegram::Bot::Client.run(token) do |bot| 9 | bot.listen do |message| 10 | case message 11 | when Telegram::Bot::Types::Message 12 | case message.text 13 | when '/start' 14 | bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}!") 15 | when '/end' 16 | bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}!") 17 | else 18 | bot.api.send_message(chat_id: message.chat.id, text: "I don't understand you :(") 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/telegram/bot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'logger' 4 | require 'json' 5 | require 'faraday' 6 | require 'faraday/multipart' 7 | require 'zeitwerk' 8 | require 'dry-struct' 9 | 10 | module Telegram 11 | module Bot 12 | class << self 13 | attr_writer :configuration 14 | end 15 | 16 | def self.configuration 17 | @configuration ||= Configuration.new 18 | end 19 | 20 | def self.configure 21 | yield(configuration) 22 | end 23 | end 24 | end 25 | 26 | loader = Zeitwerk::Loader.new 27 | loader.inflector = Zeitwerk::GemInflector.new(__FILE__) 28 | loader.inflector.inflect('endpoints' => 'ENDPOINTS') 29 | loader.push_dir("#{__dir__}/bot", namespace: Telegram::Bot) 30 | loader.setup 31 | -------------------------------------------------------------------------------- /lib/telegram/bot/api.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | class Api 6 | attr_reader :token, :url, :environment 7 | 8 | def initialize(token, url: 'https://api.telegram.org', environment: :production) 9 | @token = token 10 | @url = url 11 | @environment = environment.downcase.to_sym 12 | end 13 | 14 | def connection 15 | @connection ||= Faraday.new(url: url) do |faraday| 16 | faraday.request :multipart 17 | faraday.request :url_encoded 18 | faraday.adapter Telegram::Bot.configuration.adapter 19 | faraday.options.timeout = Telegram::Bot.configuration.connection_timeout 20 | faraday.options.open_timeout = Telegram::Bot.configuration.connection_open_timeout 21 | end 22 | end 23 | 24 | def method_missing(method_name, *args, &block) 25 | endpoint = method_name.to_s 26 | endpoint = camelize(endpoint) if endpoint.include?('_') 27 | 28 | return super unless ENDPOINTS.key?(endpoint) 29 | 30 | result = call(endpoint, *args) 31 | 32 | return result['ok'] unless (result = result['result']) 33 | 34 | ENDPOINTS[endpoint].call(result) 35 | end 36 | 37 | def respond_to_missing?(*args) 38 | method_name = args[0].to_s 39 | method_name = camelize(method_name) if method_name.include?('_') 40 | 41 | ENDPOINTS.key?(method_name) || super 42 | end 43 | 44 | def call(endpoint, raw_params = {}) 45 | params = build_params(raw_params) 46 | path = build_path(endpoint) 47 | response = connection.post(path, params) 48 | raise Exceptions::ResponseError.new(response: response) unless response.status == 200 49 | 50 | JSON.parse(response.body) 51 | end 52 | 53 | private 54 | 55 | def build_params(params) 56 | params.transform_values do |value| 57 | sanitize_value(value) 58 | end 59 | end 60 | 61 | def build_path(endpoint) 62 | path = "/bot#{token}/" 63 | path += 'test/' if environment == :test 64 | path + endpoint 65 | end 66 | 67 | def sanitize_value(value) 68 | jsonify_value(value) 69 | end 70 | 71 | def jsonify_value(value) 72 | jsonify_value?(value) ? value.to_json : value 73 | end 74 | 75 | def jsonify_value?(value) 76 | value.respond_to?(:to_compact_hash) || value.is_a?(Array) 77 | end 78 | 79 | def camelize(method_name) 80 | words = method_name.split('_') 81 | words.drop(1).map(&:capitalize!) 82 | words.join 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /lib/telegram/bot/api/endpoints.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | class Api 6 | ENDPOINTS = { 7 | 'getUpdates' => Types::Array.of(Types::Update), 8 | 'setWebhook' => Types::Bool, 9 | 'deleteWebhook' => Types::Bool, 10 | 'getWebhookInfo' => Types::WebhookInfo, 11 | 'getMe' => Types::User, 12 | 'sendMessage' => Types::Message, 13 | 'forwardMessage' => Types::Message, 14 | 'forwardMessages' => Types::Array.of(Types::MessageId), 15 | 'sendPhoto' => Types::Message, 16 | 'sendAudio' => Types::Message, 17 | 'sendDocument' => Types::Message, 18 | 'sendVideo' => Types::Message, 19 | 'sendVoice' => Types::Message, 20 | 'sendVideoNote' => Types::Message, 21 | 'sendMediaGroup' => Types::Array.of(Types::Message), 22 | 'sendLocation' => Types::Message, 23 | 'editMessageLiveLocation' => Types::Message | Types::Bool, 24 | 'stopMessageLiveLocation' => Types::Message | Types::Bool, 25 | 'sendVenue' => Types::Message, 26 | 'sendContact' => Types::Message, 27 | 'sendChatAction' => Types::Bool, 28 | 'setMessageReaction' => Types::Bool, 29 | 'getUserProfilePhotos' => Types::UserProfilePhotos, 30 | 'getFile' => Types::File, 31 | 'banChatMember' => Types::Bool, 32 | 'unbanChatMember' => Types::Bool, 33 | 'restrictChatMember' => Types::Bool, 34 | 'promoteChatMember' => Types::Bool, 35 | 'leaveChat' => Types::Bool, 36 | 'getChat' => Types::ChatFullInfo, 37 | 'getChatAdministrators' => Types::Array.of(Types::ChatMember), 38 | 'exportChatInviteLink' => Types::String, 39 | 'setChatPhoto' => Types::Bool, 40 | 'deleteChatPhoto' => Types::Bool, 41 | 'setChatTitle' => Types::Bool, 42 | 'setChatDescription' => Types::Bool, 43 | 'pinChatMessage' => Types::Bool, 44 | 'unpinChatMessage' => Types::Bool, 45 | 'getChatMembersCount' => Types::Integer, 46 | 'getChatMember' => Types::ChatMember, 47 | 'setChatStickerSet' => Types::Bool, 48 | 'deleteChatStickerSet' => Types::Bool, 49 | 'answerCallbackQuery' => Types::Bool, 50 | 'getUserChatBoosts' => Types::UserChatBoosts, 51 | 'editMessageText' => Types::Message | Types::Bool, 52 | 'editMessageCaption' => Types::Message | Types::Bool, 53 | 'editMessageReplyMarkup' => Types::Message | Types::Bool, 54 | 'deleteMessage' => Types::Bool, 55 | 'deleteMessages' => Types::Bool, 56 | 'sendSticker' => Types::Message, 57 | 'getStickerSet' => Types::StickerSet, 58 | 'uploadStickerFile' => Types::File, 59 | 'createNewStickerSet' => Types::Bool, 60 | 'addStickerToSet' => Types::Bool, 61 | 'setStickerPositionInSet' => Types::Bool, 62 | 'deleteStickerFromSet' => Types::Bool, 63 | 'answerInlineQuery' => Types::Bool, 64 | 'sendInvoice' => Types::Message, 65 | 'answerShippingQuery' => Types::Bool, 66 | 'answerPreCheckoutQuery' => Types::Bool, 67 | 'sendGame' => Types::Message, 68 | 'setGameScore' => Types::Message | Types::Bool, 69 | 'getGameHighScores' => Types::Array.of(Types::GameHighScore), 70 | 'setPassportDataErrors' => Types::Bool, 71 | 'editMessageMedia' => Types::Message | Types::Bool, 72 | 'sendAnimation' => Types::Message, 73 | 'sendPoll' => Types::Message, 74 | 'stopPoll' => Types::Poll, 75 | 'setChatPermissions' => Types::Bool, 76 | 'setChatAdministratorCustomTitle' => Types::Bool, 77 | 'sendDice' => Types::Message, 78 | 'getMyCommands' => Types::Array.of(Types::BotCommand), 79 | 'setMyCommands' => Types::Bool, 80 | 'deleteMyCommands' => Types::Bool, 81 | 'setStickerSetThumbnail' => Types::Bool, 82 | 'logOut' => Types::Bool, 83 | 'close' => Types::Bool, 84 | 'copyMessage' => Types::MessageId, 85 | 'copyMessages' => Types::Array.of(Types::MessageId), 86 | 'createChatInviteLink' => Types::ChatInviteLink, 87 | 'editChatInviteLink' => Types::ChatInviteLink, 88 | 'revokeChatInviteLink' => Types::ChatInviteLink, 89 | 'approveChatJoinRequest' => Types::Bool, 90 | 'declineChatJoinRequest' => Types::Bool, 91 | 'banChatSenderChat' => Types::Bool, 92 | 'unbanChatSenderChat' => Types::Bool, 93 | 'answerWebAppQuery' => Types::SentWebAppMessage, 94 | 'setChatMenuButton' => Types::Bool, 95 | 'getChatMenuButton' => Types::MenuButtonDefault | Types::MenuButtonCommands | Types::MenuButtonWebApp, 96 | 'setMyDefaultAdministratorRights' => Types::Bool, 97 | 'getMyDefaultAdministratorRights' => Types::ChatAdministratorRights, 98 | 'createInvoiceLink' => Types::String, 99 | 'editGeneralForumTopic' => Types::Bool, 100 | 'closeGeneralForumTopic' => Types::Bool, 101 | 'reopenGeneralForumTopic' => Types::Bool, 102 | 'hideGeneralForumTopic' => Types::Bool, 103 | 'unhideGeneralForumTopic' => Types::Bool, 104 | 'unpinAllGeneralForumTopicMessages' => Types::Bool, 105 | 'setMyName' => Types::Bool, 106 | 'getMyName' => Types::BotName, 107 | 'setMyDescription' => Types::Bool, 108 | 'getMyDescription' => Types::BotDescription, 109 | 'setMyShortDescription' => Types::Bool, 110 | 'getMyShortDescription' => Types::BotShortDescription, 111 | 'refundStarPayment' => Types::Bool, 112 | 'getStarTransactions' => Types::StarTransactions, 113 | 'sendPaidMedia' => Types::Message, 114 | 'createChatSubscriptionInviteLink' => Types::ChatInviteLink, 115 | 'editChatSubscriptionInviteLink' => Types::ChatInviteLink, 116 | 'getAvailableGifts' => Types::Gifts, 117 | 'sendGift' => Types::Bool, 118 | 'savePreparedInlineMessage' => Types::PreparedInlineMessage, 119 | 'editUserStarSubscription' => Types::Bool, 120 | 'setUserEmojiStatus' => Types::Bool, 121 | 'verifyUser' => Types::Bool, 122 | 'verifyChat' => Types::Bool, 123 | 'removeUserVerification' => Types::Bool, 124 | 'removeChatVerification' => Types::Bool 125 | }.freeze 126 | end 127 | end 128 | end 129 | -------------------------------------------------------------------------------- /lib/telegram/bot/client.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | class Client 6 | attr_reader :api, :options 7 | attr_accessor :logger 8 | 9 | def self.run(*args, &block) 10 | new(*args).run(&block) 11 | end 12 | 13 | def initialize(token, hash = {}) 14 | @options = default_options.merge(hash) 15 | @api = Api.new(token, url: options.delete(:url), environment: options.delete(:environment)) 16 | @logger = options.delete(:logger) 17 | end 18 | 19 | def run 20 | yield self 21 | end 22 | 23 | def listen(&block) 24 | logger.info('Starting bot') 25 | @running = true 26 | fetch_updates(&block) while @running 27 | end 28 | 29 | def stop 30 | @running = false 31 | end 32 | 33 | def fetch_updates 34 | api.getUpdates(options).each do |update| 35 | yield handle_update(update) 36 | end 37 | rescue Faraday::TimeoutError, Faraday::ConnectionFailed 38 | retry if @running 39 | end 40 | 41 | def handle_update(update) 42 | @options[:offset] = update.update_id.next 43 | message = update.current_message 44 | log_incoming_message(message) 45 | 46 | message 47 | end 48 | 49 | private 50 | 51 | def default_options 52 | { 53 | offset: 0, 54 | timeout: 20, 55 | logger: NullLogger.new, 56 | url: 'https://api.telegram.org', 57 | environment: :production 58 | } 59 | end 60 | 61 | def log_incoming_message(message) 62 | uid = message.respond_to?(:from) && message.from ? message.from.id : nil 63 | logger.info( 64 | format('Incoming message: text="%s" uid=%s', message: message, uid: uid) 65 | ) 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /lib/telegram/bot/configuration.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | class Configuration 6 | attr_accessor :adapter, :connection_open_timeout, :connection_timeout 7 | 8 | def initialize 9 | @adapter = Faraday.default_adapter 10 | @connection_open_timeout = 20 11 | @connection_timeout = 20 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/exceptions/base.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Exceptions 6 | class Base < StandardError; end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/telegram/bot/exceptions/response_error.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Exceptions 6 | class ResponseError < Base 7 | attr_reader :response 8 | 9 | def initialize(response:) 10 | @response = response 11 | 12 | super("Telegram API has returned the error. (#{data.map { |k, v| %(#{k}: #{v.inspect}) }.join(', ')})") 13 | end 14 | 15 | def error_code 16 | data[:error_code] || data['error_code'] 17 | end 18 | 19 | def data 20 | @data ||= begin 21 | JSON.parse(response.body) 22 | rescue JSON::ParserError 23 | { error_code: response.status, uri: response.env.url.to_s } 24 | end 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/telegram/bot/null_logger.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | class NullLogger < Logger 6 | def initialize(*); end # rubocop:disable Lint/MissingSuper 7 | 8 | def add(*); end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | include Dry.Types() 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/affiliate_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class AffiliateInfo < Base 7 | attribute? :affiliate_user, User 8 | attribute? :affiliate_chat, Chat 9 | attribute :commission_per_mille, Types::Integer 10 | attribute :amount, Types::Integer 11 | attribute? :nanostar_amount, Types::Integer 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/animation.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Animation < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :width, Types::Integer 10 | attribute :height, Types::Integer 11 | attribute :duration, Types::Integer 12 | attribute? :thumbnail, PhotoSize 13 | attribute? :file_name, Types::String 14 | attribute? :mime_type, Types::String 15 | attribute? :file_size, Types::Integer 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/audio.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Audio < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :duration, Types::Integer 10 | attribute? :performer, Types::String 11 | attribute? :title, Types::String 12 | attribute? :file_name, Types::String 13 | attribute? :mime_type, Types::String 14 | attribute? :file_size, Types::Integer 15 | attribute? :thumbnail, PhotoSize 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_fill.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | BackgroundFill = ( 9 | BackgroundFillSolid | 10 | BackgroundFillGradient | 11 | BackgroundFillFreeformGradient 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_fill_freeform_gradient.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundFillFreeformGradient < Base 7 | attribute :type, Types::String.constrained(eql: 'freeform_gradient').default('freeform_gradient') 8 | attribute :colors, Types::Array.of(Types::Integer) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_fill_gradient.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundFillGradient < Base 7 | attribute :type, Types::String.constrained(eql: 'gradient').default('gradient') 8 | attribute :top_color, Types::Integer 9 | attribute :bottom_color, Types::Integer 10 | attribute :rotation_angle, Types::Integer 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_fill_solid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundFillSolid < Base 7 | attribute :type, Types::String.constrained(eql: 'solid').default('solid') 8 | attribute :color, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | BackgroundType = ( 9 | BackgroundTypeFill | 10 | BackgroundTypeWallpaper | 11 | BackgroundTypePattern | 12 | BackgroundTypeChatTheme 13 | ) 14 | # rubocop:enable Naming/ConstantName 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_type_chat_theme.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundTypeChatTheme < Base 7 | attribute :type, Types::String.constrained(eql: 'chat_theme').default('chat_theme') 8 | attribute :theme_name, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_type_fill.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundTypeFill < Base 7 | attribute :type, Types::String.constrained(eql: 'fill').default('fill') 8 | attribute :fill, BackgroundFill 9 | attribute :dark_theme_dimming, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_type_pattern.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundTypePattern < Base 7 | attribute :type, Types::String.constrained(eql: 'pattern').default('pattern') 8 | attribute :document, Document 9 | attribute :fill, BackgroundFill 10 | attribute :intensity, Types::Integer 11 | attribute? :is_inverted, Types::True 12 | attribute? :is_moving, Types::True 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/background_type_wallpaper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BackgroundTypeWallpaper < Base 7 | attribute :type, Types::String.constrained(eql: 'wallpaper').default('wallpaper') 8 | attribute :document, Document 9 | attribute :dark_theme_dimming, Types::Integer 10 | attribute? :is_blurred, Types::True 11 | attribute? :is_moving, Types::True 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/base.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Base < Dry::Struct 7 | include Compactable 8 | include PatternMatching 9 | 10 | transform_keys(&:to_sym) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/birthdate.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Birthdate < Base 7 | attribute :day, Types::Integer 8 | attribute :month, Types::Integer 9 | attribute? :year, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommand < Base 7 | attribute :command, Types::String.constrained(min_size: 1, max_size: 32) 8 | attribute :description, Types::String.constrained(min_size: 1, max_size: 256) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | BotCommandScope = ( 9 | BotCommandScopeDefault | 10 | BotCommandScopeAllPrivateChats | 11 | BotCommandScopeAllGroupChats | 12 | BotCommandScopeAllChatAdministrators | 13 | BotCommandScopeChat | 14 | BotCommandScopeChatAdministrators | 15 | BotCommandScopeChatMember 16 | ) 17 | # rubocop:enable Naming/ConstantName 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_all_chat_administrators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeAllChatAdministrators < Base 7 | attribute :type, Types::String.constrained(eql: 'all_chat_administrators').default('all_chat_administrators') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_all_group_chats.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeAllGroupChats < Base 7 | attribute :type, Types::String.constrained(eql: 'all_group_chats').default('all_group_chats') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_all_private_chats.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeAllPrivateChats < Base 7 | attribute :type, Types::String.constrained(eql: 'all_private_chats').default('all_private_chats') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeChat < Base 7 | attribute :type, Types::String.constrained(eql: 'chat').default('chat') 8 | attribute :chat_id, Types::Integer | Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_chat_administrators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeChatAdministrators < Base 7 | attribute :type, Types::String.constrained(eql: 'chat_administrators').default('chat_administrators') 8 | attribute :chat_id, Types::Integer | Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_chat_member.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeChatMember < Base 7 | attribute :type, Types::String.constrained(eql: 'chat_member').default('chat_member') 8 | attribute :chat_id, Types::Integer | Types::String 9 | attribute :user_id, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_command_scope_default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotCommandScopeDefault < Base 7 | attribute :type, Types::String.constrained(eql: 'default').default('default') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_description.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotDescription < Base 7 | attribute :description, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_name.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotName < Base 7 | attribute :name, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/bot_short_description.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BotShortDescription < Base 7 | attribute :short_description, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_connection.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessConnection < Base 7 | attribute :id, Types::String 8 | attribute :user, User 9 | attribute :user_chat_id, Types::Integer 10 | attribute :date, Types::Integer 11 | attribute :can_reply, Types::Bool 12 | attribute :is_enabled, Types::Bool 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_intro.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessIntro < Base 7 | attribute? :title, Types::String 8 | attribute? :message, Types::String 9 | attribute? :sticker, Sticker 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_location.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessLocation < Base 7 | attribute :address, Types::String 8 | attribute? :location, Location 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_messages_deleted.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessMessagesDeleted < Base 7 | attribute :business_connection_id, Types::String 8 | attribute :chat, Chat 9 | attribute :message_ids, Types::Array.of(Types::Integer) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_opening_hours.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessOpeningHours < Base 7 | attribute :time_zone_name, Types::String 8 | attribute :opening_hours, Types::Array.of(BusinessOpeningHoursInterval) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/business_opening_hours_interval.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class BusinessOpeningHoursInterval < Base 7 | attribute :opening_minute, Types::Integer 8 | attribute :closing_minute, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/callback_game.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class CallbackGame < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/callback_query.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class CallbackQuery < Base 7 | attribute :id, Types::String 8 | attribute :from, User 9 | attribute? :message, MaybeInaccessibleMessage 10 | attribute? :inline_message_id, Types::String 11 | attribute :chat_instance, Types::String 12 | attribute? :data, Types::String 13 | attribute? :game_short_name, Types::String 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Chat < Base 7 | attribute :id, Types::Integer 8 | attribute :type, Types::String 9 | attribute? :title, Types::String 10 | attribute? :username, Types::String 11 | attribute? :first_name, Types::String 12 | attribute? :last_name, Types::String 13 | attribute? :is_forum, Types::True 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_administrator_rights.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatAdministratorRights < Base 7 | attribute :is_anonymous, Types::Bool 8 | attribute :can_manage_chat, Types::Bool 9 | attribute :can_delete_messages, Types::Bool 10 | attribute :can_manage_video_chats, Types::Bool 11 | attribute :can_restrict_members, Types::Bool 12 | attribute :can_promote_members, Types::Bool 13 | attribute :can_change_info, Types::Bool 14 | attribute :can_invite_users, Types::Bool 15 | attribute :can_post_stories, Types::Bool 16 | attribute :can_edit_stories, Types::Bool 17 | attribute :can_delete_stories, Types::Bool 18 | attribute? :can_post_messages, Types::Bool 19 | attribute? :can_edit_messages, Types::Bool 20 | attribute? :can_pin_messages, Types::Bool 21 | attribute? :can_manage_topics, Types::Bool 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_background.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBackground < Base 7 | attribute :type, BackgroundType 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoost < Base 7 | attribute :boost_id, Types::String 8 | attribute :add_date, Types::Integer 9 | attribute :expiration_date, Types::Integer 10 | attribute :source, ChatBoostSource 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_added.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostAdded < Base 7 | attribute :boost_count, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_removed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostRemoved < Base 7 | attribute :chat, Chat 8 | attribute :boost_id, Types::String 9 | attribute :remove_date, Types::Integer 10 | attribute :source, ChatBoostSource 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_source.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | ChatBoostSource = ( 9 | ChatBoostSourcePremium | 10 | ChatBoostSourceGiftCode | 11 | ChatBoostSourceGiveaway 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_source_gift_code.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostSourceGiftCode < Base 7 | attribute :source, Types::String.constrained(eql: 'gift_code').default('gift_code') 8 | attribute :user, User 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_source_giveaway.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostSourceGiveaway < Base 7 | attribute :source, Types::String.constrained(eql: 'giveaway').default('giveaway') 8 | attribute :giveaway_message_id, Types::Integer 9 | attribute? :user, User 10 | attribute? :prize_star_count, Types::Integer 11 | attribute? :is_unclaimed, Types::True 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_source_premium.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostSourcePremium < Base 7 | attribute :source, Types::String.constrained(eql: 'premium').default('premium') 8 | attribute :user, User 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_boost_updated.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatBoostUpdated < Base 7 | attribute :chat, Chat 8 | attribute :boost, ChatBoost 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_full_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatFullInfo < Base 7 | attribute :id, Types::Integer 8 | attribute :type, Types::String 9 | attribute? :title, Types::String 10 | attribute? :username, Types::String 11 | attribute? :first_name, Types::String 12 | attribute? :last_name, Types::String 13 | attribute? :is_forum, Types::True 14 | attribute :accent_color_id, Types::Integer 15 | attribute :max_reaction_count, Types::Integer 16 | attribute? :photo, ChatPhoto 17 | attribute? :active_usernames, Types::Array.of(Types::String) 18 | attribute? :birthdate, Birthdate 19 | attribute? :business_intro, BusinessIntro 20 | attribute? :business_location, BusinessLocation 21 | attribute? :business_opening_hours, BusinessOpeningHours 22 | attribute? :personal_chat, Chat 23 | attribute? :available_reactions, Types::Array.of(ReactionType) 24 | attribute? :background_custom_emoji_id, Types::String 25 | attribute? :profile_accent_color_id, Types::Integer 26 | attribute? :profile_background_custom_emoji_id, Types::String 27 | attribute? :emoji_status_custom_emoji_id, Types::String 28 | attribute? :emoji_status_expiration_date, Types::Integer 29 | attribute? :bio, Types::String 30 | attribute? :has_private_forwards, Types::True 31 | attribute? :has_restricted_voice_and_video_messages, Types::True 32 | attribute? :join_to_send_messages, Types::True 33 | attribute? :join_by_request, Types::True 34 | attribute? :description, Types::String 35 | attribute? :invite_link, Types::String 36 | attribute? :pinned_message, Message 37 | attribute? :permissions, ChatPermissions 38 | attribute? :can_send_gift, Types::True 39 | attribute? :can_send_paid_media, Types::True 40 | attribute? :slow_mode_delay, Types::Integer 41 | attribute? :unrestrict_boost_count, Types::Integer 42 | attribute? :message_auto_delete_time, Types::Integer 43 | attribute? :has_aggressive_anti_spam_enabled, Types::True 44 | attribute? :has_hidden_members, Types::True 45 | attribute? :has_protected_content, Types::True 46 | attribute? :has_visible_history, Types::True 47 | attribute? :sticker_set_name, Types::String 48 | attribute? :can_set_sticker_set, Types::True 49 | attribute? :custom_emoji_sticker_set_name, Types::String 50 | attribute? :linked_chat_id, Types::Integer 51 | attribute? :location, ChatLocation 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_invite_link.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatInviteLink < Base 7 | attribute :invite_link, Types::String 8 | attribute :creator, User 9 | attribute :creates_join_request, Types::Bool 10 | attribute :is_primary, Types::Bool 11 | attribute :is_revoked, Types::Bool 12 | attribute? :name, Types::String 13 | attribute? :expire_date, Types::Integer 14 | attribute? :member_limit, Types::Integer 15 | attribute? :pending_join_request_count, Types::Integer 16 | attribute? :subscription_period, Types::Integer 17 | attribute? :subscription_price, Types::Integer 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_join_request.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatJoinRequest < Base 7 | attribute :chat, Chat 8 | attribute :from, User 9 | attribute :user_chat_id, Types::Integer 10 | attribute :date, Types::Integer 11 | attribute? :bio, Types::String 12 | attribute? :invite_link, ChatInviteLink 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_location.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatLocation < Base 7 | attribute :location, Location 8 | attribute :address, Types::String.constrained(min_size: 1, max_size: 64) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | ChatMember = ( 9 | ChatMemberOwner | 10 | ChatMemberAdministrator | 11 | ChatMemberMember | 12 | ChatMemberRestricted | 13 | ChatMemberLeft | 14 | ChatMemberBanned 15 | ) 16 | # rubocop:enable Naming/ConstantName 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_administrator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberAdministrator < Base 7 | attribute :status, Types::String.constrained(eql: 'administrator').default('administrator') 8 | attribute :user, User 9 | attribute :can_be_edited, Types::Bool 10 | attribute :is_anonymous, Types::Bool 11 | attribute :can_manage_chat, Types::Bool 12 | attribute :can_delete_messages, Types::Bool 13 | attribute :can_manage_video_chats, Types::Bool 14 | attribute :can_restrict_members, Types::Bool 15 | attribute :can_promote_members, Types::Bool 16 | attribute :can_change_info, Types::Bool 17 | attribute :can_invite_users, Types::Bool 18 | attribute :can_post_stories, Types::Bool 19 | attribute :can_edit_stories, Types::Bool 20 | attribute :can_delete_stories, Types::Bool 21 | attribute? :can_post_messages, Types::Bool 22 | attribute? :can_edit_messages, Types::Bool 23 | attribute? :can_pin_messages, Types::Bool 24 | attribute? :can_manage_topics, Types::Bool 25 | attribute? :custom_title, Types::String 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_banned.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberBanned < Base 7 | attribute :status, Types::String.constrained(eql: 'kicked').default('kicked') 8 | attribute :user, User 9 | attribute :until_date, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_left.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberLeft < Base 7 | attribute :status, Types::String.constrained(eql: 'left').default('left') 8 | attribute :user, User 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_member.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberMember < Base 7 | attribute :status, Types::String.constrained(eql: 'member').default('member') 8 | attribute :user, User 9 | attribute? :until_date, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_owner.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberOwner < Base 7 | attribute :status, Types::String.constrained(eql: 'creator').default('creator') 8 | attribute :user, User 9 | attribute :is_anonymous, Types::Bool 10 | attribute? :custom_title, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_restricted.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberRestricted < Base 7 | attribute :status, Types::String.constrained(eql: 'restricted').default('restricted') 8 | attribute :user, User 9 | attribute :is_member, Types::Bool 10 | attribute :can_send_messages, Types::Bool 11 | attribute :can_send_audios, Types::Bool 12 | attribute :can_send_documents, Types::Bool 13 | attribute :can_send_photos, Types::Bool 14 | attribute :can_send_videos, Types::Bool 15 | attribute :can_send_video_notes, Types::Bool 16 | attribute :can_send_voice_notes, Types::Bool 17 | attribute :can_send_polls, Types::Bool 18 | attribute :can_send_other_messages, Types::Bool 19 | attribute :can_add_web_page_previews, Types::Bool 20 | attribute :can_change_info, Types::Bool 21 | attribute :can_invite_users, Types::Bool 22 | attribute :can_pin_messages, Types::Bool 23 | attribute :can_manage_topics, Types::Bool 24 | attribute :until_date, Types::Integer 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_member_updated.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatMemberUpdated < Base 7 | attribute :chat, Chat 8 | attribute :from, User 9 | attribute :date, Types::Integer 10 | attribute :old_chat_member, ChatMember 11 | attribute :new_chat_member, ChatMember 12 | attribute? :invite_link, ChatInviteLink 13 | attribute? :via_join_request, Types::Bool 14 | attribute? :via_chat_folder_invite_link, Types::Bool 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_permissions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatPermissions < Base 7 | attribute? :can_send_messages, Types::Bool 8 | attribute? :can_send_audios, Types::Bool 9 | attribute? :can_send_documents, Types::Bool 10 | attribute? :can_send_photos, Types::Bool 11 | attribute? :can_send_videos, Types::Bool 12 | attribute? :can_send_video_notes, Types::Bool 13 | attribute? :can_send_voice_notes, Types::Bool 14 | attribute? :can_send_polls, Types::Bool 15 | attribute? :can_send_other_messages, Types::Bool 16 | attribute? :can_add_web_page_previews, Types::Bool 17 | attribute? :can_change_info, Types::Bool 18 | attribute? :can_invite_users, Types::Bool 19 | attribute? :can_pin_messages, Types::Bool 20 | attribute? :can_manage_topics, Types::Bool 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatPhoto < Base 7 | attribute :small_file_id, Types::String 8 | attribute :small_file_unique_id, Types::String 9 | attribute :big_file_id, Types::String 10 | attribute :big_file_unique_id, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chat_shared.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChatShared < Base 7 | attribute :request_id, Types::Integer 8 | attribute :chat_id, Types::Integer 9 | attribute? :title, Types::String 10 | attribute? :username, Types::String 11 | attribute? :photo, Types::Array.of(PhotoSize) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/chosen_inline_result.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ChosenInlineResult < Base 7 | attribute :result_id, Types::String 8 | attribute :from, User 9 | attribute? :location, Location 10 | attribute? :inline_message_id, Types::String 11 | attribute :query, Types::String 12 | 13 | alias to_s query 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/compactable.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | module Compactable 7 | def to_compact_hash 8 | attributes.dup.compact.to_h do |key, value| 9 | value = value.to_compact_hash if value.respond_to?(:to_compact_hash) 10 | 11 | [key, value] 12 | end 13 | end 14 | 15 | def to_json(*args) 16 | to_compact_hash.select { |_, v| v }.to_json(*args) 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/contact.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Contact < Base 7 | attribute :phone_number, Types::String 8 | attribute :first_name, Types::String 9 | attribute? :last_name, Types::String 10 | attribute? :user_id, Types::Integer 11 | attribute? :vcard, Types::String 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/copy_text_button.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class CopyTextButton < Base 7 | attribute :text, Types::String.constrained(min_size: 1, max_size: 256) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/dice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Dice < Base 7 | attribute :emoji, Types::String 8 | attribute :value, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/document.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Document < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute? :thumbnail, PhotoSize 10 | attribute? :file_name, Types::String 11 | attribute? :mime_type, Types::String 12 | attribute? :file_size, Types::Integer 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/encrypted_credentials.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class EncryptedCredentials < Base 7 | attribute :data, Types::String 8 | attribute :hash, Types::String 9 | attribute :secret, Types::String 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/encrypted_passport_element.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class EncryptedPassportElement < Base 7 | attribute :type, Types::String 8 | attribute? :data, Types::String 9 | attribute? :phone_number, Types::String 10 | attribute? :email, Types::String 11 | attribute? :files, Types::Array.of(PassportFile) 12 | attribute? :front_side, PassportFile 13 | attribute? :reverse_side, PassportFile 14 | attribute? :selfie, PassportFile 15 | attribute? :translation, Types::Array.of(PassportFile) 16 | attribute :hash, Types::String 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/error.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Error < Base 7 | attribute :ok, Types::Bool 8 | attribute :error_code, Types::Integer 9 | attribute :description, Types::String 10 | attribute? :parameters, ResponseParameters 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/external_reply_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ExternalReplyInfo < Base 7 | attribute :origin, MessageOrigin 8 | attribute? :chat, Chat 9 | attribute? :message_id, Types::Integer 10 | attribute? :link_preview_options, LinkPreviewOptions 11 | attribute? :animation, Animation 12 | attribute? :audio, Audio 13 | attribute? :document, Document 14 | attribute? :paid_media, PaidMediaInfo 15 | attribute? :photo, Types::Array.of(PhotoSize) 16 | attribute? :sticker, Sticker 17 | attribute? :story, Story 18 | attribute? :video, Video 19 | attribute? :video_note, VideoNote 20 | attribute? :voice, Voice 21 | attribute? :has_media_spoiler, Types::True 22 | attribute? :contact, Contact 23 | attribute? :dice, Dice 24 | attribute? :game, Game 25 | attribute? :giveaway, Giveaway 26 | attribute? :giveaway_winners, GiveawayWinners 27 | attribute? :invoice, Invoice 28 | attribute? :location, Location 29 | attribute? :poll, Poll 30 | attribute? :venue, Venue 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class File < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute? :file_size, Types::Integer 10 | attribute? :file_path, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/force_reply.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForceReply < Base 7 | attribute :force_reply, Types::True 8 | attribute? :input_field_placeholder, Types::String.constrained(min_size: 1, max_size: 64) 9 | attribute? :selective, Types::Bool 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/forum_topic.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForumTopic < Base 7 | attribute :message_thread_id, Types::Integer 8 | attribute :name, Types::String 9 | attribute :icon_color, Types::Integer 10 | attribute? :icon_custom_emoji_id, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/forum_topic_closed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForumTopicClosed < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/forum_topic_created.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForumTopicCreated < Base 7 | attribute :name, Types::String 8 | attribute :icon_color, Types::Integer 9 | attribute? :icon_custom_emoji_id, Types::String 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/forum_topic_edited.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForumTopicEdited < Base 7 | attribute? :name, Types::String 8 | attribute? :icon_custom_emoji_id, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/forum_topic_reopened.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ForumTopicReopened < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/game.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Game < Base 7 | attribute :title, Types::String 8 | attribute :description, Types::String 9 | attribute :photo, Types::Array.of(PhotoSize) 10 | attribute? :text, Types::String 11 | attribute? :text_entities, Types::Array.of(MessageEntity) 12 | attribute? :animation, Animation 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/game_high_score.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GameHighScore < Base 7 | attribute :position, Types::Integer 8 | attribute :user, User 9 | attribute :score, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/general_forum_topic_hidden.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GeneralForumTopicHidden < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/general_forum_topic_unhidden.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GeneralForumTopicUnhidden < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/gift.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Gift < Base 7 | attribute :id, Types::String 8 | attribute :sticker, Sticker 9 | attribute :star_count, Types::Integer 10 | attribute? :upgrade_star_count, Types::Integer 11 | attribute? :total_count, Types::Integer 12 | attribute? :remaining_count, Types::Integer 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/gifts.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Gifts < Base 7 | attribute :gifts, Types::Array.of(Gift) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/giveaway.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Giveaway < Base 7 | attribute :chats, Types::Array.of(Chat) 8 | attribute :winners_selection_date, Types::Integer 9 | attribute :winner_count, Types::Integer 10 | attribute? :only_new_members, Types::True 11 | attribute? :has_public_winners, Types::True 12 | attribute? :prize_description, Types::String 13 | attribute? :country_codes, Types::Array.of(Types::String) 14 | attribute? :prize_star_count, Types::Integer 15 | attribute? :premium_subscription_month_count, Types::Integer 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/giveaway_completed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GiveawayCompleted < Base 7 | attribute :winner_count, Types::Integer 8 | attribute? :unclaimed_prize_count, Types::Integer 9 | attribute? :giveaway_message, Message 10 | attribute? :is_star_giveaway, Types::True 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/giveaway_created.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GiveawayCreated < Base 7 | attribute? :prize_star_count, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/giveaway_winners.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class GiveawayWinners < Base 7 | attribute :chat, Chat 8 | attribute :giveaway_message_id, Types::Integer 9 | attribute :winners_selection_date, Types::Integer 10 | attribute :winner_count, Types::Integer 11 | attribute :winners, Types::Array.of(User) 12 | attribute? :additional_chat_count, Types::Integer 13 | attribute? :prize_star_count, Types::Integer 14 | attribute? :premium_subscription_month_count, Types::Integer 15 | attribute? :unclaimed_prize_count, Types::Integer 16 | attribute? :only_new_members, Types::True 17 | attribute? :was_refunded, Types::True 18 | attribute? :prize_description, Types::String 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inaccessible_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InaccessibleMessage < Base 7 | attribute :chat, Chat 8 | attribute :message_id, Types::Integer 9 | attribute :date, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_keyboard_button.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineKeyboardButton < Base 7 | attribute :text, Types::String 8 | attribute? :url, Types::String 9 | attribute? :callback_data, Types::String 10 | attribute? :web_app, WebAppInfo 11 | attribute? :login_url, LoginUrl 12 | attribute? :switch_inline_query, Types::String 13 | attribute? :switch_inline_query_current_chat, Types::String 14 | attribute? :switch_inline_query_chosen_chat, SwitchInlineQueryChosenChat 15 | attribute? :copy_text, CopyTextButton 16 | attribute? :callback_game, CallbackGame 17 | attribute? :pay, Types::Bool 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_keyboard_markup.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineKeyboardMarkup < Base 7 | attribute :inline_keyboard, Types::Array.of(Types::Array.of(InlineKeyboardButton)) 8 | 9 | def to_compact_hash 10 | hsh = super 11 | hsh[:inline_keyboard].map! do |arr| 12 | arr.map do |item| 13 | item.is_a?(InlineKeyboardButton) ? item.to_compact_hash : item 14 | end 15 | end 16 | 17 | hsh 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQuery < Base 7 | attribute :id, Types::String 8 | attribute :from, User 9 | attribute :query, Types::String 10 | attribute :offset, Types::String 11 | attribute? :chat_type, Types::String 12 | attribute? :location, Location 13 | 14 | alias to_s query 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | InlineQueryResult = ( 9 | InlineQueryResultCachedAudio | 10 | InlineQueryResultCachedDocument | 11 | InlineQueryResultCachedGif | 12 | InlineQueryResultCachedMpeg4Gif | 13 | InlineQueryResultCachedPhoto | 14 | InlineQueryResultCachedSticker | 15 | InlineQueryResultCachedVideo | 16 | InlineQueryResultCachedVoice | 17 | InlineQueryResultArticle | 18 | InlineQueryResultAudio | 19 | InlineQueryResultContact | 20 | InlineQueryResultGame | 21 | InlineQueryResultDocument | 22 | InlineQueryResultGif | 23 | InlineQueryResultLocation | 24 | InlineQueryResultMpeg4Gif | 25 | InlineQueryResultPhoto | 26 | InlineQueryResultVenue | 27 | InlineQueryResultVideo | 28 | InlineQueryResultVoice 29 | ) 30 | # rubocop:enable Naming/ConstantName 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_article.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultArticle < Base 7 | attribute :type, Types::String.constrained(eql: 'article').default('article') 8 | attribute :id, Types::String 9 | attribute :title, Types::String 10 | attribute :input_message_content, InputMessageContent 11 | attribute? :reply_markup, InlineKeyboardMarkup 12 | attribute? :url, Types::String 13 | attribute? :description, Types::String 14 | attribute? :thumbnail_url, Types::String 15 | attribute? :thumbnail_width, Types::Integer 16 | attribute? :thumbnail_height, Types::Integer 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_audio.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultAudio < Base 7 | attribute :type, Types::String.constrained(eql: 'audio').default('audio') 8 | attribute :id, Types::String 9 | attribute :audio_url, Types::String 10 | attribute :title, Types::String 11 | attribute? :caption, Types::String 12 | attribute? :parse_mode, Types::String 13 | attribute? :caption_entities, Types::Array.of(MessageEntity) 14 | attribute? :performer, Types::String 15 | attribute? :audio_duration, Types::Integer 16 | attribute? :reply_markup, InlineKeyboardMarkup 17 | attribute? :input_message_content, InputMessageContent 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_audio.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedAudio < Base 7 | attribute :type, Types::String.constrained(eql: 'audio').default('audio') 8 | attribute :id, Types::String 9 | attribute :audio_file_id, Types::String 10 | attribute? :caption, Types::String 11 | attribute? :parse_mode, Types::String 12 | attribute? :caption_entities, Types::Array.of(MessageEntity) 13 | attribute? :reply_markup, InlineKeyboardMarkup 14 | attribute? :input_message_content, InputMessageContent 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_document.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedDocument < Base 7 | attribute :type, Types::String.constrained(eql: 'document').default('document') 8 | attribute :id, Types::String 9 | attribute :title, Types::String 10 | attribute :document_file_id, Types::String 11 | attribute? :description, Types::String 12 | attribute? :caption, Types::String 13 | attribute? :parse_mode, Types::String 14 | attribute? :caption_entities, Types::Array.of(MessageEntity) 15 | attribute? :reply_markup, InlineKeyboardMarkup 16 | attribute? :input_message_content, InputMessageContent 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_gif.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedGif < Base 7 | attribute :type, Types::String.constrained(eql: 'gif').default('gif') 8 | attribute :id, Types::String 9 | attribute :gif_file_id, Types::String 10 | attribute? :title, Types::String 11 | attribute? :caption, Types::String 12 | attribute? :parse_mode, Types::String 13 | attribute? :caption_entities, Types::Array.of(MessageEntity) 14 | attribute? :show_caption_above_media, Types::Bool 15 | attribute? :reply_markup, InlineKeyboardMarkup 16 | attribute? :input_message_content, InputMessageContent 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_mpeg4_gif.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedMpeg4Gif < Base 7 | attribute :type, Types::String.constrained(eql: 'mpeg4_gif').default('mpeg4_gif') 8 | attribute :id, Types::String 9 | attribute :mpeg4_file_id, Types::String 10 | attribute? :title, Types::String 11 | attribute? :caption, Types::String 12 | attribute? :parse_mode, Types::String 13 | attribute? :caption_entities, Types::Array.of(MessageEntity) 14 | attribute? :show_caption_above_media, Types::Bool 15 | attribute? :reply_markup, InlineKeyboardMarkup 16 | attribute? :input_message_content, InputMessageContent 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedPhoto < Base 7 | attribute :type, Types::String.constrained(eql: 'photo').default('photo') 8 | attribute :id, Types::String 9 | attribute :photo_file_id, Types::String 10 | attribute? :title, Types::String 11 | attribute? :description, Types::String 12 | attribute? :caption, Types::String 13 | attribute? :parse_mode, Types::String 14 | attribute? :caption_entities, Types::Array.of(MessageEntity) 15 | attribute? :show_caption_above_media, Types::Bool 16 | attribute? :reply_markup, InlineKeyboardMarkup 17 | attribute? :input_message_content, InputMessageContent 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_sticker.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedSticker < Base 7 | attribute :type, Types::String.constrained(eql: 'sticker').default('sticker') 8 | attribute :id, Types::String 9 | attribute :sticker_file_id, Types::String 10 | attribute? :reply_markup, InlineKeyboardMarkup 11 | attribute? :input_message_content, InputMessageContent 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedVideo < Base 7 | attribute :type, Types::String.constrained(eql: 'video').default('video') 8 | attribute :id, Types::String 9 | attribute :video_file_id, Types::String 10 | attribute :title, Types::String 11 | attribute? :description, Types::String 12 | attribute? :caption, Types::String 13 | attribute? :parse_mode, Types::String 14 | attribute? :caption_entities, Types::Array.of(MessageEntity) 15 | attribute? :show_caption_above_media, Types::Bool 16 | attribute? :reply_markup, InlineKeyboardMarkup 17 | attribute? :input_message_content, InputMessageContent 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_cached_voice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultCachedVoice < Base 7 | attribute :type, Types::String.constrained(eql: 'voice').default('voice') 8 | attribute :id, Types::String 9 | attribute :voice_file_id, Types::String 10 | attribute :title, Types::String 11 | attribute? :caption, Types::String 12 | attribute? :parse_mode, Types::String 13 | attribute? :caption_entities, Types::Array.of(MessageEntity) 14 | attribute? :reply_markup, InlineKeyboardMarkup 15 | attribute? :input_message_content, InputMessageContent 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_contact.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultContact < Base 7 | attribute :type, Types::String.constrained(eql: 'contact').default('contact') 8 | attribute :id, Types::String 9 | attribute :phone_number, Types::String 10 | attribute :first_name, Types::String 11 | attribute? :last_name, Types::String 12 | attribute? :vcard, Types::String 13 | attribute? :reply_markup, InlineKeyboardMarkup 14 | attribute? :input_message_content, InputMessageContent 15 | attribute? :thumbnail_url, Types::String 16 | attribute? :thumbnail_width, Types::Integer 17 | attribute? :thumbnail_height, Types::Integer 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_document.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultDocument < Base 7 | attribute :type, Types::String.constrained(eql: 'document').default('document') 8 | attribute :id, Types::String 9 | attribute :title, Types::String 10 | attribute? :caption, Types::String 11 | attribute? :parse_mode, Types::String 12 | attribute? :caption_entities, Types::Array.of(MessageEntity) 13 | attribute :document_url, Types::String 14 | attribute :mime_type, Types::String 15 | attribute? :description, Types::String 16 | attribute? :reply_markup, InlineKeyboardMarkup 17 | attribute? :input_message_content, InputMessageContent 18 | attribute? :thumbnail_url, Types::String 19 | attribute? :thumbnail_width, Types::Integer 20 | attribute? :thumbnail_height, Types::Integer 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_game.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultGame < Base 7 | attribute :type, Types::String.constrained(eql: 'game').default('game') 8 | attribute :id, Types::String 9 | attribute :game_short_name, Types::String 10 | attribute? :reply_markup, InlineKeyboardMarkup 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_gif.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultGif < Base 7 | attribute :type, Types::String.constrained(eql: 'gif').default('gif') 8 | attribute :id, Types::String 9 | attribute :gif_url, Types::String 10 | attribute? :gif_width, Types::Integer 11 | attribute? :gif_height, Types::Integer 12 | attribute? :gif_duration, Types::Integer 13 | attribute :thumbnail_url, Types::String 14 | attribute? :thumbnail_mime_type, Types::String.default('image/jpeg') 15 | attribute? :title, Types::String 16 | attribute? :caption, Types::String 17 | attribute? :parse_mode, Types::String 18 | attribute? :caption_entities, Types::Array.of(MessageEntity) 19 | attribute? :show_caption_above_media, Types::Bool 20 | attribute? :reply_markup, InlineKeyboardMarkup 21 | attribute? :input_message_content, InputMessageContent 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_location.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultLocation < Base 7 | attribute :type, Types::String.constrained(eql: 'location').default('location') 8 | attribute :id, Types::String 9 | attribute :latitude, Types::Float 10 | attribute :longitude, Types::Float 11 | attribute :title, Types::String 12 | attribute? :horizontal_accuracy, Types::Float 13 | attribute? :live_period, Types::Integer 14 | attribute? :heading, Types::Integer 15 | attribute? :proximity_alert_radius, Types::Integer 16 | attribute? :reply_markup, InlineKeyboardMarkup 17 | attribute? :input_message_content, InputMessageContent 18 | attribute? :thumbnail_url, Types::String 19 | attribute? :thumbnail_width, Types::Integer 20 | attribute? :thumbnail_height, Types::Integer 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_mpeg4_gif.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultMpeg4Gif < Base 7 | attribute :type, Types::String.constrained(eql: 'mpeg4_gif').default('mpeg4_gif') 8 | attribute :id, Types::String 9 | attribute :mpeg4_url, Types::String 10 | attribute? :mpeg4_width, Types::Integer 11 | attribute? :mpeg4_height, Types::Integer 12 | attribute? :mpeg4_duration, Types::Integer 13 | attribute :thumbnail_url, Types::String 14 | attribute? :thumbnail_mime_type, Types::String.default('image/jpeg') 15 | attribute? :title, Types::String 16 | attribute? :caption, Types::String 17 | attribute? :parse_mode, Types::String 18 | attribute? :caption_entities, Types::Array.of(MessageEntity) 19 | attribute? :show_caption_above_media, Types::Bool 20 | attribute? :reply_markup, InlineKeyboardMarkup 21 | attribute? :input_message_content, InputMessageContent 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultPhoto < Base 7 | attribute :type, Types::String.constrained(eql: 'photo').default('photo') 8 | attribute :id, Types::String 9 | attribute :photo_url, Types::String 10 | attribute :thumbnail_url, Types::String 11 | attribute? :photo_width, Types::Integer 12 | attribute? :photo_height, Types::Integer 13 | attribute? :title, Types::String 14 | attribute? :description, Types::String 15 | attribute? :caption, Types::String 16 | attribute? :parse_mode, Types::String 17 | attribute? :caption_entities, Types::Array.of(MessageEntity) 18 | attribute? :show_caption_above_media, Types::Bool 19 | attribute? :reply_markup, InlineKeyboardMarkup 20 | attribute? :input_message_content, InputMessageContent 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_venue.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultVenue < Base 7 | attribute :type, Types::String.constrained(eql: 'venue').default('venue') 8 | attribute :id, Types::String 9 | attribute :latitude, Types::Float 10 | attribute :longitude, Types::Float 11 | attribute :title, Types::String 12 | attribute :address, Types::String 13 | attribute? :foursquare_id, Types::String 14 | attribute? :foursquare_type, Types::String 15 | attribute? :google_place_id, Types::String 16 | attribute? :google_place_type, Types::String 17 | attribute? :reply_markup, InlineKeyboardMarkup 18 | attribute? :input_message_content, InputMessageContent 19 | attribute? :thumbnail_url, Types::String 20 | attribute? :thumbnail_width, Types::Integer 21 | attribute? :thumbnail_height, Types::Integer 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultVideo < Base 7 | attribute :type, Types::String.constrained(eql: 'video').default('video') 8 | attribute :id, Types::String 9 | attribute :video_url, Types::String 10 | attribute :mime_type, Types::String 11 | attribute :thumbnail_url, Types::String 12 | attribute :title, Types::String 13 | attribute? :caption, Types::String 14 | attribute? :parse_mode, Types::String 15 | attribute? :caption_entities, Types::Array.of(MessageEntity) 16 | attribute? :show_caption_above_media, Types::Bool 17 | attribute? :video_width, Types::Integer 18 | attribute? :video_height, Types::Integer 19 | attribute? :video_duration, Types::Integer 20 | attribute? :description, Types::String 21 | attribute? :reply_markup, InlineKeyboardMarkup 22 | attribute? :input_message_content, InputMessageContent 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_result_voice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultVoice < Base 7 | attribute :type, Types::String.constrained(eql: 'voice').default('voice') 8 | attribute :id, Types::String 9 | attribute :voice_url, Types::String 10 | attribute :title, Types::String 11 | attribute? :caption, Types::String 12 | attribute? :parse_mode, Types::String 13 | attribute? :caption_entities, Types::Array.of(MessageEntity) 14 | attribute? :voice_duration, Types::Integer 15 | attribute? :reply_markup, InlineKeyboardMarkup 16 | attribute? :input_message_content, InputMessageContent 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/inline_query_results_button.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InlineQueryResultsButton < Base 7 | attribute :text, Types::String 8 | attribute? :web_app, WebAppInfo 9 | attribute? :start_parameter, Types::String.constrained(min_size: 1, max_size: 64) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_contact_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputContactMessageContent < Base 7 | attribute :phone_number, Types::String 8 | attribute :first_name, Types::String 9 | attribute? :last_name, Types::String 10 | attribute? :vcard, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_invoice_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputInvoiceMessageContent < Base 7 | attribute :title, Types::String.constrained(min_size: 1, max_size: 32) 8 | attribute :description, Types::String.constrained(min_size: 1, max_size: 255) 9 | attribute :payload, Types::String 10 | attribute? :provider_token, Types::String 11 | attribute :currency, Types::String 12 | attribute :prices, Types::Array.of(LabeledPrice) 13 | attribute? :max_tip_amount, Types::Integer.default(0) 14 | attribute? :suggested_tip_amounts, Types::Array.of(Types::Integer) 15 | attribute? :provider_data, Types::String 16 | attribute? :photo_url, Types::String 17 | attribute? :photo_size, Types::Integer 18 | attribute? :photo_width, Types::Integer 19 | attribute? :photo_height, Types::Integer 20 | attribute? :need_name, Types::Bool 21 | attribute? :need_phone_number, Types::Bool 22 | attribute? :need_email, Types::Bool 23 | attribute? :need_shipping_address, Types::Bool 24 | attribute? :send_phone_number_to_provider, Types::Bool 25 | attribute? :send_email_to_provider, Types::Bool 26 | attribute? :is_flexible, Types::Bool 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_location_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputLocationMessageContent < Base 7 | attribute :latitude, Types::Float 8 | attribute :longitude, Types::Float 9 | attribute? :horizontal_accuracy, Types::Float 10 | attribute? :live_period, Types::Integer 11 | attribute? :heading, Types::Integer 12 | attribute? :proximity_alert_radius, Types::Integer 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | InputMedia = ( 9 | InputMediaAnimation | 10 | InputMediaDocument | 11 | InputMediaAudio | 12 | InputMediaPhoto | 13 | InputMediaVideo 14 | ) 15 | # rubocop:enable Naming/ConstantName 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media_animation.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputMediaAnimation < Base 7 | attribute :type, Types::String.constrained(eql: 'animation').default('animation') 8 | attribute :media, Types::String 9 | attribute? :thumbnail, Types::String 10 | attribute? :caption, Types::String 11 | attribute? :parse_mode, Types::String 12 | attribute? :caption_entities, Types::Array.of(MessageEntity) 13 | attribute? :show_caption_above_media, Types::Bool 14 | attribute? :width, Types::Integer 15 | attribute? :height, Types::Integer 16 | attribute? :duration, Types::Integer 17 | attribute? :has_spoiler, Types::Bool 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media_audio.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputMediaAudio < Base 7 | attribute :type, Types::String.constrained(eql: 'audio').default('audio') 8 | attribute :media, Types::String 9 | attribute? :thumbnail, Types::String 10 | attribute? :caption, Types::String 11 | attribute? :parse_mode, Types::String 12 | attribute? :caption_entities, Types::Array.of(MessageEntity) 13 | attribute? :duration, Types::Integer 14 | attribute? :performer, Types::String 15 | attribute? :title, Types::String 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media_document.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputMediaDocument < Base 7 | attribute :type, Types::String.constrained(eql: 'document').default('document') 8 | attribute :media, Types::String 9 | attribute? :thumbnail, Types::String 10 | attribute? :caption, Types::String 11 | attribute? :parse_mode, Types::String 12 | attribute? :caption_entities, Types::Array.of(MessageEntity) 13 | attribute? :disable_content_type_detection, Types::Bool 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputMediaPhoto < Base 7 | attribute :type, Types::String.constrained(eql: 'photo').default('photo') 8 | attribute :media, Types::String 9 | attribute? :caption, Types::String 10 | attribute? :parse_mode, Types::String 11 | attribute? :caption_entities, Types::Array.of(MessageEntity) 12 | attribute? :show_caption_above_media, Types::Bool 13 | attribute? :has_spoiler, Types::Bool 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_media_video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputMediaVideo < Base 7 | attribute :type, Types::String.constrained(eql: 'video').default('video') 8 | attribute :media, Types::String 9 | attribute? :thumbnail, Types::String 10 | attribute? :cover, Types::String 11 | attribute? :start_timestamp, Types::Integer 12 | attribute? :caption, Types::String 13 | attribute? :parse_mode, Types::String 14 | attribute? :caption_entities, Types::Array.of(MessageEntity) 15 | attribute? :show_caption_above_media, Types::Bool 16 | attribute? :width, Types::Integer 17 | attribute? :height, Types::Integer 18 | attribute? :duration, Types::Integer 19 | attribute? :supports_streaming, Types::Bool 20 | attribute? :has_spoiler, Types::Bool 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | InputMessageContent = ( 9 | InputTextMessageContent | 10 | InputLocationMessageContent | 11 | InputVenueMessageContent | 12 | InputContactMessageContent | 13 | InputInvoiceMessageContent 14 | ) 15 | # rubocop:enable Naming/ConstantName 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_paid_media.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | InputPaidMedia = ( 9 | InputPaidMediaPhoto | 10 | InputPaidMediaVideo 11 | ) 12 | # rubocop:enable Naming/ConstantName 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_paid_media_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputPaidMediaPhoto < Base 7 | attribute :type, Types::String.constrained(eql: 'photo').default('photo') 8 | attribute :media, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_paid_media_video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputPaidMediaVideo < Base 7 | attribute :type, Types::String.constrained(eql: 'video').default('video') 8 | attribute :media, Types::String 9 | attribute? :thumbnail, Types::String 10 | attribute? :cover, Types::String 11 | attribute? :start_timestamp, Types::Integer 12 | attribute? :width, Types::Integer 13 | attribute? :height, Types::Integer 14 | attribute? :duration, Types::Integer 15 | attribute? :supports_streaming, Types::Bool 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_poll_option.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputPollOption < Base 7 | attribute :text, Types::String.constrained(min_size: 1, max_size: 100) 8 | attribute? :text_parse_mode, Types::String 9 | attribute? :text_entities, Types::Array.of(MessageEntity) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_sticker.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputSticker < Base 7 | attribute :sticker, Types::String 8 | attribute :format, Types::String 9 | attribute :emoji_list, Types::Array.of(Types::String) 10 | attribute? :mask_position, MaskPosition 11 | attribute? :keywords, Types::Array.of(Types::String) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_text_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputTextMessageContent < Base 7 | attribute :message_text, Types::String.constrained(min_size: 1, max_size: 4096) 8 | attribute? :parse_mode, Types::String 9 | attribute? :entities, Types::Array.of(MessageEntity) 10 | attribute? :link_preview_options, LinkPreviewOptions 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/input_venue_message_content.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class InputVenueMessageContent < Base 7 | attribute :latitude, Types::Float 8 | attribute :longitude, Types::Float 9 | attribute :title, Types::String 10 | attribute :address, Types::String 11 | attribute? :foursquare_id, Types::String 12 | attribute? :foursquare_type, Types::String 13 | attribute? :google_place_id, Types::String 14 | attribute? :google_place_type, Types::String 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/invoice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Invoice < Base 7 | attribute :title, Types::String 8 | attribute :description, Types::String 9 | attribute :start_parameter, Types::String 10 | attribute :currency, Types::String 11 | attribute :total_amount, Types::Integer 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/keyboard_button.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class KeyboardButton < Base 7 | attribute :text, Types::String 8 | attribute? :request_users, KeyboardButtonRequestUsers 9 | attribute? :request_chat, KeyboardButtonRequestChat 10 | attribute? :request_contact, Types::Bool 11 | attribute? :request_location, Types::Bool 12 | attribute? :request_poll, KeyboardButtonPollType 13 | attribute? :web_app, WebAppInfo 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/keyboard_button_poll_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class KeyboardButtonPollType < Base 7 | attribute? :type, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/keyboard_button_request_chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class KeyboardButtonRequestChat < Base 7 | attribute :request_id, Types::Integer 8 | attribute :chat_is_channel, Types::Bool 9 | attribute? :chat_is_forum, Types::Bool 10 | attribute? :chat_has_username, Types::Bool 11 | attribute? :chat_is_created, Types::Bool 12 | attribute? :user_administrator_rights, ChatAdministratorRights 13 | attribute? :bot_administrator_rights, ChatAdministratorRights 14 | attribute? :bot_is_member, Types::Bool 15 | attribute? :request_title, Types::Bool 16 | attribute? :request_username, Types::Bool 17 | attribute? :request_photo, Types::Bool 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/keyboard_button_request_users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class KeyboardButtonRequestUsers < Base 7 | attribute :request_id, Types::Integer 8 | attribute? :user_is_bot, Types::Bool 9 | attribute? :user_is_premium, Types::Bool 10 | attribute? :max_quantity, Types::Integer.default(1) 11 | attribute? :request_name, Types::Bool 12 | attribute? :request_username, Types::Bool 13 | attribute? :request_photo, Types::Bool 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/labeled_price.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class LabeledPrice < Base 7 | attribute :label, Types::String 8 | attribute :amount, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/link_preview_options.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class LinkPreviewOptions < Base 7 | attribute? :is_disabled, Types::Bool 8 | attribute? :url, Types::String 9 | attribute? :prefer_small_media, Types::Bool 10 | attribute? :prefer_large_media, Types::Bool 11 | attribute? :show_above_text, Types::Bool 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/location.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Location < Base 7 | attribute :latitude, Types::Float 8 | attribute :longitude, Types::Float 9 | attribute? :horizontal_accuracy, Types::Float 10 | attribute? :live_period, Types::Integer 11 | attribute? :heading, Types::Integer 12 | attribute? :proximity_alert_radius, Types::Integer 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/login_url.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class LoginUrl < Base 7 | attribute :url, Types::String 8 | attribute? :forward_text, Types::String 9 | attribute? :bot_username, Types::String 10 | attribute? :request_write_access, Types::Bool 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/mask_position.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MaskPosition < Base 7 | attribute :point, Types::String 8 | attribute :x_shift, Types::Float 9 | attribute :y_shift, Types::Float 10 | attribute :scale, Types::Float 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/maybe_inaccessible_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | MaybeInaccessibleMessage = ( 9 | Message | 10 | InaccessibleMessage 11 | ) 12 | # rubocop:enable Naming/ConstantName 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/menu_button.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | MenuButton = ( 9 | MenuButtonCommands | 10 | MenuButtonWebApp | 11 | MenuButtonDefault 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/menu_button_commands.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MenuButtonCommands < Base 7 | attribute :type, Types::String.constrained(eql: 'commands').default('commands') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/menu_button_default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MenuButtonDefault < Base 7 | attribute :type, Types::String.constrained(eql: 'default').default('default') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/menu_button_web_app.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MenuButtonWebApp < Base 7 | attribute :type, Types::String.constrained(eql: 'web_app').default('web_app') 8 | attribute :text, Types::String 9 | attribute :web_app, WebAppInfo 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Message < Base 7 | attribute :message_id, Types::Integer 8 | attribute? :message_thread_id, Types::Integer 9 | attribute? :from, User 10 | attribute? :sender_chat, Chat 11 | attribute? :sender_boost_count, Types::Integer 12 | attribute? :sender_business_bot, User 13 | attribute :date, Types::Integer 14 | attribute? :business_connection_id, Types::String 15 | attribute :chat, Chat 16 | attribute? :forward_origin, MessageOrigin 17 | attribute? :is_topic_message, Types::True 18 | attribute? :is_automatic_forward, Types::True 19 | attribute? :reply_to_message, Message 20 | attribute? :external_reply, ExternalReplyInfo 21 | attribute? :quote, TextQuote 22 | attribute? :reply_to_story, Story 23 | attribute? :via_bot, User 24 | attribute? :edit_date, Types::Integer 25 | attribute? :has_protected_content, Types::True 26 | attribute? :is_from_offline, Types::True 27 | attribute? :media_group_id, Types::String 28 | attribute? :author_signature, Types::String 29 | attribute? :text, Types::String 30 | attribute? :entities, Types::Array.of(MessageEntity) 31 | attribute? :link_preview_options, LinkPreviewOptions 32 | attribute? :effect_id, Types::String 33 | attribute? :animation, Animation 34 | attribute? :audio, Audio 35 | attribute? :document, Document 36 | attribute? :paid_media, PaidMediaInfo 37 | attribute? :photo, Types::Array.of(PhotoSize) 38 | attribute? :sticker, Sticker 39 | attribute? :story, Story 40 | attribute? :video, Video 41 | attribute? :video_note, VideoNote 42 | attribute? :voice, Voice 43 | attribute? :caption, Types::String 44 | attribute? :caption_entities, Types::Array.of(MessageEntity) 45 | attribute? :show_caption_above_media, Types::True 46 | attribute? :has_media_spoiler, Types::True 47 | attribute? :contact, Contact 48 | attribute? :dice, Dice 49 | attribute? :game, Game 50 | attribute? :poll, Poll 51 | attribute? :venue, Venue 52 | attribute? :location, Location 53 | attribute? :new_chat_members, Types::Array.of(User) 54 | attribute? :left_chat_member, User 55 | attribute? :new_chat_title, Types::String 56 | attribute? :new_chat_photo, Types::Array.of(PhotoSize) 57 | attribute? :delete_chat_photo, Types::True 58 | attribute? :group_chat_created, Types::True 59 | attribute? :supergroup_chat_created, Types::True 60 | attribute? :channel_chat_created, Types::True 61 | attribute? :message_auto_delete_timer_changed, MessageAutoDeleteTimerChanged 62 | attribute? :migrate_to_chat_id, Types::Integer 63 | attribute? :migrate_from_chat_id, Types::Integer 64 | attribute? :pinned_message, MaybeInaccessibleMessage 65 | attribute? :invoice, Invoice 66 | attribute? :successful_payment, SuccessfulPayment 67 | attribute? :refunded_payment, RefundedPayment 68 | attribute? :users_shared, UsersShared 69 | attribute? :chat_shared, ChatShared 70 | attribute? :connected_website, Types::String 71 | attribute? :write_access_allowed, WriteAccessAllowed 72 | attribute? :passport_data, PassportData 73 | attribute? :proximity_alert_triggered, ProximityAlertTriggered 74 | attribute? :boost_added, ChatBoostAdded 75 | attribute? :chat_background_set, ChatBackground 76 | attribute? :forum_topic_created, ForumTopicCreated 77 | attribute? :forum_topic_edited, ForumTopicEdited 78 | attribute? :forum_topic_closed, ForumTopicClosed 79 | attribute? :forum_topic_reopened, ForumTopicReopened 80 | attribute? :general_forum_topic_hidden, GeneralForumTopicHidden 81 | attribute? :general_forum_topic_unhidden, GeneralForumTopicUnhidden 82 | attribute? :giveaway_created, GiveawayCreated 83 | attribute? :giveaway, Giveaway 84 | attribute? :giveaway_winners, GiveawayWinners 85 | attribute? :giveaway_completed, GiveawayCompleted 86 | attribute? :video_chat_scheduled, VideoChatScheduled 87 | attribute? :video_chat_started, VideoChatStarted 88 | attribute? :video_chat_ended, VideoChatEnded 89 | attribute? :video_chat_participants_invited, VideoChatParticipantsInvited 90 | attribute? :web_app_data, WebAppData 91 | attribute? :reply_markup, InlineKeyboardMarkup 92 | 93 | alias to_s text 94 | end 95 | end 96 | end 97 | end 98 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_auto_delete_timer_changed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageAutoDeleteTimerChanged < Base 7 | attribute :message_auto_delete_time, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_entity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageEntity < Base 7 | attribute :type, Types::String 8 | attribute :offset, Types::Integer 9 | attribute :length, Types::Integer 10 | attribute? :url, Types::String 11 | attribute? :user, User 12 | attribute? :language, Types::String 13 | attribute? :custom_emoji_id, Types::String 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_id.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageId < Base 7 | attribute :message_id, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_origin.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | MessageOrigin = ( 9 | MessageOriginUser | 10 | MessageOriginHiddenUser | 11 | MessageOriginChat | 12 | MessageOriginChannel 13 | ) 14 | # rubocop:enable Naming/ConstantName 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_origin_channel.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageOriginChannel < Base 7 | attribute :type, Types::String.constrained(eql: 'channel').default('channel') 8 | attribute :date, Types::Integer 9 | attribute :chat, Chat 10 | attribute :message_id, Types::Integer 11 | attribute? :author_signature, Types::String 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_origin_chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageOriginChat < Base 7 | attribute :type, Types::String.constrained(eql: 'chat').default('chat') 8 | attribute :date, Types::Integer 9 | attribute :sender_chat, Chat 10 | attribute? :author_signature, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_origin_hidden_user.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageOriginHiddenUser < Base 7 | attribute :type, Types::String.constrained(eql: 'hidden_user').default('hidden_user') 8 | attribute :date, Types::Integer 9 | attribute :sender_user_name, Types::String 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_origin_user.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageOriginUser < Base 7 | attribute :type, Types::String.constrained(eql: 'user').default('user') 8 | attribute :date, Types::Integer 9 | attribute :sender_user, User 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_reaction_count_updated.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageReactionCountUpdated < Base 7 | attribute :chat, Chat 8 | attribute :message_id, Types::Integer 9 | attribute :date, Types::Integer 10 | attribute :reactions, Types::Array.of(ReactionCount) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/message_reaction_updated.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class MessageReactionUpdated < Base 7 | attribute :chat, Chat 8 | attribute :message_id, Types::Integer 9 | attribute? :user, User 10 | attribute? :actor_chat, Chat 11 | attribute :date, Types::Integer 12 | attribute :old_reaction, Types::Array.of(ReactionType) 13 | attribute :new_reaction, Types::Array.of(ReactionType) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/order_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class OrderInfo < Base 7 | attribute? :name, Types::String 8 | attribute? :phone_number, Types::String 9 | attribute? :email, Types::String 10 | attribute? :shipping_address, ShippingAddress 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | PaidMedia = ( 9 | PaidMediaPreview | 10 | PaidMediaPhoto | 11 | PaidMediaVideo 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PaidMediaInfo < Base 7 | attribute :star_count, Types::Integer 8 | attribute :paid_media, Types::Array.of(PaidMedia) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media_photo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PaidMediaPhoto < Base 7 | attribute :type, Types::String.constrained(eql: 'photo').default('photo') 8 | attribute :photo, Types::Array.of(PhotoSize) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media_preview.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PaidMediaPreview < Base 7 | attribute :type, Types::String.constrained(eql: 'preview').default('preview') 8 | attribute? :width, Types::Integer 9 | attribute? :height, Types::Integer 10 | attribute? :duration, Types::Integer 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media_purchased.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PaidMediaPurchased < Base 7 | attribute :from, User 8 | attribute :paid_media_payload, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/paid_media_video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PaidMediaVideo < Base 7 | attribute :type, Types::String.constrained(eql: 'video').default('video') 8 | attribute :video, Video 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_data.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportData < Base 7 | attribute :data, Types::Array.of(EncryptedPassportElement) 8 | attribute :credentials, EncryptedCredentials 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | PassportElementError = ( 9 | PassportElementErrorDataField | 10 | PassportElementErrorFrontSide | 11 | PassportElementErrorReverseSide | 12 | PassportElementErrorSelfie | 13 | PassportElementErrorFile | 14 | PassportElementErrorFiles | 15 | PassportElementErrorTranslationFile | 16 | PassportElementErrorTranslationFiles | 17 | PassportElementErrorUnspecified 18 | ) 19 | # rubocop:enable Naming/ConstantName 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_data_field.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorDataField < Base 7 | attribute :source, Types::String.constrained(eql: 'data').default('data') 8 | attribute :type, Types::String 9 | attribute :field_name, Types::String 10 | attribute :data_hash, Types::String 11 | attribute :message, Types::String 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorFile < Base 7 | attribute :source, Types::String.constrained(eql: 'file').default('file') 8 | attribute :type, Types::String 9 | attribute :file_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_files.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorFiles < Base 7 | attribute :source, Types::String.constrained(eql: 'files').default('files') 8 | attribute :type, Types::String 9 | attribute :file_hashes, Types::Array.of(Types::String) 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_front_side.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorFrontSide < Base 7 | attribute :source, Types::String.constrained(eql: 'front_side').default('front_side') 8 | attribute :type, Types::String 9 | attribute :file_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_reverse_side.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorReverseSide < Base 7 | attribute :source, Types::String.constrained(eql: 'reverse_side').default('reverse_side') 8 | attribute :type, Types::String 9 | attribute :file_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_selfie.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorSelfie < Base 7 | attribute :source, Types::String.constrained(eql: 'selfie').default('selfie') 8 | attribute :type, Types::String 9 | attribute :file_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_translation_file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorTranslationFile < Base 7 | attribute :source, Types::String.constrained(eql: 'translation_file').default('translation_file') 8 | attribute :type, Types::String 9 | attribute :file_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_translation_files.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorTranslationFiles < Base 7 | attribute :source, Types::String.constrained(eql: 'translation_files').default('translation_files') 8 | attribute :type, Types::String 9 | attribute :file_hashes, Types::Array.of(Types::String) 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_element_error_unspecified.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportElementErrorUnspecified < Base 7 | attribute :source, Types::String.constrained(eql: 'unspecified').default('unspecified') 8 | attribute :type, Types::String 9 | attribute :element_hash, Types::String 10 | attribute :message, Types::String 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/passport_file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PassportFile < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :file_size, Types::Integer 10 | attribute :file_date, Types::Integer 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/pattern_matching.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | module PatternMatching 7 | def deconstruct_keys(_keys) 8 | attributes 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/photo_size.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PhotoSize < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :width, Types::Integer 10 | attribute :height, Types::Integer 11 | attribute? :file_size, Types::Integer 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/poll.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Poll < Base 7 | attribute :id, Types::String 8 | attribute :question, Types::String.constrained(min_size: 1, max_size: 300) 9 | attribute? :question_entities, Types::Array.of(MessageEntity) 10 | attribute :options, Types::Array.of(PollOption) 11 | attribute :total_voter_count, Types::Integer 12 | attribute :is_closed, Types::Bool 13 | attribute :is_anonymous, Types::Bool 14 | attribute :type, Types::String 15 | attribute :allows_multiple_answers, Types::Bool 16 | attribute? :correct_option_id, Types::Integer 17 | attribute? :explanation, Types::String 18 | attribute? :explanation_entities, Types::Array.of(MessageEntity) 19 | attribute? :open_period, Types::Integer 20 | attribute? :close_date, Types::Integer 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/poll_answer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PollAnswer < Base 7 | attribute :poll_id, Types::String 8 | attribute? :voter_chat, Chat 9 | attribute? :user, User 10 | attribute :option_ids, Types::Array.of(Types::Integer) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/poll_option.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PollOption < Base 7 | attribute :text, Types::String.constrained(min_size: 1, max_size: 100) 8 | attribute? :text_entities, Types::Array.of(MessageEntity) 9 | attribute :voter_count, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/pre_checkout_query.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PreCheckoutQuery < Base 7 | attribute :id, Types::String 8 | attribute :from, User 9 | attribute :currency, Types::String 10 | attribute :total_amount, Types::Integer 11 | attribute :invoice_payload, Types::String 12 | attribute? :shipping_option_id, Types::String 13 | attribute? :order_info, OrderInfo 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/prepared_inline_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class PreparedInlineMessage < Base 7 | attribute :id, Types::String 8 | attribute :expiration_date, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/proximity_alert_triggered.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ProximityAlertTriggered < Base 7 | attribute :traveler, User 8 | attribute :watcher, User 9 | attribute :distance, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reaction_count.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReactionCount < Base 7 | attribute :type, ReactionType 8 | attribute :total_count, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reaction_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | ReactionType = ( 9 | ReactionTypeEmoji | 10 | ReactionTypeCustomEmoji | 11 | ReactionTypePaid 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reaction_type_custom_emoji.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReactionTypeCustomEmoji < Base 7 | attribute :type, Types::String.constrained(eql: 'custom_emoji').default('custom_emoji') 8 | attribute :custom_emoji_id, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reaction_type_emoji.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReactionTypeEmoji < Base 7 | attribute :type, Types::String.constrained(eql: 'emoji').default('emoji') 8 | attribute :emoji, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reaction_type_paid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReactionTypePaid < Base 7 | attribute :type, Types::String.constrained(eql: 'paid').default('paid') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/refunded_payment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class RefundedPayment < Base 7 | attribute :currency, Types::String.constrained(eql: 'XTR').default('XTR') 8 | attribute :total_amount, Types::Integer 9 | attribute :invoice_payload, Types::String 10 | attribute :telegram_payment_charge_id, Types::String 11 | attribute? :provider_payment_charge_id, Types::String 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reply_keyboard_markup.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReplyKeyboardMarkup < Base 7 | attribute :keyboard, Types::Array.of(Types::Array.of(KeyboardButton)) 8 | attribute? :is_persistent, Types::Bool.default(false) 9 | attribute? :resize_keyboard, Types::Bool.default(false) 10 | attribute? :one_time_keyboard, Types::Bool.default(false) 11 | attribute? :input_field_placeholder, Types::String.constrained(min_size: 1, max_size: 64) 12 | attribute? :selective, Types::Bool 13 | 14 | def to_compact_hash 15 | hsh = super 16 | hsh[:keyboard].map! do |arr| 17 | arr.map do |item| 18 | item.is_a?(KeyboardButton) ? item.to_compact_hash : item 19 | end 20 | end 21 | 22 | hsh 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reply_keyboard_remove.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReplyKeyboardRemove < Base 7 | attribute :remove_keyboard, Types::True 8 | attribute? :selective, Types::Bool 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/reply_parameters.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ReplyParameters < Base 7 | attribute :message_id, Types::Integer 8 | attribute? :chat_id, Types::Integer | Types::String 9 | attribute? :allow_sending_without_reply, Types::Bool 10 | attribute? :quote, Types::String 11 | attribute? :quote_parse_mode, Types::String 12 | attribute? :quote_entities, Types::Array.of(MessageEntity) 13 | attribute? :quote_position, Types::Integer 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/response_parameters.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ResponseParameters < Base 7 | attribute? :migrate_to_chat_id, Types::Integer 8 | attribute? :retry_after, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/revenue_withdrawal_state.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | RevenueWithdrawalState = ( 9 | RevenueWithdrawalStatePending | 10 | RevenueWithdrawalStateSucceeded | 11 | RevenueWithdrawalStateFailed 12 | ) 13 | # rubocop:enable Naming/ConstantName 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/revenue_withdrawal_state_failed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class RevenueWithdrawalStateFailed < Base 7 | attribute :type, Types::String.constrained(eql: 'failed').default('failed') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/revenue_withdrawal_state_pending.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class RevenueWithdrawalStatePending < Base 7 | attribute :type, Types::String.constrained(eql: 'pending').default('pending') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/revenue_withdrawal_state_succeeded.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class RevenueWithdrawalStateSucceeded < Base 7 | attribute :type, Types::String.constrained(eql: 'succeeded').default('succeeded') 8 | attribute :date, Types::Integer 9 | attribute :url, Types::String 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/sent_web_app_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class SentWebAppMessage < Base 7 | attribute? :inline_message_id, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/shared_user.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class SharedUser < Base 7 | attribute :user_id, Types::Integer 8 | attribute? :first_name, Types::String 9 | attribute? :last_name, Types::String 10 | attribute? :username, Types::String 11 | attribute? :photo, Types::Array.of(PhotoSize) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/shipping_address.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ShippingAddress < Base 7 | attribute :country_code, Types::String 8 | attribute :state, Types::String 9 | attribute :city, Types::String 10 | attribute :street_line1, Types::String 11 | attribute :street_line2, Types::String 12 | attribute :post_code, Types::String 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/shipping_option.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ShippingOption < Base 7 | attribute :id, Types::String 8 | attribute :title, Types::String 9 | attribute :prices, Types::Array.of(LabeledPrice) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/shipping_query.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class ShippingQuery < Base 7 | attribute :id, Types::String 8 | attribute :from, User 9 | attribute :invoice_payload, Types::String 10 | attribute :shipping_address, ShippingAddress 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/star_transaction.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class StarTransaction < Base 7 | attribute :id, Types::String 8 | attribute :amount, Types::Integer 9 | attribute? :nanostar_amount, Types::Integer 10 | attribute :date, Types::Integer 11 | attribute? :source, TransactionPartner 12 | attribute? :receiver, TransactionPartner 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/star_transactions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class StarTransactions < Base 7 | attribute :transactions, Types::Array.of(StarTransaction) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/sticker.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Sticker < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :type, Types::String 10 | attribute :width, Types::Integer 11 | attribute :height, Types::Integer 12 | attribute :is_animated, Types::Bool 13 | attribute :is_video, Types::Bool 14 | attribute? :thumbnail, PhotoSize 15 | attribute? :emoji, Types::String 16 | attribute? :set_name, Types::String 17 | attribute? :premium_animation, File 18 | attribute? :mask_position, MaskPosition 19 | attribute? :custom_emoji_id, Types::String 20 | attribute? :needs_repainting, Types::True 21 | attribute? :file_size, Types::Integer 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/sticker_set.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class StickerSet < Base 7 | attribute :name, Types::String 8 | attribute :title, Types::String 9 | attribute :sticker_type, Types::String 10 | attribute :stickers, Types::Array.of(Sticker) 11 | attribute? :thumbnail, PhotoSize 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/story.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Story < Base 7 | attribute :chat, Chat 8 | attribute :id, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/successful_payment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class SuccessfulPayment < Base 7 | attribute :currency, Types::String 8 | attribute :total_amount, Types::Integer 9 | attribute :invoice_payload, Types::String 10 | attribute? :subscription_expiration_date, Types::Integer 11 | attribute? :is_recurring, Types::True 12 | attribute? :is_first_recurring, Types::True 13 | attribute? :shipping_option_id, Types::String 14 | attribute? :order_info, OrderInfo 15 | attribute :telegram_payment_charge_id, Types::String 16 | attribute :provider_payment_charge_id, Types::String 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/switch_inline_query_chosen_chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class SwitchInlineQueryChosenChat < Base 7 | attribute? :query, Types::String 8 | attribute? :allow_user_chats, Types::Bool 9 | attribute? :allow_bot_chats, Types::Bool 10 | attribute? :allow_group_chats, Types::Bool 11 | attribute? :allow_channel_chats, Types::Bool 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/text_quote.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TextQuote < Base 7 | attribute :text, Types::String 8 | attribute? :entities, Types::Array.of(MessageEntity) 9 | attribute :position, Types::Integer 10 | attribute? :is_manual, Types::True 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | TransactionPartner = ( 9 | TransactionPartnerUser | 10 | TransactionPartnerChat | 11 | TransactionPartnerAffiliateProgram | 12 | TransactionPartnerFragment | 13 | TransactionPartnerTelegramAds | 14 | TransactionPartnerTelegramApi | 15 | TransactionPartnerOther 16 | ) 17 | # rubocop:enable Naming/ConstantName 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_affiliate_program.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerAffiliateProgram < Base 7 | attribute :type, Types::String.constrained(eql: 'affiliate_program').default('affiliate_program') 8 | attribute? :sponsor_user, User 9 | attribute :commission_per_mille, Types::Integer 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_chat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerChat < Base 7 | attribute :type, Types::String.constrained(eql: 'chat').default('chat') 8 | attribute :chat, Chat 9 | attribute? :gift, Gift 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_fragment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerFragment < Base 7 | attribute :type, Types::String.constrained(eql: 'fragment').default('fragment') 8 | attribute? :withdrawal_state, RevenueWithdrawalState 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_other.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerOther < Base 7 | attribute :type, Types::String.constrained(eql: 'other').default('other') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_telegram_ads.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerTelegramAds < Base 7 | attribute :type, Types::String.constrained(eql: 'telegram_ads').default('telegram_ads') 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_telegram_api.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerTelegramApi < Base 7 | attribute :type, Types::String.constrained(eql: 'telegram_api').default('telegram_api') 8 | attribute :request_count, Types::Integer 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/transaction_partner_user.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class TransactionPartnerUser < Base 7 | attribute :type, Types::String.constrained(eql: 'user').default('user') 8 | attribute :user, User 9 | attribute? :affiliate, AffiliateInfo 10 | attribute? :invoice_payload, Types::String 11 | attribute? :subscription_period, Types::Integer 12 | attribute? :paid_media, Types::Array.of(PaidMedia) 13 | attribute? :paid_media_payload, Types::String 14 | attribute? :gift, Gift 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/update.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Update < Base 7 | attribute :update_id, Types::Integer 8 | attribute? :message, Message 9 | attribute? :edited_message, Message 10 | attribute? :channel_post, Message 11 | attribute? :edited_channel_post, Message 12 | attribute? :business_connection, BusinessConnection 13 | attribute? :business_message, Message 14 | attribute? :edited_business_message, Message 15 | attribute? :deleted_business_messages, BusinessMessagesDeleted 16 | attribute? :message_reaction, MessageReactionUpdated 17 | attribute? :message_reaction_count, MessageReactionCountUpdated 18 | attribute? :inline_query, InlineQuery 19 | attribute? :chosen_inline_result, ChosenInlineResult 20 | attribute? :callback_query, CallbackQuery 21 | attribute? :shipping_query, ShippingQuery 22 | attribute? :pre_checkout_query, PreCheckoutQuery 23 | attribute? :purchased_paid_media, PaidMediaPurchased 24 | attribute? :poll, Poll 25 | attribute? :poll_answer, PollAnswer 26 | attribute? :my_chat_member, ChatMemberUpdated 27 | attribute? :chat_member, ChatMemberUpdated 28 | attribute? :chat_join_request, ChatJoinRequest 29 | attribute? :chat_boost, ChatBoostUpdated 30 | attribute? :removed_chat_boost, ChatBoostRemoved 31 | 32 | def current_message 33 | @current_message ||= 34 | Hash[*attributes.find { |k, v| k != :update_id && v }].values.first 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/user.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class User < Base 7 | attribute :id, Types::Integer 8 | attribute :is_bot, Types::Bool 9 | attribute :first_name, Types::String 10 | attribute? :last_name, Types::String 11 | attribute? :username, Types::String 12 | attribute? :language_code, Types::String 13 | attribute? :is_premium, Types::True 14 | attribute? :added_to_attachment_menu, Types::True 15 | attribute? :can_join_groups, Types::Bool 16 | attribute? :can_read_all_group_messages, Types::Bool 17 | attribute? :supports_inline_queries, Types::Bool 18 | attribute? :can_connect_to_business, Types::Bool 19 | attribute? :has_main_web_app, Types::Bool 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/user_chat_boosts.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class UserChatBoosts < Base 7 | attribute :boosts, Types::Array.of(ChatBoost) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/user_profile_photos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class UserProfilePhotos < Base 7 | attribute :total_count, Types::Integer 8 | attribute :photos, Types::Array.of(Types::Array.of(PhotoSize)) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/users_shared.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class UsersShared < Base 7 | attribute :request_id, Types::Integer 8 | attribute :users, Types::Array.of(SharedUser) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/venue.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Venue < Base 7 | attribute :location, Location 8 | attribute :title, Types::String 9 | attribute :address, Types::String 10 | attribute? :foursquare_id, Types::String 11 | attribute? :foursquare_type, Types::String 12 | attribute? :google_place_id, Types::String 13 | attribute? :google_place_type, Types::String 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Video < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :width, Types::Integer 10 | attribute :height, Types::Integer 11 | attribute :duration, Types::Integer 12 | attribute? :thumbnail, PhotoSize 13 | attribute? :cover, Types::Array.of(PhotoSize) 14 | attribute? :start_timestamp, Types::Integer 15 | attribute? :file_name, Types::String 16 | attribute? :mime_type, Types::String 17 | attribute? :file_size, Types::Integer 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video_chat_ended.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class VideoChatEnded < Base 7 | attribute :duration, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video_chat_participants_invited.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class VideoChatParticipantsInvited < Base 7 | attribute :users, Types::Array.of(User) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video_chat_scheduled.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class VideoChatScheduled < Base 7 | attribute :start_date, Types::Integer 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video_chat_started.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class VideoChatStarted < Base 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/video_note.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class VideoNote < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :length, Types::Integer 10 | attribute :duration, Types::Integer 11 | attribute? :thumbnail, PhotoSize 12 | attribute? :file_size, Types::Integer 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/voice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class Voice < Base 7 | attribute :file_id, Types::String 8 | attribute :file_unique_id, Types::String 9 | attribute :duration, Types::Integer 10 | attribute? :mime_type, Types::String 11 | attribute? :file_size, Types::Integer 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/web_app_data.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class WebAppData < Base 7 | attribute :data, Types::String 8 | attribute :button_text, Types::String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/web_app_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class WebAppInfo < Base 7 | attribute :url, Types::String 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/webhook_info.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class WebhookInfo < Base 7 | attribute :url, Types::String 8 | attribute :has_custom_certificate, Types::Bool 9 | attribute :pending_update_count, Types::Integer 10 | attribute? :ip_address, Types::String 11 | attribute? :last_error_date, Types::Integer 12 | attribute? :last_error_message, Types::String 13 | attribute? :last_synchronization_error_date, Types::Integer 14 | attribute? :max_connections, Types::Integer 15 | attribute? :allowed_updates, Types::Array.of(Types::String) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/telegram/bot/types/write_access_allowed.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class WriteAccessAllowed < Base 7 | attribute? :from_request, Types::Bool 8 | attribute? :web_app_name, Types::String 9 | attribute? :from_attachment_menu, Types::Bool 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/telegram/bot/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | VERSION = '2.4.0' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /rakelib/parse_schema.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'openapi3_parser' 4 | 5 | desc 'Parse types from public json, should be up to date https://github.com/ark0f/tg-bot-api' 6 | task :parse_schema do 7 | document = Openapi3Parser.load_url('https://ark0f.github.io/tg-bot-api/openapi.json') 8 | 9 | result = document.components.schemas.to_h do |type_name, schema| 10 | type_schema = schema.properties.to_h do |property_name, property_schema| 11 | attribute = { type: parse_initial_type(property_schema, property_name) } 12 | 13 | unless property_schema.any_of.nil? 14 | attribute[:type] = property_schema.any_of.map { |item| property_schema.name || item.name || item.type }.uniq 15 | end 16 | 17 | # Input File is literally just a string for our purpose 18 | attribute[:type]&.delete('InputFile') 19 | attribute[:type] = attribute[:type].join if attribute[:type]&.length == 1 20 | 21 | attribute[:required] = true if required_keys(schema).include?(property_name) 22 | 23 | # getting required values from the description, no values in json 😔 24 | required_value = property_schema.description&.match(/always “(.+)”|must be \*(.+)\*/) 25 | attribute[:required_value] = (required_value[1] || required_value[2]).delete('\\') if required_value 26 | 27 | # for some reason every property's minLength is 0 by default, probably parser bug, had to ignore that 28 | attribute[:min_size] = property_schema[:minLength] if property_schema[:minLength] != 0 29 | attribute[:max_size] = property_schema[:maxLength] if property_schema[:maxLength] 30 | 31 | attribute[:items] = property_schema.items.type if property_schema&.items 32 | if property_schema&.type == 'array' && property_schema&.items&.type.nil? 33 | attribute[:items] = property_schema&.items&.name 34 | end 35 | 36 | attribute[:items] = property_schema.items.name if property_schema&.items&.type == 'object' 37 | 38 | # array of arrays 39 | if property_schema&.items&.type == 'array' 40 | attribute[:items] = { type: 'array', items: property_schema.items.items.name } 41 | end 42 | 43 | attribute = apply_default_schema(attribute, property_schema) 44 | [property_name, attribute] 45 | end 46 | 47 | # find empty classes 48 | type_schema[:type] = schema.any_of.map(&:name) if schema.properties.empty? && schema.any_of 49 | [type_name, type_schema] 50 | end 51 | 52 | # Input File is literally just a string for our purpose 53 | File.write "#{__dir__}/../data/type_attributes.json", JSON.pretty_generate(result.except('InputFile')) 54 | end 55 | 56 | def required_keys(schema) 57 | schema.required.to_a || [] 58 | end 59 | 60 | def apply_default_schema(attribute, property_schema) 61 | attribute[:default] = property_schema.default unless property_schema.default.nil? 62 | # previous line would have been enough, but had to check the description due to issue: https://github.com/kevindew/openapi3_parser/issues/28 63 | attribute[:default] = false if property_schema.description&.include?('Defaults to *false*') 64 | attribute 65 | end 66 | 67 | def parse_initial_type(property_schema, property_name) 68 | case property_schema.type 69 | when nil then property_name.capitalize.gsub(/_(\w)/) { Regexp.last_match(1).upcase } 70 | when 'object' then property_schema.name 71 | else property_schema.type 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /rakelib/rebuild_types.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'json' 4 | require 'erb' 5 | DRY_TYPES = %w[string integer float decimal array hash symbol boolean date date_time time range].freeze 6 | 7 | desc 'Rebuild types' 8 | task :rebuild_types do 9 | types = JSON.parse(File.read("#{__dir__}/../data/type_attributes.json"), symbolize_names: true) 10 | 11 | types.each_pair do |name, attributes| 12 | next build_empty_type(name, attributes) if attributes[:type].instance_of?(Array) 13 | 14 | attributes.each_pair do |attr_name, properties| 15 | attributes[attr_name][:type] = add_module_types(properties[:type]) unless properties[:type].is_a?(Array) 16 | if properties[:type].is_a?(Array) 17 | attributes[attr_name][:type] = properties[:type].map do |type| 18 | add_module_types(type) 19 | end.join(' | ') 20 | end 21 | 22 | if properties[:items].instance_of?(String) 23 | attributes[attr_name][:type] += ".of(#{add_module_types(properties[:items])})" 24 | elsif properties[:items] && properties[:items][:type] == 'array' 25 | attributes[attr_name][:type] += ".of(Types::Array.of(#{properties[:items][:items]}))" 26 | end 27 | original_type = properties[:type] 28 | 29 | attributes = apply_required(attributes, attr_name, properties, original_type) 30 | attributes = apply_min_max(attributes, attr_name, properties) 31 | attributes = apply_default(attributes, attr_name, properties, original_type) 32 | 33 | attributes[attr_name][:type] = 'Types::True' if attributes[attr_name][:type] == 'Types::Boolean.default(true)' 34 | attributes[attr_name][:type] = attributes[attr_name][:type].gsub('Types::Boolean', 'Types::Bool') 35 | end 36 | 37 | File.write "#{__dir__}/../lib/telegram/bot/types/#{underscore(name)}.rb", 38 | ERB.new(File.read("#{__dir__}/templates/type.erb")).result(binding).gsub(" \n", '') 39 | end 40 | end 41 | 42 | def build_empty_type(name, attributes) 43 | attributes = attributes[:type].join(" |\n ") 44 | File.write "#{__dir__}/../lib/telegram/bot/types/#{underscore(name)}.rb", 45 | ERB.new(File.read("#{__dir__}/templates/empty_type.erb")).result(binding).gsub(" \n", '') 46 | end 47 | 48 | def apply_default(attributes, attr_name, properties, original_type) 49 | return attributes if properties[:default].nil? 50 | 51 | attributes[attr_name][:type] += ".default(#{typecast(original_type, 52 | properties[:default])})" 53 | attributes 54 | end 55 | 56 | def apply_required(attributes, attr_name, properties, original_type) 57 | return attributes unless properties[:required_value] 58 | 59 | attributes[attr_name][:type] += ".constrained(eql: #{typecast(original_type, 60 | properties[:required_value])})" 61 | attributes 62 | end 63 | 64 | def apply_min_max(attributes, attr_name, properties) 65 | return attributes unless properties[:min_size] || properties[:max_size] 66 | 67 | constrain = '.constrained(minmax)' 68 | constrain = properties[:min_size] ? constrain.gsub('min', "min_size: #{properties[:min_size]}, ") : '' 69 | constrain = constrain.gsub('max', "max_size: #{properties[:max_size]}") if properties[:max_size] 70 | attributes[attr_name][:type] += constrain 71 | attributes 72 | end 73 | 74 | def add_module_types(type) 75 | return 'Types::Float' if type == 'number' 76 | 77 | DRY_TYPES.include?(type) ? "Types::#{type.capitalize}" : type 78 | end 79 | 80 | def underscore(camel_cased_word) 81 | camel_cased_word.to_s.gsub('::', '/') 82 | .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') 83 | .gsub(/([a-z\d])([A-Z])/, '\1_\2') 84 | .tr('-', '_') 85 | .downcase 86 | end 87 | 88 | def typecast(type, obj) 89 | type == 'Types::String' ? "'#{obj}'" : obj 90 | end 91 | -------------------------------------------------------------------------------- /rakelib/templates/empty_type.erb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | ## Just for classes consistency 7 | # rubocop:disable Naming/ConstantName 8 | <%= name %> = ( 9 | <%= attributes %> 10 | ) 11 | # rubocop:enable Naming/ConstantName 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /rakelib/templates/type.erb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Telegram 4 | module Bot 5 | module Types 6 | class <%= name %> < Base 7 | <% attributes.each_pair do |name, properties| %> 8 | <%= "#{properties[:required] ? 'attribute' : 'attribute?'} :#{name}, #{properties[:type]}" %> 9 | <% end %> 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_call/has_result.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:06:03 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '200' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"id":2200529744,"is_bot":true,"first_name":"Test 40 | bot","username":"alexwayfer_test_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}' 41 | recorded_at: Mon, 17 Jul 2023 09:06:03 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_call/has_status.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:06:02 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '200' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"id":2200529744,"is_bot":true,"first_name":"Test 40 | bot","username":"alexwayfer_test_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}' 41 | recorded_at: Mon, 17 Jul 2023 09:06:02 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_call/returns_hash.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:06:02 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '200' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"id":2200529744,"is_bot":true,"first_name":"Test 40 | bot","username":"alexwayfer_test_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}' 41 | recorded_at: Mon, 17 Jul 2023 09:06:02 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_call/when_token_is_invalid/raises_an_error.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot123456:wrongtoken/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 401 17 | message: Unauthorized 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:06:03 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '58' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-expose-headers: 34 | - Content-Length,Content-Type,Date,Server,Connection 35 | body: 36 | encoding: UTF-8 37 | string: '{"ok":false,"error_code":401,"description":"Unauthorized"}' 38 | recorded_at: Mon, 17 Jul 2023 09:06:03 GMT 39 | recorded_with: VCR 6.1.0 40 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_getMe/1_3_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 09:12:16 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '200' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"id":2200529744,"is_bot":true,"first_name":"Test 40 | bot","username":"alexwayfer_test_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}' 41 | recorded_at: Mon, 21 Aug 2023 09:12:16 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_getMyCommands/1_6_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMyCommands 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 10:01:01 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '115' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":[{"command":"menu","description":"Show actions"},{"command":"help","description":"Show 40 | help"}]}' 41 | recorded_at: Mon, 21 Aug 2023 10:01:01 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_getMyDescription/1_5_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMyDescription 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 10:01:00 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '39' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"description":""}}' 40 | recorded_at: Mon, 21 Aug 2023 10:01:00 GMT 41 | recorded_with: VCR 6.1.0 42 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Api/_getMyName/1_4_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMyName 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 10:00:59 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '40' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"name":"Test bot"}}' 40 | recorded_at: Mon, 21 Aug 2023 10:00:59 GMT 41 | recorded_with: VCR 6.1.0 42 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Client/_run/returns_hash.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot/test/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 200 17 | message: OK 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:08:44 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '200' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-allow-methods: 34 | - GET, POST, OPTIONS 35 | access-control-expose-headers: 36 | - Content-Length,Content-Type,Date,Server,Connection 37 | body: 38 | encoding: UTF-8 39 | string: '{"ok":true,"result":{"id":2200529744,"is_bot":true,"first_name":"Test 40 | bot","username":"alexwayfer_test_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}}' 41 | recorded_at: Mon, 17 Jul 2023 09:08:44 GMT 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Exceptions_ResponseError/_data/1_3_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot123456:wrongtoken/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 401 17 | message: Unauthorized 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 09:12:18 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '58' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-expose-headers: 34 | - Content-Length,Content-Type,Date,Server,Connection 35 | body: 36 | encoding: UTF-8 37 | string: '{"ok":false,"error_code":401,"description":"Unauthorized"}' 38 | recorded_at: Mon, 21 Aug 2023 09:12:18 GMT 39 | recorded_with: VCR 6.1.0 40 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Exceptions_ResponseError/_error_code/1_1_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot123456:wrongtoken/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 401 17 | message: Unauthorized 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 09:12:17 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '58' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-expose-headers: 34 | - Content-Length,Content-Type,Date,Server,Connection 35 | body: 36 | encoding: UTF-8 37 | string: '{"ok":false,"error_code":401,"description":"Unauthorized"}' 38 | recorded_at: Mon, 21 Aug 2023 09:12:17 GMT 39 | recorded_with: VCR 6.1.0 40 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Exceptions_ResponseError/_to_s/1_2_1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot123456:wrongtoken/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 401 17 | message: Unauthorized 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 21 Aug 2023 09:12:17 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '58' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-expose-headers: 34 | - Content-Length,Content-Type,Date,Server,Connection 35 | body: 36 | encoding: UTF-8 37 | string: '{"ok":false,"error_code":401,"description":"Unauthorized"}' 38 | recorded_at: Mon, 21 Aug 2023 09:12:18 GMT 39 | recorded_with: VCR 6.1.0 40 | -------------------------------------------------------------------------------- /spec/cassettes/Telegram_Bot_Exceptions_ResponseError/has_error_code.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.telegram.org/bot123456:wrongtoken/getMe 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.7.10 12 | Content-Type: 13 | - application/x-www-form-urlencoded 14 | response: 15 | status: 16 | code: 401 17 | message: Unauthorized 18 | headers: 19 | server: 20 | - nginx/1.18.0 21 | date: 22 | - Mon, 17 Jul 2023 09:08:44 GMT 23 | content-type: 24 | - application/json 25 | content-length: 26 | - '58' 27 | connection: 28 | - keep-alive 29 | strict-transport-security: 30 | - max-age=31536000; includeSubDomains; preload 31 | access-control-allow-origin: 32 | - "*" 33 | access-control-expose-headers: 34 | - Content-Length,Content-Type,Date,Server,Connection 35 | body: 36 | encoding: UTF-8 37 | string: '{"ok":false,"error_code":401,"description":"Unauthorized"}' 38 | recorded_at: Mon, 17 Jul 2023 09:08:44 GMT 39 | recorded_with: VCR 6.1.0 40 | -------------------------------------------------------------------------------- /spec/lib/telegram/bot/api_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Telegram::Bot::Api, :vcr do 4 | let(:token) { ENV.fetch('BOT_API_TOKEN') } 5 | let(:environment) { ENV.fetch('BOT_API_ENV', :test) } 6 | let(:endpoint) { 'getMe' } 7 | let(:api) { described_class.new(token, environment: environment) } 8 | 9 | describe '#call' do 10 | subject(:api_call) { api.call(endpoint) } 11 | 12 | it 'returns hash' do 13 | expect(api_call).to be_a(Hash) 14 | end 15 | 16 | it 'has status' do 17 | expect(api_call).to have_key('ok') 18 | end 19 | 20 | it 'has result' do 21 | expect(api_call).to have_key('result') 22 | end 23 | 24 | context 'when token is invalid' do 25 | let(:token) { '123456:wrongtoken' } 26 | 27 | it 'raises an error' do 28 | expect { api_call }.to raise_error( 29 | Telegram::Bot::Exceptions::ResponseError, 30 | 'Telegram API has returned the error. (ok: false, error_code: 401, description: "Unauthorized")' 31 | ) 32 | end 33 | end 34 | 35 | context 'with low timeout' do 36 | before do 37 | Telegram::Bot.configure { |config| config.connection_timeout = 0.001 } 38 | end 39 | 40 | after do 41 | Telegram::Bot.configure { |config| config.connection_timeout = 30 } 42 | end 43 | 44 | it 'raises an error' do 45 | expect { api_call } 46 | .to raise_error(Faraday::TimeoutError) 47 | end 48 | end 49 | 50 | context 'with low open_timeout' do 51 | before do 52 | Telegram::Bot.configure { |config| config.connection_open_timeout = 0.001 } 53 | end 54 | 55 | after do 56 | Telegram::Bot.configure { |config| config.connection_open_timeout = 30 } 57 | end 58 | 59 | it 'raises an error' do 60 | expect { api_call } 61 | .to raise_error(Faraday::ConnectionFailed) 62 | end 63 | end 64 | end 65 | 66 | describe '#method_missing' do 67 | subject { api } 68 | 69 | it 'responds to endpoints' do 70 | expect(api).to respond_to(endpoint) 71 | end 72 | 73 | context 'when method name is in snake case' do 74 | let(:endpoint) { 'get_me' } 75 | 76 | it 'responds to snake-cased endpoints' do 77 | expect(api).to respond_to(endpoint) 78 | end 79 | end 80 | end 81 | 82 | describe '#getMe' do 83 | subject { api.getMe } 84 | 85 | it { is_expected.to be_an_instance_of(Telegram::Bot::Types::User) } 86 | end 87 | 88 | describe '#getMyName' do 89 | subject { api.getMyName } 90 | 91 | it { is_expected.to be_an_instance_of(Telegram::Bot::Types::BotName) } 92 | end 93 | 94 | describe '#getMyDescription' do 95 | subject { api.getMyDescription } 96 | 97 | it { is_expected.to be_an_instance_of(Telegram::Bot::Types::BotDescription) } 98 | end 99 | 100 | describe '#getMyCommands' do 101 | subject { api.getMyCommands } 102 | 103 | it { is_expected.to all be_an_instance_of(Telegram::Bot::Types::BotCommand) } 104 | end 105 | 106 | pending '#getChatMenuButton' 107 | 108 | ## I don't know why `setChatMenuButton` returns `OK` but changes nothing 109 | ## Code is commented, because `pending` is not enough: 110 | ## some of these specs are not failing returning the same button as it was 111 | 112 | # describe '#getChatMenuButton' do 113 | # subject { api.getChatMenuButton } 114 | # 115 | # context "when it's commands" do 116 | # let(:menu_button) { Telegram::Bot::Types::MenuButtonCommands.new } 117 | # 118 | # around do |example| 119 | # # api.send(:connection).response :logger, nil, { headers: true, bodies: true } 120 | # 121 | # old_menu_button = api.getChatMenuButton 122 | # api.setChatMenuButton(menu_button: menu_button) 123 | # 124 | # example.run 125 | # 126 | # api.setChatMenuButton(menu_button: old_menu_button) 127 | # end 128 | # 129 | # it { is_expected.to eq menu_button } 130 | # end 131 | # 132 | # context "when it's web app" do 133 | # let(:menu_button) do 134 | # Telegram::Bot::Types::MenuButtonWebApp.new( 135 | # text: 'Open link', 136 | # web_app: Telegram::Bot::Types::WebAppInfo.new(url: 'https://example.org/') 137 | # ) 138 | # end 139 | # 140 | # around do |example| 141 | # # api.send(:connection).response :logger, nil, { headers: true, bodies: true } 142 | # 143 | # old_menu_button = api.getChatMenuButton 144 | # api.setChatMenuButton(menu_button: menu_button) 145 | # 146 | # example.run 147 | # 148 | # api.setChatMenuButton(menu_button: old_menu_button) 149 | # end 150 | # 151 | # it { is_expected.to eq menu_button } 152 | # end 153 | # end 154 | 155 | describe '#getUpdates' do 156 | subject { api.getUpdates } 157 | 158 | describe 'with chat member' do 159 | let(:stubbed_response) do 160 | { 161 | 'ok' => true, 162 | 'result' => [ 163 | { 164 | 'update_id' => 111_111, 165 | 'my_chat_member' => { 166 | 'chat' => { 167 | 'id' => 222_222, 168 | 'first_name' => 'Alexander', 169 | 'last_name' => 'Popov', 170 | 'username' => 'AlexWayfer', 171 | 'type' => 'private' 172 | }, 173 | 'from' => { 174 | 'id' => 222_222, 175 | 'is_bot' => false, 176 | 'first_name' => 'Alexander', 177 | 'last_name' => 'Popov', 178 | 'username' => 'AlexWayfer', 179 | 'language_code' => 'en', 180 | 'is_premium' => true 181 | }, 182 | 'date' => 1_689_850_120, 183 | 'old_chat_member' => { 184 | 'user' => { 185 | 'id' => 333_333, 186 | 'is_bot' => true, 187 | 'first_name' => 'Test Bot', 188 | 'username' => 'test_bot' 189 | }, 190 | 'status' => 'member' 191 | }, 192 | 'new_chat_member' => { 193 | 'user' => { 194 | 'id' => 333_333, 195 | 'is_bot' => true, 196 | 'first_name' => 'Test Bot', 197 | 'username' => 'test_bot' 198 | }, 199 | 'status' => 'kicked', 200 | 'until_date' => 0 201 | } 202 | } 203 | } 204 | ] 205 | } 206 | end 207 | 208 | let(:expected_data) do 209 | [ 210 | Telegram::Bot::Types::Update.new( 211 | 'update_id' => 111_111, 212 | 'my_chat_member' => Telegram::Bot::Types::ChatMemberUpdated.new( 213 | 'chat' => Telegram::Bot::Types::Chat.new( 214 | 'id' => 222_222, 215 | 'first_name' => 'Alexander', 216 | 'last_name' => 'Popov', 217 | 'username' => 'AlexWayfer', 218 | 'type' => 'private' 219 | ), 220 | 'from' => Telegram::Bot::Types::User.new( 221 | 'id' => 222_222, 222 | 'is_bot' => false, 223 | 'first_name' => 'Alexander', 224 | 'last_name' => 'Popov', 225 | 'username' => 'AlexWayfer', 226 | 'language_code' => 'en', 227 | 'is_premium' => true 228 | ), 229 | 'date' => 1_689_850_120, 230 | 'old_chat_member' => Telegram::Bot::Types::ChatMemberMember.new( 231 | 'user' => { 232 | 'id' => 333_333, 233 | 'is_bot' => true, 234 | 'first_name' => 'Test Bot', 235 | 'username' => 'test_bot' 236 | }, 237 | 'status' => 'member' 238 | ), 239 | 'new_chat_member' => Telegram::Bot::Types::ChatMemberBanned.new( 240 | 'user' => { 241 | 'id' => 333_333, 242 | 'is_bot' => true, 243 | 'first_name' => 'Test Bot', 244 | 'username' => 'test_bot' 245 | }, 246 | 'status' => 'kicked', 247 | 'until_date' => 0 248 | ) 249 | ) 250 | ) 251 | ] 252 | end 253 | 254 | before do 255 | allow(api).to receive(:call).with('getUpdates').and_return(stubbed_response) 256 | end 257 | 258 | it { is_expected.to eq expected_data } 259 | end 260 | end 261 | end 262 | -------------------------------------------------------------------------------- /spec/lib/telegram/bot/client_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Telegram::Bot::Client, :vcr do 4 | subject(:client) { described_class.new(token, environment: environment) } 5 | 6 | let(:token) { ENV.fetch('BOT_API_TOKEN') } 7 | let(:environment) { ENV.fetch('BOT_API_ENV', :test) } 8 | 9 | describe '#run' do 10 | it 'accepts block with itself as an argument' do 11 | result = nil 12 | client.run { |something| result = something } 13 | 14 | expect(result).to be client 15 | end 16 | end 17 | 18 | describe '#stop' do 19 | context 'when bot receives messages' do 20 | before do 21 | allow(client.api).to receive(:getUpdates).and_return [Telegram::Bot::Types::Update.new(update_id: 111_111)] 22 | 23 | current_times = 0 24 | 25 | client.listen do |_message| 26 | current_times += 1 27 | client.stop if current_times == expected_times 28 | end 29 | end 30 | 31 | let(:expected_times) { 3 } 32 | 33 | specify do 34 | expect(client.api).to have_received(:getUpdates).exactly(expected_times).times 35 | end 36 | end 37 | 38 | context 'when bot does not receive any messages' do 39 | before do 40 | current_times = 0 41 | 42 | allow(client.api).to receive(:getUpdates) do 43 | if current_times >= expected_times - 1 44 | client.stop 45 | raise Faraday::TimeoutError 46 | end 47 | 48 | [Telegram::Bot::Types::Update.new(update_id: 111_111)] 49 | end 50 | 51 | client.listen do |_message| 52 | current_times += 1 53 | end 54 | end 55 | 56 | let(:expected_times) { 3 } 57 | 58 | specify do 59 | expect(client.api).to have_received(:getUpdates).exactly(expected_times).times 60 | end 61 | end 62 | end 63 | 64 | describe '#fetch_updates' do 65 | before do 66 | allow(client.api).to receive(:call).with('getUpdates', hash_including(offset: 0)).and_return( 67 | { 68 | 'ok' => true, 69 | 'result' => [ 70 | { 71 | 'update_id' => 222_222, 72 | 'message' => { 73 | 'message_id' => 333_333, 74 | 'from' => { 75 | 'id' => 111_111, 76 | 'is_bot' => false, 77 | 'first_name' => 'Alexander' 78 | # "last_name"=>"Popov", 79 | # "username"=>"AlexWayfer", 80 | # "language_code"=>"en", 81 | # "is_premium"=>true 82 | }, 83 | 'chat' => { 84 | 'id' => 444_444, 85 | # 'first_name' => 'Alexander', 86 | # "last_name"=>"Popov", 87 | # "username"=>"AlexWayfer", 88 | 'type' => 'private' 89 | }, 90 | 'date' => 1_688_640_799, 91 | 'text' => '/start' 92 | # "entities" => [{"offset"=>0, "length"=>6, "type"=>"bot_command"}] 93 | } 94 | } 95 | ] 96 | } 97 | ).once 98 | end 99 | 100 | it 'accepts block and pass Message into it' do 101 | result = nil 102 | client.fetch_updates { |something| result = something } 103 | 104 | expect(result).to be_a Telegram::Bot::Types::Message 105 | end 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /spec/lib/telegram/bot/exceptions/response_error_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Telegram::Bot::Exceptions::ResponseError, :vcr do 4 | subject(:error) do 5 | described_class.new(response) 6 | rescue StandardError => e 7 | e 8 | end 9 | 10 | let(:response) { Telegram::Bot::Api.new('123456:wrongtoken').call('getMe') } 11 | 12 | describe '#error_code' do 13 | subject { super().error_code } 14 | 15 | it { is_expected.to eq 401 } 16 | end 17 | 18 | describe '#to_s' do 19 | subject { super().to_s } 20 | 21 | let(:expected_result) do 22 | <<~STRING.chomp 23 | Telegram API has returned the error. (ok: false, error_code: 401, description: "Unauthorized") 24 | STRING 25 | end 26 | 27 | it { is_expected.to eq expected_result } 28 | end 29 | 30 | describe '#data' do 31 | subject { super().data } 32 | 33 | it { is_expected.to eq({ 'ok' => false, 'error_code' => 401, 'description' => 'Unauthorized' }) } 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/lib/telegram/bot/types_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'json' 4 | 5 | file = File.read("#{__dir__}/../../../../data/type_attributes.json") 6 | parsed_types = JSON.parse(file) 7 | 8 | RSpec.describe Telegram::Bot::Types do 9 | parsed_types.each do |class_name, attributes| 10 | describe class_name do 11 | subject(:klass) { described_class.const_get(class_name, false) } 12 | 13 | # empty classes exception 14 | next if described_class.const_get(class_name, false).instance_of?(Dry::Struct::Sum) 15 | 16 | it 'has correct attributes' do 17 | expect(klass.schema.keys.map(&:name)).to eq(attributes.keys.map(&:to_sym)) 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'dotenv/load' 4 | 5 | ENV['BOT_API_ENV'] ||= 'test' 6 | ENV['BOT_API_TOKEN'] ||= 'test_api_token' 7 | 8 | require 'vcr' 9 | 10 | VCR.configure do |config| 11 | config.cassette_library_dir = "#{__dir__}/cassettes" 12 | config.default_cassette_options = { record_on_error: false } 13 | config.hook_into :faraday 14 | config.configure_rspec_metadata! 15 | 16 | config.filter_sensitive_data('') do 17 | ENV.fetch('BOT_API_TOKEN') 18 | end 19 | end 20 | 21 | require_relative '../lib/telegram/bot' 22 | -------------------------------------------------------------------------------- /telegram-bot-ruby.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/telegram/bot/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'telegram-bot-ruby' 7 | spec.version = Telegram::Bot::VERSION 8 | spec.authors = ['Alexander Tipugin'] 9 | spec.email = ['atipugin@gmail.com'] 10 | 11 | spec.summary = "Ruby wrapper for Telegram's Bot API" 12 | spec.homepage = 'https://github.com/atipugin/telegram-bot' 13 | 14 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|data)/}) } 15 | spec.bindir = 'exe' 16 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 17 | spec.require_paths = ['lib'] 18 | 19 | spec.required_ruby_version = '>= 2.7' 20 | spec.metadata['rubygems_mfa_required'] = 'true' 21 | 22 | spec.add_dependency 'dry-struct', '~> 1.6' 23 | spec.add_dependency 'faraday', '~> 2.0' 24 | spec.add_dependency 'faraday-multipart', '~> 1.0' 25 | spec.add_dependency 'zeitwerk', '~> 2.6' 26 | end 27 | --------------------------------------------------------------------------------