diff --git a/Rakefile b/Rakefile index ae62e91..e56f475 100644 --- a/Rakefile +++ b/Rakefile @@ -15,130 +15,3 @@ end RSpec::Core::RakeTask.new(:spec) task default: :spec - -desc 'Dump type definitions from docs to YAML' -task :dump_type_attributes do - require_relative 'lib/telegram/bot' - require 'nokogiri' - require 'open-uri' - require 'yaml' - - # Preload every type we have - Zeitwerk::Loader.eager_load_all - types = Telegram::Bot::Types::Base.descendants.map { |c| c.name.split('::').last } - - # Fetch and parse docs - doc = Nokogiri::HTML(URI.open('https://core.telegram.org/bots/api').read) - - next_type_element_names = %w[table h4] - - result = types.to_h do |type| - # This is very hacky but working way to find table containing attributes for - # given type. Basic idea is to find heading with type and then iterate until - # we find table with attributes or next heading (because sometimes type - # doesn't have any attributes). - element = doc.at_xpath(%{//h4[text() = "#{type}"]}) - loop do - element = element.next_element - break if next_type_element_names.include?(element.name) - end - - attributes = element.xpath('.//tbody//tr').map do |el| - cells = el.children.select { |c| c.name == 'td' } - { - 'name' => cells[0].text, - 'type' => cells[1].text, - 'required' => !cells[2].text.start_with?('Optional.'), - 'required_value' => - cells[2].text.match(/^.+, (?:must be (?\w+)|always “(?\w+)”)$/)&.[](:found_type) - }.compact - end - - [type, attributes] - end - - # Write everything to fixture file - File.write "#{__dir__}/spec/support/type_attributes.yml", result.to_yaml -end - -DRY_TYPES = %w[string integer float decimal array hash symbol boolean date date_time time range].freeze -desc 'Rebuild types' -task :rebuild_types do - require 'json' - require 'erb' - - types = JSON.parse(File.read("#{__dir__}/spec/support/openapi_type_attributes.json"), symbolize_names: true) - - types.each_pair do |name, attributes| - template = ERB.new(File.read("#{__dir__}/spec/support/type.erb")) - - attributes.each_pair do |attr_name, properties| - attributes[attr_name][:type] = add_module_types(properties[:type]) unless properties[:type].is_a?(Array) - if properties[:type].is_a?(Array) - attributes[attr_name][:type] = properties[:type].map do |type| - add_module_types(type) - end.join(' | ') - end - attributes[attr_name][:type] += ".of(#{add_module_types(properties[:items])})" if properties[:items] - if properties[:default] - attributes[attr_name][:type] += ".default(#{typecast_default(properties[:type], - properties[:default])})" - end - attributes[attr_name][:type] = 'Types::True' if attributes[attr_name][:type] == 'Types::Boolean.default(true)' - attributes[attr_name][:type] = 'Types::Bool' if attributes[attr_name][:type] == 'Types::Boolean' - end - - File.write "#{__dir__}/lib/telegram/bot/types/#{underscore(name)}.rb", template.result(binding).gsub(" \n", '') - end -end - -desc 'Parse types from public json, should be up to date https://github.com/ark0f/tg-bot-api' -task :parse_type_attributes_from_opeanapi do - require 'openapi3_parser' - result = {} - document = Openapi3Parser.load_url('https://ark0f.github.io/tg-bot-api/openapi.json') - - document.components.schemas.each do |schema| - result_schema = {} - schema[1].properties.each do |property| - required_keys = schema[1].required.to_a || [] - - result_schema[property[0]] = { - type: property[1].type == 'object' ? property[1].name : property[1].type - } - - unless property[1].any_of.nil? - result_schema[property[0]][:type] = property[1].any_of.map do |item| - property[1].name || item.name || item.type - end.uniq - end - if result_schema[property[0]][:type]&.length == 1 - result_schema[property[0]][:type] = - result_schema[property[0]][:type].join - end - result_schema[property[0]][:required] = true if required_keys.include?(property[0]) - result_schema[property[0]][:items] = property[1].items.type if property[1]&.items - result_schema[property[0]][:items] = property[1].items.name if property[1]&.items&.type == 'object' - result_schema[property[0]][:default] = property[1].default if property[1].default - end - result[schema[0]] = result_schema - end - - File.write "#{__dir__}/spec/support/openapi_type_attributes.json", result.to_json -end - -def add_module_types(type) - DRY_TYPES.include?(type) ? "Types::#{type.capitalize}" : type -end - -def underscore(camel_cased_word) - camel_cased_word.to_s.gsub('::', '/') - .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') - .gsub(/([a-z\d])([A-Z])/, '\1_\2') - .tr('-', '_') - .downcase -end - -def typecast_default(type, obj) - type == 'Types::String' ? "'#{obj}'" : obj -end diff --git a/lib/telegram/bot/types/bot_command.rb b/lib/telegram/bot/types/bot_command.rb index c1c44a7..b44a8bc 100644 --- a/lib/telegram/bot/types/bot_command.rb +++ b/lib/telegram/bot/types/bot_command.rb @@ -4,8 +4,8 @@ module Telegram module Bot module Types class BotCommand < Base - attribute :command, Types::String - attribute :description, Types::String + attribute :command, Types::String.constrained(min_size: 1, max_size: 32) + attribute :description, Types::String.constrained(min_size: 1, max_size: 256) end end end diff --git a/lib/telegram/bot/types/chat_boost_source.rb b/lib/telegram/bot/types/chat_boost_source.rb index 097509d..defb41e 100644 --- a/lib/telegram/bot/types/chat_boost_source.rb +++ b/lib/telegram/bot/types/chat_boost_source.rb @@ -3,11 +3,14 @@ module Telegram module Bot module Types - ChatBoostSource = ( # rubocop:disable Naming/ConstantName + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + ChatBoostSource = ( ChatBoostSourcePremium | ChatBoostSourceGiftCode | ChatBoostSourceGiveaway ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/chat_full_info.rb b/lib/telegram/bot/types/chat_full_info.rb index fcea4ff..07d54b2 100644 --- a/lib/telegram/bot/types/chat_full_info.rb +++ b/lib/telegram/bot/types/chat_full_info.rb @@ -20,7 +20,7 @@ class ChatFullInfo < Base attribute? :business_location, BusinessLocation attribute? :business_opening_hours, BusinessOpeningHours attribute? :personal_chat, Chat - attribute? :available_reactions, Types::Array + attribute? :available_reactions, Types::Array.of(ReactionType) attribute? :background_custom_emoji_id, Types::String attribute? :profile_accent_color_id, Types::Integer attribute? :profile_background_custom_emoji_id, Types::String diff --git a/lib/telegram/bot/types/chat_location.rb b/lib/telegram/bot/types/chat_location.rb index bf9d14d..6e0fd50 100644 --- a/lib/telegram/bot/types/chat_location.rb +++ b/lib/telegram/bot/types/chat_location.rb @@ -5,7 +5,7 @@ module Bot module Types class ChatLocation < Base attribute :location, Location - attribute :address, Types::String + attribute :address, Types::String.constrained(min_size: 1, max_size: 64) end end end diff --git a/lib/telegram/bot/types/chat_member.rb b/lib/telegram/bot/types/chat_member.rb index 8e2344c..031241e 100644 --- a/lib/telegram/bot/types/chat_member.rb +++ b/lib/telegram/bot/types/chat_member.rb @@ -6,12 +6,12 @@ module Types ## Just for classes consistency # rubocop:disable Naming/ConstantName ChatMember = ( + ChatMemberOwner | ChatMemberAdministrator | - ChatMemberBanned | - ChatMemberLeft | ChatMemberMember | - ChatMemberOwner | - ChatMemberRestricted + ChatMemberRestricted | + ChatMemberLeft | + ChatMemberBanned ) # rubocop:enable Naming/ConstantName end diff --git a/lib/telegram/bot/types/force_reply.rb b/lib/telegram/bot/types/force_reply.rb index 42c3cb3..03fd758 100644 --- a/lib/telegram/bot/types/force_reply.rb +++ b/lib/telegram/bot/types/force_reply.rb @@ -5,7 +5,7 @@ module Bot module Types class ForceReply < Base attribute :force_reply, Types::True - attribute? :input_field_placeholder, Types::String + attribute? :input_field_placeholder, Types::String.constrained(min_size: 1, max_size: 64) attribute? :selective, Types::Bool end end diff --git a/lib/telegram/bot/types/inline_keyboard_button.rb b/lib/telegram/bot/types/inline_keyboard_button.rb index 1acdc15..f9e0d08 100644 --- a/lib/telegram/bot/types/inline_keyboard_button.rb +++ b/lib/telegram/bot/types/inline_keyboard_button.rb @@ -12,9 +12,9 @@ class InlineKeyboardButton < Base attribute? :switch_inline_query, Types::String attribute? :switch_inline_query_current_chat, Types::String attribute? :switch_inline_query_chosen_chat, SwitchInlineQueryChosenChat + attribute? :copy_text, CopyTextButton attribute? :callback_game, CallbackGame attribute? :pay, Types::Bool - attribute? :copy_text, CopyTextButton end end end diff --git a/lib/telegram/bot/types/inline_query_results_button.rb b/lib/telegram/bot/types/inline_query_results_button.rb index 3a1dc92..b27d47a 100644 --- a/lib/telegram/bot/types/inline_query_results_button.rb +++ b/lib/telegram/bot/types/inline_query_results_button.rb @@ -6,7 +6,7 @@ module Types class InlineQueryResultsButton < Base attribute :text, Types::String attribute? :web_app, WebAppInfo - attribute? :start_parameter, Types::String + attribute? :start_parameter, Types::String.constrained(min_size: 1, max_size: 64) end end end diff --git a/lib/telegram/bot/types/input_contact_message_content.rb b/lib/telegram/bot/types/input_contact_message_content.rb index 7e4a647..44fe038 100644 --- a/lib/telegram/bot/types/input_contact_message_content.rb +++ b/lib/telegram/bot/types/input_contact_message_content.rb @@ -3,7 +3,7 @@ module Telegram module Bot module Types - class InputContactMessageContent < InputMessageContent + class InputContactMessageContent < Base attribute :phone_number, Types::String attribute :first_name, Types::String attribute? :last_name, Types::String diff --git a/lib/telegram/bot/types/input_invoice_message_content.rb b/lib/telegram/bot/types/input_invoice_message_content.rb index 04f482b..35ccddc 100644 --- a/lib/telegram/bot/types/input_invoice_message_content.rb +++ b/lib/telegram/bot/types/input_invoice_message_content.rb @@ -3,9 +3,9 @@ module Telegram module Bot module Types - class InputInvoiceMessageContent < InputMessageContent - attribute :title, Types::String - attribute :description, Types::String + class InputInvoiceMessageContent < Base + attribute :title, Types::String.constrained(min_size: 1, max_size: 32) + attribute :description, Types::String.constrained(min_size: 1, max_size: 255) attribute :payload, Types::String attribute? :provider_token, Types::String attribute :currency, Types::String diff --git a/lib/telegram/bot/types/input_location_message_content.rb b/lib/telegram/bot/types/input_location_message_content.rb index 97da31a..653be3e 100644 --- a/lib/telegram/bot/types/input_location_message_content.rb +++ b/lib/telegram/bot/types/input_location_message_content.rb @@ -3,7 +3,7 @@ module Telegram module Bot module Types - class InputLocationMessageContent < InputMessageContent + class InputLocationMessageContent < Base attribute :latitude, Types::Float attribute :longitude, Types::Float attribute? :horizontal_accuracy, Types::Float diff --git a/lib/telegram/bot/types/input_message_content.rb b/lib/telegram/bot/types/input_message_content.rb index e53de3c..ad2f5de 100644 --- a/lib/telegram/bot/types/input_message_content.rb +++ b/lib/telegram/bot/types/input_message_content.rb @@ -3,8 +3,16 @@ module Telegram module Bot module Types - class InputMessageContent < Base - end + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + InputMessageContent = ( + InputTextMessageContent | + InputLocationMessageContent | + InputVenueMessageContent | + InputContactMessageContent | + InputInvoiceMessageContent + ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/input_poll_option.rb b/lib/telegram/bot/types/input_poll_option.rb index e1ce5e4..8418232 100644 --- a/lib/telegram/bot/types/input_poll_option.rb +++ b/lib/telegram/bot/types/input_poll_option.rb @@ -4,7 +4,7 @@ module Telegram module Bot module Types class InputPollOption < Base - attribute :text, Types::String + attribute :text, Types::String.constrained(min_size: 1, max_size: 100) attribute? :text_parse_mode, Types::String attribute? :text_entities, Types::Array.of(MessageEntity) end diff --git a/lib/telegram/bot/types/input_text_message_content.rb b/lib/telegram/bot/types/input_text_message_content.rb index 8c02dcf..6c6983d 100644 --- a/lib/telegram/bot/types/input_text_message_content.rb +++ b/lib/telegram/bot/types/input_text_message_content.rb @@ -3,8 +3,8 @@ module Telegram module Bot module Types - class InputTextMessageContent < InputMessageContent - attribute :message_text, Types::String + class InputTextMessageContent < Base + attribute :message_text, Types::String.constrained(min_size: 1, max_size: 4096) attribute? :parse_mode, Types::String attribute? :entities, Types::Array.of(MessageEntity) attribute? :link_preview_options, LinkPreviewOptions diff --git a/lib/telegram/bot/types/input_venue_message_content.rb b/lib/telegram/bot/types/input_venue_message_content.rb index 9cc9b2b..176855d 100644 --- a/lib/telegram/bot/types/input_venue_message_content.rb +++ b/lib/telegram/bot/types/input_venue_message_content.rb @@ -3,7 +3,7 @@ module Telegram module Bot module Types - class InputVenueMessageContent < InputMessageContent + class InputVenueMessageContent < Base attribute :latitude, Types::Float attribute :longitude, Types::Float attribute :title, Types::String diff --git a/lib/telegram/bot/types/maybe_inaccessible_message.rb b/lib/telegram/bot/types/maybe_inaccessible_message.rb index 3380b0d..0259702 100644 --- a/lib/telegram/bot/types/maybe_inaccessible_message.rb +++ b/lib/telegram/bot/types/maybe_inaccessible_message.rb @@ -3,10 +3,13 @@ module Telegram module Bot module Types - MaybeInaccessibleMessage = ( # rubocop:disable Naming/ConstantName + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + MaybeInaccessibleMessage = ( Message | InaccessibleMessage ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/message_origin.rb b/lib/telegram/bot/types/message_origin.rb index a3a8913..aaa4b01 100644 --- a/lib/telegram/bot/types/message_origin.rb +++ b/lib/telegram/bot/types/message_origin.rb @@ -3,12 +3,15 @@ module Telegram module Bot module Types - MessageOrigin = ( # rubocop:disable Naming/ConstantName + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + MessageOrigin = ( MessageOriginUser | MessageOriginHiddenUser | MessageOriginChat | MessageOriginChannel ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/paid_media.rb b/lib/telegram/bot/types/paid_media.rb index d31c5b5..eea7374 100644 --- a/lib/telegram/bot/types/paid_media.rb +++ b/lib/telegram/bot/types/paid_media.rb @@ -3,8 +3,14 @@ module Telegram module Bot module Types - class PaidMedia < Base - end + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + PaidMedia = ( + PaidMediaPreview | + PaidMediaPhoto | + PaidMediaVideo + ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/paid_media_info.rb b/lib/telegram/bot/types/paid_media_info.rb index b3ea617..3686187 100644 --- a/lib/telegram/bot/types/paid_media_info.rb +++ b/lib/telegram/bot/types/paid_media_info.rb @@ -5,7 +5,7 @@ module Bot module Types class PaidMediaInfo < Base attribute :star_count, Types::Integer - attribute :paid_media, Types::Array + attribute :paid_media, Types::Array.of(PaidMedia) end end end diff --git a/lib/telegram/bot/types/paid_media_photo.rb b/lib/telegram/bot/types/paid_media_photo.rb index dd18c5f..bf257c6 100644 --- a/lib/telegram/bot/types/paid_media_photo.rb +++ b/lib/telegram/bot/types/paid_media_photo.rb @@ -4,7 +4,7 @@ module Telegram module Bot module Types class PaidMediaPhoto < Base - attribute :type, Types::String.default('photo') + attribute :type, Types::String.constrained(eql: 'photo').default('photo') attribute :photo, Types::Array.of(PhotoSize) end end diff --git a/lib/telegram/bot/types/passport_element_error.rb b/lib/telegram/bot/types/passport_element_error.rb index d41b054..6820c0b 100644 --- a/lib/telegram/bot/types/passport_element_error.rb +++ b/lib/telegram/bot/types/passport_element_error.rb @@ -3,8 +3,20 @@ module Telegram module Bot module Types - class PassportElementError < Base - end + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + PassportElementError = ( + PassportElementErrorDataField | + PassportElementErrorFrontSide | + PassportElementErrorReverseSide | + PassportElementErrorSelfie | + PassportElementErrorFile | + PassportElementErrorFiles | + PassportElementErrorTranslationFile | + PassportElementErrorTranslationFiles | + PassportElementErrorUnspecified + ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/poll.rb b/lib/telegram/bot/types/poll.rb index 91cf0fb..53d563a 100644 --- a/lib/telegram/bot/types/poll.rb +++ b/lib/telegram/bot/types/poll.rb @@ -5,7 +5,7 @@ module Bot module Types class Poll < Base attribute :id, Types::String - attribute :question, Types::String + attribute :question, Types::String.constrained(min_size: 1, max_size: 300) attribute? :question_entities, Types::Array.of(MessageEntity) attribute :options, Types::Array.of(PollOption) attribute :total_voter_count, Types::Integer diff --git a/lib/telegram/bot/types/poll_option.rb b/lib/telegram/bot/types/poll_option.rb index afac6a2..d5eee79 100644 --- a/lib/telegram/bot/types/poll_option.rb +++ b/lib/telegram/bot/types/poll_option.rb @@ -4,7 +4,7 @@ module Telegram module Bot module Types class PollOption < Base - attribute :text, Types::String + attribute :text, Types::String.constrained(min_size: 1, max_size: 100) attribute? :text_entities, Types::Array.of(MessageEntity) attribute :voter_count, Types::Integer end diff --git a/lib/telegram/bot/types/reaction_type.rb b/lib/telegram/bot/types/reaction_type.rb index f823791..ed088f7 100644 --- a/lib/telegram/bot/types/reaction_type.rb +++ b/lib/telegram/bot/types/reaction_type.rb @@ -3,11 +3,14 @@ module Telegram module Bot module Types - ReactionType = ( # rubocop:disable Naming/ConstantName + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + ReactionType = ( ReactionTypeEmoji | ReactionTypeCustomEmoji | ReactionTypePaid ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/reply_keyboard_markup.rb b/lib/telegram/bot/types/reply_keyboard_markup.rb index b76c97a..afddecc 100644 --- a/lib/telegram/bot/types/reply_keyboard_markup.rb +++ b/lib/telegram/bot/types/reply_keyboard_markup.rb @@ -8,7 +8,7 @@ class ReplyKeyboardMarkup < Base attribute? :is_persistent, Types::Bool.default(false) attribute? :resize_keyboard, Types::Bool.default(false) attribute? :one_time_keyboard, Types::Bool.default(false) - attribute? :input_field_placeholder, Types::String + attribute? :input_field_placeholder, Types::String.constrained(min_size: 1, max_size: 64) attribute? :selective, Types::Bool def to_compact_hash diff --git a/lib/telegram/bot/types/revenue_withdrawal_state.rb b/lib/telegram/bot/types/revenue_withdrawal_state.rb index 4e403e4..9533814 100644 --- a/lib/telegram/bot/types/revenue_withdrawal_state.rb +++ b/lib/telegram/bot/types/revenue_withdrawal_state.rb @@ -3,8 +3,14 @@ module Telegram module Bot module Types - class RevenueWithdrawalState < Base - end + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + RevenueWithdrawalState = ( + RevenueWithdrawalStatePending | + RevenueWithdrawalStateSucceeded | + RevenueWithdrawalStateFailed + ) + # rubocop:enable Naming/ConstantName end end end diff --git a/lib/telegram/bot/types/transaction_partner_user.rb b/lib/telegram/bot/types/transaction_partner_user.rb index 0759ce3..5487f40 100644 --- a/lib/telegram/bot/types/transaction_partner_user.rb +++ b/lib/telegram/bot/types/transaction_partner_user.rb @@ -7,7 +7,7 @@ class TransactionPartnerUser < Base attribute :type, Types::String.constrained(eql: 'user').default('user') attribute :user, User attribute? :invoice_payload, Types::String - attribute? :paid_media, Types::Array + attribute? :paid_media, Types::Array.of(PaidMedia) attribute? :paid_media_payload, Types::String end end diff --git a/rakelib/parse_schema.rake b/rakelib/parse_schema.rake new file mode 100644 index 0000000..876c0bc --- /dev/null +++ b/rakelib/parse_schema.rake @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'openapi3_parser' +DRY_TYPES = %w[string integer float decimal array hash symbol boolean date date_time time range].freeze + +desc 'Parse types from public json, should be up to date https://github.com/ark0f/tg-bot-api' +task :parse_schema do + result = {} + document = Openapi3Parser.load_url('https://ark0f.github.io/tg-bot-api/openapi.json') + + document.components.schemas.each do |schema| + # Input File is literally just a string for our purpose + next if schema[0] == 'InputFile' + + result_schema = {} + + schema[1].properties.each do |property| + required_keys = schema[1].required.to_a || [] + property_name = property[0] + property_schema = property[1] + + attribute_type = + case property_schema.type + when nil then property_name.capitalize.gsub(/_(\w)/) { Regexp.last_match(1).upcase } + when 'object' then property_schema.name + else property_schema.type + end + + attribute = { + type: attribute_type + } + + unless property_schema.any_of.nil? + attribute[:type] = property_schema.any_of.map do |item| + property_schema.name || item.name || item.type + end.uniq + end + + # Input File is literally just a string for our purpose + attribute[:type]&.delete('InputFile') + attribute[:type] = attribute[:type].join if attribute[:type]&.length == 1 + + attribute[:required] = true if required_keys.include?(property_name) + + # getting required values from the description, no values in json 😔 + required_value = property_schema.description&.match(/always “(.+)”|must be \*(.+)\*/) + attribute[:required_value] = (required_value[1] || required_value[2]).delete('\\') if required_value + + # for some reason every property's minLength is 0 by default, probably parser bug, had to ignore that + attribute[:min_size] = property_schema[:minLength] if property_schema[:minLength] != 0 + attribute[:max_size] = property_schema[:maxLength] if property_schema[:maxLength] + + attribute[:items] = property_schema.items.type if property_schema&.items + if property_schema&.type == 'array' && property_schema&.items&.type.nil? + attribute[:items] = property_schema&.items&.name + end + + attribute[:items] = property_schema.items.name if property_schema&.items&.type == 'object' + + # array of arrays + if property_schema&.items&.type == 'array' + attribute[:items] = { + type: 'array', + items: property_schema&.items&.items&.name + } + end + + attribute[:default] = property_schema.default if property_schema.default + # previous line would have been enough, but had to check the description due to issue: https://github.com/kevindew/openapi3_parser/issues/28 + attribute[:default] = false if property_schema.description&.include?('Defaults to *false*') + result_schema[property_name] = attribute + end + + result[schema[0]] = result_schema + + # find empty classes + result[schema[0]][:type] = schema[1].any_of.map(&:name) if schema[1].properties.empty? && schema[1].any_of + end + + File.write "#{__dir__}/../utility/type_attributes.json", JSON.pretty_generate(result) +end + +def add_module_types(type) + return 'Types::Float' if type == 'number' + + DRY_TYPES.include?(type) ? "Types::#{type.capitalize}" : type +end + +def underscore(camel_cased_word) + camel_cased_word.to_s.gsub('::', '/') + .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + .gsub(/([a-z\d])([A-Z])/, '\1_\2') + .tr('-', '_') + .downcase +end + +def typecast_default(type, obj) + type == 'Types::String' ? "'#{obj}'" : obj +end diff --git a/rakelib/rebuild_types.rake b/rakelib/rebuild_types.rake new file mode 100644 index 0000000..977c817 --- /dev/null +++ b/rakelib/rebuild_types.rake @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'json' +require 'erb' + +desc 'Rebuild types' +task :rebuild_types do + types = JSON.parse(File.read("#{__dir__}/../utility/type_attributes.json"), symbolize_names: true) + + types.each_pair do |name, attributes| + attributes.delete(:inherited_from) + if attributes[:type].instance_of?(Array) + attributes = attributes[:type].join(" |\n ") + template = ERB.new(File.read("#{__dir__}/../utility/empty_type.erb")) + else + template = ERB.new(File.read("#{__dir__}/../utility/type.erb")) + attributes.each_pair do |attr_name, properties| + attributes[attr_name][:type] = add_module_types(properties[:type]) unless properties[:type].is_a?(Array) + if properties[:type].is_a?(Array) + attributes[attr_name][:type] = properties[:type].map do |type| + add_module_types(type) + end.join(' | ') + end + + if properties[:items].instance_of?(String) + attributes[attr_name][:type] += ".of(#{add_module_types(properties[:items])})" + elsif properties[:items] && properties[:items][:type] == 'array' + attributes[attr_name][:type] += ".of(Types::Array.of(#{properties[:items][:items]}))" + end + original_type = properties[:type] + if properties[:required_value] + attributes[attr_name][:type] += ".constrained(eql: #{typecast_default(original_type, + properties[:required_value])})" + end + if properties[:min_size] || properties[:max_size] + constrain = '.constrained(minmax)' + constrain = properties[:min_size] ? constrain.gsub('min', "min_size: #{properties[:min_size]}, ") : '' + constrain = constrain.gsub('max', "max_size: #{properties[:max_size]}") if properties[:max_size] + attributes[attr_name][:type] += constrain + end + unless properties[:default].nil? + attributes[attr_name][:type] += ".default(#{typecast_default(original_type, + properties[:default])})" + end + attributes[attr_name][:type] = 'Types::True' if attributes[attr_name][:type] == 'Types::Boolean.default(true)' + attributes[attr_name][:type] = attributes[attr_name][:type].gsub('Types::Boolean', 'Types::Bool') + end + end + + File.write "#{__dir__}/../lib/telegram/bot/types/#{underscore(name)}.rb", + template.result(binding).gsub(" \n", '') + end +end diff --git a/spec/lib/telegram/bot/types_spec.rb b/spec/lib/telegram/bot/types_spec.rb index 7200429..0b1d500 100644 --- a/spec/lib/telegram/bot/types_spec.rb +++ b/spec/lib/telegram/bot/types_spec.rb @@ -1,84 +1,20 @@ # frozen_string_literal: true -require 'yaml' +require 'json' -type_attributes = YAML.safe_load File.read("#{__dir__}/../../../support/type_attributes.yml") +file = File.read("#{__dir__}/../../../../utility/type_attributes.json") +parsed_types = JSON.parse(file) RSpec.describe Telegram::Bot::Types do - type_attributes.each do |parsed_type, parsed_attributes| - describe parsed_type do - subject(:klass) { described_class.const_get(parsed_type, false) } + parsed_types.each do |class_name, attributes| + describe class_name do + subject(:klass) { described_class.const_get(class_name, false) } - it 'has correct attributes' do - expect(klass.schema.keys.map(&:name)).to eq(parsed_attributes.map { |e| e['name'].to_sym }) - end - - parsed_attributes.each do |parsed_attribute| - describe "##{parsed_attribute['name']}" do - subject(:klass_attribute) { klass.schema.name_key_map[parsed_attribute['name'].to_sym] } - - describe 'type' do - subject do - klass_attribute_type = klass_attribute&.type - - ## We need to get rid of `default` values - ## https://discourse.dry-rb.org/t/how-to-remove-a-default-from-dry-types-custom-class-attribute/1727 - klass_attribute_type = klass_attribute_type.type if klass_attribute_type.default? - - klass_attribute_type - end - - def parse_string_type(type_string) - if (match_data = type_string.match(/^Array of (?.+)$/)) - ## Call a recursion for `Array of Array of Something` - return described_class::Array.of(send(__method__, match_data[:inner_type])) - end - - ## We have no examples of `or` with 3 or more types - if (match_data = type_string.match(/^(\w+) or (\w+)$/)) - ## `uniq` for `InputFile`, for example - return match_data[1..].map { |matched_type| send(__method__, matched_type) }.uniq.reduce(:|) - end - - type_string = - case type_string - ## `dry-types` has no `Boolean` type (or alias) - when 'Boolean' then 'Bool' - when 'Float number' then 'Float' - ## It's a `file_id`, URL or `multipart/form-data`: - ## https://core.telegram.org/bots/api#inputfile - when 'InputFile' then 'String' - ## I'm not sure about this. It's like "True is optional to send" and "We can response with False" - # when 'True' && !parsed_attribute['required'] then 'Boolean' - else type_string - end + # empty classes exception + next if described_class.const_get(class_name, false).instance_of?(Dry::Struct::Sum) - # binding.irb if type_string == 'Bool' - - ## Without `false` for `const_get` because base types inhereted from the `dry-types` - described_class.const_get(type_string) - end - - let(:expected_type) do - result = parse_string_type(parsed_attribute['type']) - - ## Sometimes there are required values for attributes, like `BotCommandScope` or `MenuButton` - if (required_value = parsed_attribute['required_value']) - result = result.constrained(eql: required_value) - end - - result - end - - it { is_expected.to eq expected_type } - end - - describe 'optionality' do - subject { klass_attribute&.required? } - - it { is_expected.to eq parsed_attribute['required'] } - end - end + it 'has correct attributes' do + expect(klass.schema.keys.map(&:name)).to eq(attributes.keys.map(&:to_sym)) end end end diff --git a/spec/support/type_attributes.yml b/spec/support/type_attributes.yml deleted file mode 100644 index 7780c88..0000000 --- a/spec/support/type_attributes.yml +++ /dev/null @@ -1,3357 +0,0 @@ ---- -ShippingOption: -- name: id - type: String - required: true -- name: title - type: String - required: true -- name: prices - type: Array of LabeledPrice - required: true -ReplyParameters: -- name: message_id - type: Integer - required: true -- name: chat_id - type: Integer or String - required: false -- name: allow_sending_without_reply - type: Boolean - required: false -- name: quote - type: String - required: false -- name: quote_parse_mode - type: String - required: false -- name: quote_entities - type: Array of MessageEntity - required: false -- name: quote_position - type: Integer - required: false -ReplyKeyboardRemove: -- name: remove_keyboard - type: 'True' - required: true -- name: selective - type: Boolean - required: false -ReplyKeyboardMarkup: -- name: keyboard - type: Array of Array of KeyboardButton - required: true -- name: is_persistent - type: Boolean - required: false -- name: resize_keyboard - type: Boolean - required: false -- name: one_time_keyboard - type: Boolean - required: false -- name: input_field_placeholder - type: String - required: false -- name: selective - type: Boolean - required: false -PassportElementErrorUnspecified: -- name: source - type: String - required: true - required_value: unspecified -- name: type - type: String - required: true -- name: element_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorTranslationFiles: -- name: source - type: String - required: true - required_value: translation_files -- name: type - type: String - required: true -- name: file_hashes - type: Array of String - required: true -- name: message - type: String - required: true -PassportElementErrorTranslationFile: -- name: source - type: String - required: true - required_value: translation_file -- name: type - type: String - required: true -- name: file_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorSelfie: -- name: source - type: String - required: true - required_value: selfie -- name: type - type: String - required: true -- name: file_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorReverseSide: -- name: source - type: String - required: true - required_value: reverse_side -- name: type - type: String - required: true -- name: file_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorFrontSide: -- name: source - type: String - required: true - required_value: front_side -- name: type - type: String - required: true -- name: file_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorFiles: -- name: source - type: String - required: true - required_value: files -- name: type - type: String - required: true -- name: file_hashes - type: Array of String - required: true -- name: message - type: String - required: true -PassportElementErrorFile: -- name: source - type: String - required: true - required_value: file -- name: type - type: String - required: true -- name: file_hash - type: String - required: true -- name: message - type: String - required: true -PassportElementErrorDataField: -- name: source - type: String - required: true - required_value: data -- name: type - type: String - required: true -- name: field_name - type: String - required: true -- name: data_hash - type: String - required: true -- name: message - type: String - required: true -KeyboardButtonPollType: -- name: type - type: String - required: false -KeyboardButtonRequestChat: -- name: request_id - type: Integer - required: true -- name: chat_is_channel - type: Boolean - required: true -- name: chat_is_forum - type: Boolean - required: false -- name: chat_has_username - type: Boolean - required: false -- name: chat_is_created - type: Boolean - required: false -- name: user_administrator_rights - type: ChatAdministratorRights - required: false -- name: bot_administrator_rights - type: ChatAdministratorRights - required: false -- name: bot_is_member - type: Boolean - required: false -- name: request_title - type: Boolean - required: false -- name: request_username - type: Boolean - required: false -- name: request_photo - type: Boolean - required: false -KeyboardButtonRequestUsers: -- name: request_id - type: Integer - required: true -- name: user_is_bot - type: Boolean - required: false -- name: user_is_premium - type: Boolean - required: false -- name: max_quantity - type: Integer - required: false -- name: request_name - type: Boolean - required: false -- name: request_username - type: Boolean - required: false -- name: request_photo - type: Boolean - required: false -KeyboardButton: -- name: text - type: String - required: true -- name: request_users - type: KeyboardButtonRequestUsers - required: false -- name: request_chat - type: KeyboardButtonRequestChat - required: false -- name: request_contact - type: Boolean - required: false -- name: request_location - type: Boolean - required: false -- name: request_poll - type: KeyboardButtonPollType - required: false -- name: web_app - type: WebAppInfo - required: false -InputVenueMessageContent: -- name: latitude - type: Float - required: true -- name: longitude - type: Float - required: true -- name: title - type: String - required: true -- name: address - type: String - required: true -- name: foursquare_id - type: String - required: false -- name: foursquare_type - type: String - required: false -- name: google_place_id - type: String - required: false -- name: google_place_type - type: String - required: false -InputTextMessageContent: -- name: message_text - type: String - required: true -- name: parse_mode - type: String - required: false -- name: entities - type: Array of MessageEntity - required: false -- name: link_preview_options - type: LinkPreviewOptions - required: false -InputMediaVideo: -- name: type - type: String - required: true - required_value: video -- name: media - type: String - required: true -- name: thumbnail - type: InputFile or String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: width - type: Integer - required: false -- name: height - type: Integer - required: false -- name: duration - type: Integer - required: false -- name: supports_streaming - type: Boolean - required: false -- name: has_spoiler - type: Boolean - required: false -InputMediaPhoto: -- name: type - type: String - required: true - required_value: photo -- name: media - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: has_spoiler - type: Boolean - required: false -InputMediaDocument: -- name: type - type: String - required: true - required_value: document -- name: media - type: String - required: true -- name: thumbnail - type: InputFile or String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: disable_content_type_detection - type: Boolean - required: false -InputMediaAudio: -- name: type - type: String - required: true - required_value: audio -- name: media - type: String - required: true -- name: thumbnail - type: InputFile or String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: duration - type: Integer - required: false -- name: performer - type: String - required: false -- name: title - type: String - required: false -InputMediaAnimation: -- name: type - type: String - required: true - required_value: animation -- name: media - type: String - required: true -- name: thumbnail - type: InputFile or String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: width - type: Integer - required: false -- name: height - type: Integer - required: false -- name: duration - type: Integer - required: false -- name: has_spoiler - type: Boolean - required: false -InputLocationMessageContent: -- name: latitude - type: Float - required: true -- name: longitude - type: Float - required: true -- name: horizontal_accuracy - type: Float - required: false -- name: live_period - type: Integer - required: false -- name: heading - type: Integer - required: false -- name: proximity_alert_radius - type: Integer - required: false -LabeledPrice: -- name: label - type: String - required: true -- name: amount - type: Integer - required: true -InputInvoiceMessageContent: -- name: title - type: String - required: true -- name: description - type: String - required: true -- name: payload - type: String - required: true -- name: provider_token - type: String - required: false -- name: currency - type: String - required: true -- name: prices - type: Array of LabeledPrice - required: true -- name: max_tip_amount - type: Integer - required: false -- name: suggested_tip_amounts - type: Array of Integer - required: false -- name: provider_data - type: String - required: false -- name: photo_url - type: String - required: false -- name: photo_size - type: Integer - required: false -- name: photo_width - type: Integer - required: false -- name: photo_height - type: Integer - required: false -- name: need_name - type: Boolean - required: false -- name: need_phone_number - type: Boolean - required: false -- name: need_email - type: Boolean - required: false -- name: need_shipping_address - type: Boolean - required: false -- name: send_phone_number_to_provider - type: Boolean - required: false -- name: send_email_to_provider - type: Boolean - required: false -- name: is_flexible - type: Boolean - required: false -InputContactMessageContent: -- name: phone_number - type: String - required: true -- name: first_name - type: String - required: true -- name: last_name - type: String - required: false -- name: vcard - type: String - required: false -InlineQueryResultVoice: -- name: type - type: String - required: true - required_value: voice -- name: id - type: String - required: true -- name: voice_url - type: String - required: true -- name: title - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: voice_duration - type: Integer - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultVideo: -- name: type - type: String - required: true - required_value: video -- name: id - type: String - required: true -- name: video_url - type: String - required: true -- name: mime_type - type: String - required: true -- name: thumbnail_url - type: String - required: true -- name: title - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: video_width - type: Integer - required: false -- name: video_height - type: Integer - required: false -- name: video_duration - type: Integer - required: false -- name: description - type: String - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultVenue: -- name: type - type: String - required: true - required_value: venue -- name: id - type: String - required: true -- name: latitude - type: Float - required: true -- name: longitude - type: Float - required: true -- name: title - type: String - required: true -- name: address - type: String - required: true -- name: foursquare_id - type: String - required: false -- name: foursquare_type - type: String - required: false -- name: google_place_id - type: String - required: false -- name: google_place_type - type: String - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -- name: thumbnail_url - type: String - required: false -- name: thumbnail_width - type: Integer - required: false -- name: thumbnail_height - type: Integer - required: false -InlineQueryResultPhoto: -- name: type - type: String - required: true - required_value: photo -- name: id - type: String - required: true -- name: photo_url - type: String - required: true -- name: thumbnail_url - type: String - required: true -- name: photo_width - type: Integer - required: false -- name: photo_height - type: Integer - required: false -- name: title - type: String - required: false -- name: description - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultMpeg4Gif: -- name: type - type: String - required: true - required_value: mpeg4_gif -- name: id - type: String - required: true -- name: mpeg4_url - type: String - required: true -- name: mpeg4_width - type: Integer - required: false -- name: mpeg4_height - type: Integer - required: false -- name: mpeg4_duration - type: Integer - required: false -- name: thumbnail_url - type: String - required: true -- name: thumbnail_mime_type - type: String - required: false -- name: title - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultLocation: -- name: type - type: String - required: true - required_value: location -- name: id - type: String - required: true -- name: latitude - type: Float - required: true -- name: longitude - type: Float - required: true -- name: title - type: String - required: true -- name: horizontal_accuracy - type: Float - required: false -- name: live_period - type: Integer - required: false -- name: heading - type: Integer - required: false -- name: proximity_alert_radius - type: Integer - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -- name: thumbnail_url - type: String - required: false -- name: thumbnail_width - type: Integer - required: false -- name: thumbnail_height - type: Integer - required: false -InlineQueryResultGif: -- name: type - type: String - required: true - required_value: gif -- name: id - type: String - required: true -- name: gif_url - type: String - required: true -- name: gif_width - type: Integer - required: false -- name: gif_height - type: Integer - required: false -- name: gif_duration - type: Integer - required: false -- name: thumbnail_url - type: String - required: true -- name: thumbnail_mime_type - type: String - required: false -- name: title - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultGame: -- name: type - type: String - required: true - required_value: game -- name: id - type: String - required: true -- name: game_short_name - type: String - required: true -- name: reply_markup - type: InlineKeyboardMarkup - required: false -InlineQueryResultDocument: -- name: type - type: String - required: true - required_value: document -- name: id - type: String - required: true -- name: title - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: document_url - type: String - required: true -- name: mime_type - type: String - required: true -- name: description - type: String - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -- name: thumbnail_url - type: String - required: false -- name: thumbnail_width - type: Integer - required: false -- name: thumbnail_height - type: Integer - required: false -InlineQueryResultContact: -- name: type - type: String - required: true - required_value: contact -- name: id - type: String - required: true -- name: phone_number - type: String - required: true -- name: first_name - type: String - required: true -- name: last_name - type: String - required: false -- name: vcard - type: String - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -- name: thumbnail_url - type: String - required: false -- name: thumbnail_width - type: Integer - required: false -- name: thumbnail_height - type: Integer - required: false -InlineQueryResultCachedVoice: -- name: type - type: String - required: true - required_value: voice -- name: id - type: String - required: true -- name: voice_file_id - type: String - required: true -- name: title - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedVideo: -- name: type - type: String - required: true - required_value: video -- name: id - type: String - required: true -- name: video_file_id - type: String - required: true -- name: title - type: String - required: true -- name: description - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedSticker: -- name: type - type: String - required: true - required_value: sticker -- name: id - type: String - required: true -- name: sticker_file_id - type: String - required: true -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedPhoto: -- name: type - type: String - required: true - required_value: photo -- name: id - type: String - required: true -- name: photo_file_id - type: String - required: true -- name: title - type: String - required: false -- name: description - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedMpeg4Gif: -- name: type - type: String - required: true - required_value: mpeg4_gif -- name: id - type: String - required: true -- name: mpeg4_file_id - type: String - required: true -- name: title - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedGif: -- name: type - type: String - required: true - required_value: gif -- name: id - type: String - required: true -- name: gif_file_id - type: String - required: true -- name: title - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: Boolean - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedDocument: -- name: type - type: String - required: true - required_value: document -- name: id - type: String - required: true -- name: title - type: String - required: true -- name: document_file_id - type: String - required: true -- name: description - type: String - required: false -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultCachedAudio: -- name: type - type: String - required: true - required_value: audio -- name: id - type: String - required: true -- name: audio_file_id - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InlineQueryResultAudio: -- name: type - type: String - required: true - required_value: audio -- name: id - type: String - required: true -- name: audio_url - type: String - required: true -- name: title - type: String - required: true -- name: caption - type: String - required: false -- name: parse_mode - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: performer - type: String - required: false -- name: audio_duration - type: Integer - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: input_message_content - type: InputMessageContent - required: false -InputMessageContent: [] -InlineQueryResultArticle: -- name: type - type: String - required: true - required_value: article -- name: id - type: String - required: true -- name: title - type: String - required: true -- name: input_message_content - type: InputMessageContent - required: true -- name: reply_markup - type: InlineKeyboardMarkup - required: false -- name: url - type: String - required: false -- name: hide_url - type: Boolean - required: false -- name: description - type: String - required: false -- name: thumbnail_url - type: String - required: false -- name: thumbnail_width - type: Integer - required: false -- name: thumbnail_height - type: Integer - required: false -ForumTopic: -- name: message_thread_id - type: Integer - required: true -- name: name - type: String - required: true -- name: icon_color - type: Integer - required: true -- name: icon_custom_emoji_id - type: String - required: false -ForceReply: -- name: force_reply - type: 'True' - required: true -- name: input_field_placeholder - type: String - required: false -- name: selective - type: Boolean - required: false -BotCommandScopeDefault: -- name: type - type: String - required: true - required_value: default -BotCommandScopeChatMember: -- name: type - type: String - required: true - required_value: chat_member -- name: chat_id - type: Integer or String - required: true -- name: user_id - type: Integer - required: true -BotCommandScopeChatAdministrators: -- name: type - type: String - required: true - required_value: chat_administrators -- name: chat_id - type: Integer or String - required: true -BotCommandScopeChat: -- name: type - type: String - required: true - required_value: chat -- name: chat_id - type: Integer or String - required: true -BotCommandScopeAllPrivateChats: -- name: type - type: String - required: true - required_value: all_private_chats -BotCommandScopeAllGroupChats: -- name: type - type: String - required: true - required_value: all_group_chats -BotCommandScopeAllChatAdministrators: -- name: type - type: String - required: true - required_value: all_chat_administrators -BotShortDescription: -- name: short_description - type: String - required: true -BotDescription: -- name: description - type: String - required: true -BotName: -- name: name - type: String - required: true -ChatAdministratorRights: -- name: is_anonymous - type: Boolean - required: true -- name: can_manage_chat - type: Boolean - required: true -- name: can_delete_messages - type: Boolean - required: true -- name: can_manage_video_chats - type: Boolean - required: true -- name: can_restrict_members - type: Boolean - required: true -- name: can_promote_members - type: Boolean - required: true -- name: can_change_info - type: Boolean - required: true -- name: can_invite_users - type: Boolean - required: true -- name: can_post_stories - type: Boolean - required: true -- name: can_edit_stories - type: Boolean - required: true -- name: can_delete_stories - type: Boolean - required: true -- name: can_post_messages - type: Boolean - required: false -- name: can_edit_messages - type: Boolean - required: false -- name: can_pin_messages - type: Boolean - required: false -- name: can_manage_topics - type: Boolean - required: false -MenuButtonWebApp: -- name: type - type: String - required: true - required_value: web_app -- name: text - type: String - required: true -- name: web_app - type: WebAppInfo - required: true -MenuButtonCommands: -- name: type - type: String - required: true - required_value: commands -MenuButtonDefault: -- name: type - type: String - required: true - required_value: default -SentWebAppMessage: -- name: inline_message_id - type: String - required: false -BotCommand: -- name: command - type: String - required: true -- name: description - type: String - required: true -GameHighScore: -- name: position - type: Integer - required: true -- name: user - type: User - required: true -- name: score - type: Integer - required: true -StickerSet: -- name: name - type: String - required: true -- name: title - type: String - required: true -- name: sticker_type - type: String - required: true -- name: stickers - type: Array of Sticker - required: true -- name: thumbnail - type: PhotoSize - required: false -UserChatBoosts: -- name: boosts - type: Array of ChatBoost - required: true -UserProfilePhotos: -- name: total_count - type: Integer - required: true -- name: photos - type: Array of Array of PhotoSize - required: true -MessageId: -- name: message_id - type: Integer - required: true -WebhookInfo: -- name: url - type: String - required: true -- name: has_custom_certificate - type: Boolean - required: true -- name: pending_update_count - type: Integer - required: true -- name: ip_address - type: String - required: false -- name: last_error_date - type: Integer - required: false -- name: last_error_message - type: String - required: false -- name: last_synchronization_error_date - type: Integer - required: false -- name: max_connections - type: Integer - required: false -- name: allowed_updates - type: Array of String - required: false -ChatBoostRemoved: -- name: chat - type: Chat - required: true -- name: boost_id - type: String - required: true -- name: remove_date - type: Integer - required: true -- name: source - type: ChatBoostSource - required: true -ChatBoostSourceGiveaway: -- name: source - type: String - required: true - required_value: giveaway -- name: giveaway_message_id - type: Integer - required: true -- name: user - type: User - required: false -- name: prize_star_count - type: Integer - required: false -- name: is_unclaimed - type: 'True' - required: false -ChatBoostSourceGiftCode: -- name: source - type: String - required: true - required_value: gift_code -- name: user - type: User - required: true -ChatBoostSourcePremium: -- name: source - type: String - required: true - required_value: premium -- name: user - type: User - required: true -ChatBoost: -- name: boost_id - type: String - required: true -- name: add_date - type: Integer - required: true -- name: expiration_date - type: Integer - required: true -- name: source - type: ChatBoostSource - required: true -ChatBoostUpdated: -- name: chat - type: Chat - required: true -- name: boost - type: ChatBoost - required: true -ChatJoinRequest: -- name: chat - type: Chat - required: true -- name: from - type: User - required: true -- name: user_chat_id - type: Integer - required: true -- name: date - type: Integer - required: true -- name: bio - type: String - required: false -- name: invite_link - type: ChatInviteLink - required: false -ChatInviteLink: -- name: invite_link - type: String - required: true -- name: creator - type: User - required: true -- name: creates_join_request - type: Boolean - required: true -- name: is_primary - type: Boolean - required: true -- name: is_revoked - type: Boolean - required: true -- name: name - type: String - required: false -- name: expire_date - type: Integer - required: false -- name: member_limit - type: Integer - required: false -- name: pending_join_request_count - type: Integer - required: false -- name: subscription_period - type: Integer - required: false -- name: subscription_price - type: Integer - required: false -ChatMemberRestricted: -- name: status - type: String - required: true - required_value: restricted -- name: user - type: User - required: true -- name: is_member - type: Boolean - required: true -- name: can_send_messages - type: Boolean - required: true -- name: can_send_audios - type: Boolean - required: true -- name: can_send_documents - type: Boolean - required: true -- name: can_send_photos - type: Boolean - required: true -- name: can_send_videos - type: Boolean - required: true -- name: can_send_video_notes - type: Boolean - required: true -- name: can_send_voice_notes - type: Boolean - required: true -- name: can_send_polls - type: Boolean - required: true -- name: can_send_other_messages - type: Boolean - required: true -- name: can_add_web_page_previews - type: Boolean - required: true -- name: can_change_info - type: Boolean - required: true -- name: can_invite_users - type: Boolean - required: true -- name: can_pin_messages - type: Boolean - required: true -- name: can_manage_topics - type: Boolean - required: true -- name: until_date - type: Integer - required: true -ChatMemberOwner: -- name: status - type: String - required: true - required_value: creator -- name: user - type: User - required: true -- name: is_anonymous - type: Boolean - required: true -- name: custom_title - type: String - required: false -ChatMemberMember: -- name: status - type: String - required: true - required_value: member -- name: user - type: User - required: true -- name: until_date - type: Integer - required: false -ChatMemberLeft: -- name: status - type: String - required: true - required_value: left -- name: user - type: User - required: true -ChatMemberBanned: -- name: status - type: String - required: true - required_value: kicked -- name: user - type: User - required: true -- name: until_date - type: Integer - required: true -ChatMemberAdministrator: -- name: status - type: String - required: true - required_value: administrator -- name: user - type: User - required: true -- name: can_be_edited - type: Boolean - required: true -- name: is_anonymous - type: Boolean - required: true -- name: can_manage_chat - type: Boolean - required: true -- name: can_delete_messages - type: Boolean - required: true -- name: can_manage_video_chats - type: Boolean - required: true -- name: can_restrict_members - type: Boolean - required: true -- name: can_promote_members - type: Boolean - required: true -- name: can_change_info - type: Boolean - required: true -- name: can_invite_users - type: Boolean - required: true -- name: can_post_stories - type: Boolean - required: true -- name: can_edit_stories - type: Boolean - required: true -- name: can_delete_stories - type: Boolean - required: true -- name: can_post_messages - type: Boolean - required: false -- name: can_edit_messages - type: Boolean - required: false -- name: can_pin_messages - type: Boolean - required: false -- name: can_manage_topics - type: Boolean - required: false -- name: custom_title - type: String - required: false -ChatMemberUpdated: -- name: chat - type: Chat - required: true -- name: from - type: User - required: true -- name: date - type: Integer - required: true -- name: old_chat_member - type: ChatMember - required: true -- name: new_chat_member - type: ChatMember - required: true -- name: invite_link - type: ChatInviteLink - required: false -- name: via_join_request - type: Boolean - required: false -- name: via_chat_folder_invite_link - type: Boolean - required: false -PollAnswer: -- name: poll_id - type: String - required: true -- name: voter_chat - type: Chat - required: false -- name: user - type: User - required: false -- name: option_ids - type: Array of Integer - required: true -PreCheckoutQuery: -- name: id - type: String - required: true -- name: from - type: User - required: true -- name: currency - type: String - required: true -- name: total_amount - type: Integer - required: true -- name: invoice_payload - type: String - required: true -- name: shipping_option_id - type: String - required: false -- name: order_info - type: OrderInfo - required: false -ShippingQuery: -- name: id - type: String - required: true -- name: from - type: User - required: true -- name: invoice_payload - type: String - required: true -- name: shipping_address - type: ShippingAddress - required: true -CallbackQuery: -- name: id - type: String - required: true -- name: from - type: User - required: true -- name: message - type: MaybeInaccessibleMessage - required: false -- name: inline_message_id - type: String - required: false -- name: chat_instance - type: String - required: true -- name: data - type: String - required: false -- name: game_short_name - type: String - required: false -ChosenInlineResult: -- name: result_id - type: String - required: true -- name: from - type: User - required: true -- name: location - type: Location - required: false -- name: inline_message_id - type: String - required: false -- name: query - type: String - required: true -InlineQuery: -- name: id - type: String - required: true -- name: from - type: User - required: true -- name: query - type: String - required: true -- name: offset - type: String - required: true -- name: chat_type - type: String - required: false -- name: location - type: Location - required: false -ReactionCount: -- name: type - type: ReactionType - required: true -- name: total_count - type: Integer - required: true -MessageReactionCountUpdated: -- name: chat - type: Chat - required: true -- name: message_id - type: Integer - required: true -- name: date - type: Integer - required: true -- name: reactions - type: Array of ReactionCount - required: true -MessageReactionUpdated: -- name: chat - type: Chat - required: true -- name: message_id - type: Integer - required: true -- name: user - type: User - required: false -- name: actor_chat - type: Chat - required: false -- name: date - type: Integer - required: true -- name: old_reaction - type: Array of ReactionType - required: true -- name: new_reaction - type: Array of ReactionType - required: true -CallbackGame: [] -SwitchInlineQueryChosenChat: -- name: query - type: String - required: false -- name: allow_user_chats - type: Boolean - required: false -- name: allow_bot_chats - type: Boolean - required: false -- name: allow_group_chats - type: Boolean - required: false -- name: allow_channel_chats - type: Boolean - required: false -LoginUrl: -- name: url - type: String - required: true -- name: forward_text - type: String - required: false -- name: bot_username - type: String - required: false -- name: request_write_access - type: Boolean - required: false -WebAppInfo: -- name: url - type: String - required: true -InlineKeyboardButton: -- name: text - type: String - required: true -- name: url - type: String - required: false -- name: callback_data - type: String - required: false -- name: web_app - type: WebAppInfo - required: false -- name: login_url - type: LoginUrl - required: false -- name: switch_inline_query - type: String - required: false -- name: switch_inline_query_current_chat - type: String - required: false -- name: switch_inline_query_chosen_chat - type: SwitchInlineQueryChosenChat - required: false -- name: callback_game - type: CallbackGame - required: false -- name: pay - type: Boolean - required: false -- name: copy_text - type: CopyTextButton - required: false -InlineKeyboardMarkup: -- name: inline_keyboard - type: Array of Array of InlineKeyboardButton - required: true -WebAppData: -- name: data - type: String - required: true -- name: button_text - type: String - required: true -VideoChatParticipantsInvited: -- name: users - type: Array of User - required: true -VideoChatEnded: -- name: duration - type: Integer - required: true -VideoChatStarted: [] -VideoChatScheduled: -- name: start_date - type: Integer - required: true -GiveawayCompleted: -- name: winner_count - type: Integer - required: true -- name: unclaimed_prize_count - type: Integer - required: false -- name: giveaway_message - type: Message - required: false -- name: is_star_giveaway - type: 'True' - required: false -GiveawayCreated: -- name: prize_star_count - type: Integer - required: false -GeneralForumTopicUnhidden: [] -GeneralForumTopicHidden: [] -ForumTopicReopened: [] -ForumTopicClosed: [] -ForumTopicEdited: -- name: name - type: String - required: false -- name: icon_custom_emoji_id - type: String - required: false -ForumTopicCreated: -- name: name - type: String - required: true -- name: icon_color - type: Integer - required: true -- name: icon_custom_emoji_id - type: String - required: false -ProximityAlertTriggered: -- name: traveler - type: User - required: true -- name: watcher - type: User - required: true -- name: distance - type: Integer - required: true -EncryptedCredentials: -- name: data - type: String - required: true -- name: hash - type: String - required: true -- name: secret - type: String - required: true -PassportFile: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: file_size - type: Integer - required: true -- name: file_date - type: Integer - required: true -EncryptedPassportElement: -- name: type - type: String - required: true -- name: data - type: String - required: false -- name: phone_number - type: String - required: false -- name: email - type: String - required: false -- name: files - type: Array of PassportFile - required: false -- name: front_side - type: PassportFile - required: false -- name: reverse_side - type: PassportFile - required: false -- name: selfie - type: PassportFile - required: false -- name: translation - type: Array of PassportFile - required: false -- name: hash - type: String - required: true -PassportData: -- name: data - type: Array of EncryptedPassportElement - required: true -- name: credentials - type: EncryptedCredentials - required: true -WriteAccessAllowed: -- name: from_request - type: Boolean - required: false -- name: web_app_name - type: String - required: false -- name: from_attachment_menu - type: Boolean - required: false -ChatShared: -- name: request_id - type: Integer - required: true -- name: chat_id - type: Integer - required: true -- name: title - type: String - required: false -- name: username - type: String - required: false -- name: photo - type: Array of PhotoSize - required: false -UsersShared: -- name: request_id - type: Integer - required: true -- name: users - type: Array of SharedUser - required: true -ShippingAddress: -- name: country_code - type: String - required: true -- name: state - type: String - required: true -- name: city - type: String - required: true -- name: street_line1 - type: String - required: true -- name: street_line2 - type: String - required: true -- name: post_code - type: String - required: true -OrderInfo: -- name: name - type: String - required: false -- name: phone_number - type: String - required: false -- name: email - type: String - required: false -- name: shipping_address - type: ShippingAddress - required: false -SuccessfulPayment: -- name: currency - type: String - required: true -- name: total_amount - type: Integer - required: true -- name: invoice_payload - type: String - required: true -- name: shipping_option_id - type: String - required: false -- name: order_info - type: OrderInfo - required: false -- name: telegram_payment_charge_id - type: String - required: true -- name: provider_payment_charge_id - type: String - required: true -InaccessibleMessage: -- name: chat - type: Chat - required: true -- name: message_id - type: Integer - required: true -- name: date - type: Integer - required: true -MessageAutoDeleteTimerChanged: -- name: message_auto_delete_time - type: Integer - required: true -TextQuote: -- name: text - type: String - required: true -- name: entities - type: Array of MessageEntity - required: false -- name: position - type: Integer - required: true -- name: is_manual - type: 'True' - required: false -Venue: -- name: location - type: Location - required: true -- name: title - type: String - required: true -- name: address - type: String - required: true -- name: foursquare_id - type: String - required: false -- name: foursquare_type - type: String - required: false -- name: google_place_id - type: String - required: false -- name: google_place_type - type: String - required: false -PollOption: -- name: text - type: String - required: true -- name: text_entities - type: Array of MessageEntity - required: false -- name: voter_count - type: Integer - required: true -Poll: -- name: id - type: String - required: true -- name: question - type: String - required: true -- name: question_entities - type: Array of MessageEntity - required: false -- name: options - type: Array of PollOption - required: true -- name: total_voter_count - type: Integer - required: true -- name: is_closed - type: Boolean - required: true -- name: is_anonymous - type: Boolean - required: true -- name: type - type: String - required: true -- name: allows_multiple_answers - type: Boolean - required: true -- name: correct_option_id - type: Integer - required: false -- name: explanation - type: String - required: false -- name: explanation_entities - type: Array of MessageEntity - required: false -- name: open_period - type: Integer - required: false -- name: close_date - type: Integer - required: false -Invoice: -- name: title - type: String - required: true -- name: description - type: String - required: true -- name: start_parameter - type: String - required: true -- name: currency - type: String - required: true -- name: total_amount - type: Integer - required: true -GiveawayWinners: -- name: chat - type: Chat - required: true -- name: giveaway_message_id - type: Integer - required: true -- name: winners_selection_date - type: Integer - required: true -- name: winner_count - type: Integer - required: true -- name: winners - type: Array of User - required: true -- name: additional_chat_count - type: Integer - required: false -- name: prize_star_count - type: Integer - required: false -- name: premium_subscription_month_count - type: Integer - required: false -- name: unclaimed_prize_count - type: Integer - required: false -- name: only_new_members - type: 'True' - required: false -- name: was_refunded - type: 'True' - required: false -- name: prize_description - type: String - required: false -Giveaway: -- name: chats - type: Array of Chat - required: true -- name: winners_selection_date - type: Integer - required: true -- name: winner_count - type: Integer - required: true -- name: only_new_members - type: 'True' - required: false -- name: has_public_winners - type: 'True' - required: false -- name: prize_description - type: String - required: false -- name: country_codes - type: Array of String - required: false -- name: prize_star_count - type: Integer - required: false -- name: premium_subscription_month_count - type: Integer - required: false -MessageEntity: -- name: type - type: String - required: true -- name: offset - type: Integer - required: true -- name: length - type: Integer - required: true -- name: url - type: String - required: false -- name: user - type: User - required: false -- name: language - type: String - required: false -- name: custom_emoji_id - type: String - required: false -Game: -- name: title - type: String - required: true -- name: description - type: String - required: true -- name: photo - type: Array of PhotoSize - required: true -- name: text - type: String - required: false -- name: text_entities - type: Array of MessageEntity - required: false -- name: animation - type: Animation - required: false -Dice: -- name: emoji - type: String - required: true -- name: value - type: Integer - required: true -Contact: -- name: phone_number - type: String - required: true -- name: first_name - type: String - required: true -- name: last_name - type: String - required: false -- name: user_id - type: Integer - required: false -- name: vcard - type: String - required: false -Voice: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: duration - type: Integer - required: true -- name: mime_type - type: String - required: false -- name: file_size - type: Integer - required: false -VideoNote: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: length - type: Integer - required: true -- name: duration - type: Integer - required: true -- name: thumbnail - type: PhotoSize - required: false -- name: file_size - type: Integer - required: false -Video: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: width - type: Integer - required: true -- name: height - type: Integer - required: true -- name: duration - type: Integer - required: true -- name: thumbnail - type: PhotoSize - required: false -- name: file_name - type: String - required: false -- name: mime_type - type: String - required: false -- name: file_size - type: Integer - required: false -Story: -- name: chat - type: Chat - required: true -- name: id - type: Integer - required: true -MaskPosition: -- name: point - type: String - required: true -- name: x_shift - type: Float - required: true -- name: y_shift - type: Float - required: true -- name: scale - type: Float - required: true -File: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: file_size - type: Integer - required: false -- name: file_path - type: String - required: false -Sticker: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: type - type: String - required: true -- name: width - type: Integer - required: true -- name: height - type: Integer - required: true -- name: is_animated - type: Boolean - required: true -- name: is_video - type: Boolean - required: true -- name: thumbnail - type: PhotoSize - required: false -- name: emoji - type: String - required: false -- name: set_name - type: String - required: false -- name: premium_animation - type: File - required: false -- name: mask_position - type: MaskPosition - required: false -- name: custom_emoji_id - type: String - required: false -- name: needs_repainting - type: 'True' - required: false -- name: file_size - type: Integer - required: false -Document: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: thumbnail - type: PhotoSize - required: false -- name: file_name - type: String - required: false -- name: mime_type - type: String - required: false -- name: file_size - type: Integer - required: false -Audio: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: duration - type: Integer - required: true -- name: performer - type: String - required: false -- name: title - type: String - required: false -- name: file_name - type: String - required: false -- name: mime_type - type: String - required: false -- name: file_size - type: Integer - required: false -- name: thumbnail - type: PhotoSize - required: false -PhotoSize: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: width - type: Integer - required: true -- name: height - type: Integer - required: true -- name: file_size - type: Integer - required: false -Animation: -- name: file_id - type: String - required: true -- name: file_unique_id - type: String - required: true -- name: width - type: Integer - required: true -- name: height - type: Integer - required: true -- name: duration - type: Integer - required: true -- name: thumbnail - type: PhotoSize - required: false -- name: file_name - type: String - required: false -- name: mime_type - type: String - required: false -- name: file_size - type: Integer - required: false -LinkPreviewOptions: -- name: is_disabled - type: Boolean - required: false -- name: url - type: String - required: false -- name: prefer_small_media - type: Boolean - required: false -- name: prefer_large_media - type: Boolean - required: false -- name: show_above_text - type: Boolean - required: false -ExternalReplyInfo: -- name: origin - type: MessageOrigin - required: true -- name: chat - type: Chat - required: false -- name: message_id - type: Integer - required: false -- name: link_preview_options - type: LinkPreviewOptions - required: false -- name: animation - type: Animation - required: false -- name: audio - type: Audio - required: false -- name: document - type: Document - required: false -- name: paid_media - type: PaidMediaInfo - required: false -- name: photo - type: Array of PhotoSize - required: false -- name: sticker - type: Sticker - required: false -- name: story - type: Story - required: false -- name: video - type: Video - required: false -- name: video_note - type: VideoNote - required: false -- name: voice - type: Voice - required: false -- name: has_media_spoiler - type: 'True' - required: false -- name: contact - type: Contact - required: false -- name: dice - type: Dice - required: false -- name: game - type: Game - required: false -- name: giveaway - type: Giveaway - required: false -- name: giveaway_winners - type: GiveawayWinners - required: false -- name: invoice - type: Invoice - required: false -- name: location - type: Location - required: false -- name: poll - type: Poll - required: false -- name: venue - type: Venue - required: false -MessageOriginChannel: -- name: type - type: String - required: true - required_value: channel -- name: date - type: Integer - required: true -- name: chat - type: Chat - required: true -- name: message_id - type: Integer - required: true -- name: author_signature - type: String - required: false -MessageOriginChat: -- name: type - type: String - required: true - required_value: chat -- name: date - type: Integer - required: true -- name: sender_chat - type: Chat - required: true -- name: author_signature - type: String - required: false -MessageOriginHiddenUser: -- name: type - type: String - required: true - required_value: hidden_user -- name: date - type: Integer - required: true -- name: sender_user_name - type: String - required: true -MessageOriginUser: -- name: type - type: String - required: true - required_value: user -- name: date - type: Integer - required: true -- name: sender_user - type: User - required: true -Location: -- name: latitude - type: Float - required: true -- name: longitude - type: Float - required: true -- name: horizontal_accuracy - type: Float - required: false -- name: live_period - type: Integer - required: false -- name: heading - type: Integer - required: false -- name: proximity_alert_radius - type: Integer - required: false -ChatLocation: -- name: location - type: Location - required: true -- name: address - type: String - required: true -ChatPermissions: -- name: can_send_messages - type: Boolean - required: false -- name: can_send_audios - type: Boolean - required: false -- name: can_send_documents - type: Boolean - required: false -- name: can_send_photos - type: Boolean - required: false -- name: can_send_videos - type: Boolean - required: false -- name: can_send_video_notes - type: Boolean - required: false -- name: can_send_voice_notes - type: Boolean - required: false -- name: can_send_polls - type: Boolean - required: false -- name: can_send_other_messages - type: Boolean - required: false -- name: can_add_web_page_previews - type: Boolean - required: false -- name: can_change_info - type: Boolean - required: false -- name: can_invite_users - type: Boolean - required: false -- name: can_pin_messages - type: Boolean - required: false -- name: can_manage_topics - type: Boolean - required: false -ReactionTypeCustomEmoji: -- name: type - type: String - required: true - required_value: custom_emoji -- name: custom_emoji_id - type: String - required: true -ReactionTypeEmoji: -- name: type - type: String - required: true - required_value: emoji -- name: emoji - type: String - required: true -ChatPhoto: -- name: small_file_id - type: String - required: true -- name: small_file_unique_id - type: String - required: true -- name: big_file_id - type: String - required: true -- name: big_file_unique_id - type: String - required: true -Birthdate: -- name: day - type: Integer - required: true -- name: month - type: Integer - required: true -- name: year - type: Integer - required: false -Chat: -- name: id - type: Integer - required: true -- name: type - type: String - required: true -- name: title - type: String - required: false -- name: username - type: String - required: false -- name: first_name - type: String - required: false -- name: last_name - type: String - required: false -- name: is_forum - type: 'True' - required: false -User: -- name: id - type: Integer - required: true -- name: is_bot - type: Boolean - required: true -- name: first_name - type: String - required: true -- name: last_name - type: String - required: false -- name: username - type: String - required: false -- name: language_code - type: String - required: false -- name: is_premium - type: 'True' - required: false -- name: added_to_attachment_menu - type: 'True' - required: false -- name: can_join_groups - type: Boolean - required: false -- name: can_read_all_group_messages - type: Boolean - required: false -- name: supports_inline_queries - type: Boolean - required: false -- name: can_connect_to_business - type: Boolean - required: false -- name: has_main_web_app - type: Boolean - required: false -Message: -- name: message_id - type: Integer - required: true -- name: message_thread_id - type: Integer - required: false -- name: from - type: User - required: false -- name: sender_chat - type: Chat - required: false -- name: sender_boost_count - type: Integer - required: false -- name: sender_business_bot - type: User - required: false -- name: date - type: Integer - required: true -- name: business_connection_id - type: String - required: false -- name: chat - type: Chat - required: true -- name: forward_origin - type: MessageOrigin - required: false -- name: is_topic_message - type: 'True' - required: false -- name: is_automatic_forward - type: 'True' - required: false -- name: reply_to_message - type: Message - required: false -- name: external_reply - type: ExternalReplyInfo - required: false -- name: quote - type: TextQuote - required: false -- name: reply_to_story - type: Story - required: false -- name: via_bot - type: User - required: false -- name: edit_date - type: Integer - required: false -- name: has_protected_content - type: 'True' - required: false -- name: is_from_offline - type: 'True' - required: false -- name: media_group_id - type: String - required: false -- name: author_signature - type: String - required: false -- name: text - type: String - required: false -- name: entities - type: Array of MessageEntity - required: false -- name: link_preview_options - type: LinkPreviewOptions - required: false -- name: effect_id - type: String - required: false -- name: animation - type: Animation - required: false -- name: audio - type: Audio - required: false -- name: document - type: Document - required: false -- name: paid_media - type: PaidMediaInfo - required: false -- name: photo - type: Array of PhotoSize - required: false -- name: sticker - type: Sticker - required: false -- name: story - type: Story - required: false -- name: video - type: Video - required: false -- name: video_note - type: VideoNote - required: false -- name: voice - type: Voice - required: false -- name: caption - type: String - required: false -- name: caption_entities - type: Array of MessageEntity - required: false -- name: show_caption_above_media - type: 'True' - required: false -- name: has_media_spoiler - type: 'True' - required: false -- name: contact - type: Contact - required: false -- name: dice - type: Dice - required: false -- name: game - type: Game - required: false -- name: poll - type: Poll - required: false -- name: venue - type: Venue - required: false -- name: location - type: Location - required: false -- name: new_chat_members - type: Array of User - required: false -- name: left_chat_member - type: User - required: false -- name: new_chat_title - type: String - required: false -- name: new_chat_photo - type: Array of PhotoSize - required: false -- name: delete_chat_photo - type: 'True' - required: false -- name: group_chat_created - type: 'True' - required: false -- name: supergroup_chat_created - type: 'True' - required: false -- name: channel_chat_created - type: 'True' - required: false -- name: message_auto_delete_timer_changed - type: MessageAutoDeleteTimerChanged - required: false -- name: migrate_to_chat_id - type: Integer - required: false -- name: migrate_from_chat_id - type: Integer - required: false -- name: pinned_message - type: MaybeInaccessibleMessage - required: false -- name: invoice - type: Invoice - required: false -- name: successful_payment - type: SuccessfulPayment - required: false -- name: refunded_payment - type: RefundedPayment - required: false -- name: users_shared - type: UsersShared - required: false -- name: chat_shared - type: ChatShared - required: false -- name: connected_website - type: String - required: false -- name: write_access_allowed - type: WriteAccessAllowed - required: false -- name: passport_data - type: PassportData - required: false -- name: proximity_alert_triggered - type: ProximityAlertTriggered - required: false -- name: boost_added - type: ChatBoostAdded - required: false -- name: chat_background_set - type: ChatBackground - required: false -- name: forum_topic_created - type: ForumTopicCreated - required: false -- name: forum_topic_edited - type: ForumTopicEdited - required: false -- name: forum_topic_closed - type: ForumTopicClosed - required: false -- name: forum_topic_reopened - type: ForumTopicReopened - required: false -- name: general_forum_topic_hidden - type: GeneralForumTopicHidden - required: false -- name: general_forum_topic_unhidden - type: GeneralForumTopicUnhidden - required: false -- name: giveaway_created - type: GiveawayCreated - required: false -- name: giveaway - type: Giveaway - required: false -- name: giveaway_winners - type: GiveawayWinners - required: false -- name: giveaway_completed - type: GiveawayCompleted - required: false -- name: video_chat_scheduled - type: VideoChatScheduled - required: false -- name: video_chat_started - type: VideoChatStarted - required: false -- name: video_chat_ended - type: VideoChatEnded - required: false -- name: video_chat_participants_invited - type: VideoChatParticipantsInvited - required: false -- name: web_app_data - type: WebAppData - required: false -- name: reply_markup - type: InlineKeyboardMarkup - required: false -Update: -- name: update_id - type: Integer - required: true -- name: message - type: Message - required: false -- name: edited_message - type: Message - required: false -- name: channel_post - type: Message - required: false -- name: edited_channel_post - type: Message - required: false -- name: business_connection - type: BusinessConnection - required: false -- name: business_message - type: Message - required: false -- name: edited_business_message - type: Message - required: false -- name: deleted_business_messages - type: BusinessMessagesDeleted - required: false -- name: message_reaction - type: MessageReactionUpdated - required: false -- name: message_reaction_count - type: MessageReactionCountUpdated - required: false -- name: inline_query - type: InlineQuery - required: false -- name: chosen_inline_result - type: ChosenInlineResult - required: false -- name: callback_query - type: CallbackQuery - required: false -- name: shipping_query - type: ShippingQuery - required: false -- name: pre_checkout_query - type: PreCheckoutQuery - required: false -- name: purchased_paid_media - type: PaidMediaPurchased - required: false -- name: poll - type: Poll - required: false -- name: poll_answer - type: PollAnswer - required: false -- name: my_chat_member - type: ChatMemberUpdated - required: false -- name: chat_member - type: ChatMemberUpdated - required: false -- name: chat_join_request - type: ChatJoinRequest - required: false -- name: chat_boost - type: ChatBoostUpdated - required: false -- name: removed_chat_boost - type: ChatBoostRemoved - required: false diff --git a/utility/empty_type.erb b/utility/empty_type.erb new file mode 100644 index 0000000..1d1e1e5 --- /dev/null +++ b/utility/empty_type.erb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Telegram + module Bot + module Types + ## Just for classes consistency + # rubocop:disable Naming/ConstantName + <%= name %> = ( + <%= attributes %> + ) + # rubocop:enable Naming/ConstantName + end + end +end diff --git a/spec/support/type.erb b/utility/type.erb similarity index 100% rename from spec/support/type.erb rename to utility/type.erb diff --git a/spec/support/openapi_type_attributes.json b/utility/type_attributes.json similarity index 90% rename from spec/support/openapi_type_attributes.json rename to utility/type_attributes.json index 74d4f87..ec98d99 100644 --- a/spec/support/openapi_type_attributes.json +++ b/utility/type_attributes.json @@ -253,7 +253,7 @@ }, "available_reactions": { "type": "array", - "items": null + "items": "ReactionType" }, "background_custom_emoji_id": { "type": "string" @@ -580,16 +580,16 @@ "type": "ForumTopicEdited" }, "forum_topic_closed": { - "type": null + "type": "ForumTopicClosed" }, "forum_topic_reopened": { - "type": null + "type": "ForumTopicReopened" }, "general_forum_topic_hidden": { - "type": null + "type": "GeneralForumTopicHidden" }, "general_forum_topic_unhidden": { - "type": null + "type": "GeneralForumTopicUnhidden" }, "giveaway_created": { "type": "GiveawayCreated" @@ -607,7 +607,7 @@ "type": "VideoChatScheduled" }, "video_chat_started": { - "type": null + "type": "VideoChatStarted" }, "video_chat_ended": { "type": "VideoChatEnded" @@ -642,7 +642,12 @@ "required": true } }, - "MaybeInaccessibleMessage": {}, + "MaybeInaccessibleMessage": { + "type": [ + "Message", + "InaccessibleMessage" + ] + }, "MessageEntity": { "type": { "type": "string", @@ -779,7 +784,8 @@ "type": "boolean" }, "quote": { - "type": "string" + "type": "string", + "max_size": 1024 }, "quote_parse_mode": { "type": "string" @@ -792,11 +798,19 @@ "type": "integer" } }, - "MessageOrigin": {}, + "MessageOrigin": { + "type": [ + "MessageOriginUser", + "MessageOriginHiddenUser", + "MessageOriginChat", + "MessageOriginChannel" + ] + }, "MessageOriginUser": { "type": { "type": "string", "required": true, + "required_value": "user", "default": "user" }, "date": { @@ -812,6 +826,7 @@ "type": { "type": "string", "required": true, + "required_value": "hidden_user", "default": "hidden_user" }, "date": { @@ -827,6 +842,7 @@ "type": { "type": "string", "required": true, + "required_value": "chat", "default": "chat" }, "date": { @@ -845,6 +861,7 @@ "type": { "type": "string", "required": true, + "required_value": "channel", "default": "channel" }, "date": { @@ -1068,14 +1085,21 @@ "paid_media": { "type": "array", "required": true, - "items": null + "items": "PaidMedia" } }, - "PaidMedia": {}, + "PaidMedia": { + "type": [ + "PaidMediaPreview", + "PaidMediaPhoto", + "PaidMediaVideo" + ] + }, "PaidMediaPreview": { "type": { "type": "string", "required": true, + "required_value": "preview", "default": "preview" }, "width": { @@ -1092,6 +1116,7 @@ "type": { "type": "string", "required": true, + "required_value": "photo", "default": "photo" }, "photo": { @@ -1104,6 +1129,7 @@ "type": { "type": "string", "required": true, + "required_value": "video", "default": "video" }, "video": { @@ -1143,7 +1169,9 @@ "PollOption": { "text": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 100 }, "text_entities": { "type": "array", @@ -1157,7 +1185,9 @@ "InputPollOption": { "text": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 100 }, "text_parse_mode": { "type": "string" @@ -1191,7 +1221,9 @@ }, "question": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 300 }, "question_entities": { "type": "array", @@ -1226,7 +1258,8 @@ "type": "integer" }, "explanation": { - "type": "string" + "type": "string", + "max_size": 200 }, "explanation_entities": { "type": "array", @@ -1323,11 +1356,18 @@ "required": true } }, - "BackgroundFill": {}, + "BackgroundFill": { + "type": [ + "BackgroundFillSolid", + "BackgroundFillGradient", + "BackgroundFillFreeformGradient" + ] + }, "BackgroundFillSolid": { "type": { "type": "string", "required": true, + "required_value": "solid", "default": "solid" }, "color": { @@ -1339,6 +1379,7 @@ "type": { "type": "string", "required": true, + "required_value": "gradient", "default": "gradient" }, "top_color": { @@ -1358,6 +1399,7 @@ "type": { "type": "string", "required": true, + "required_value": "freeform_gradient", "default": "freeform_gradient" }, "colors": { @@ -1366,11 +1408,19 @@ "items": "integer" } }, - "BackgroundType": {}, + "BackgroundType": { + "type": [ + "BackgroundTypeFill", + "BackgroundTypeWallpaper", + "BackgroundTypePattern", + "BackgroundTypeChatTheme" + ] + }, "BackgroundTypeFill": { "type": { "type": "string", "required": true, + "required_value": "fill", "default": "fill" }, "fill": { @@ -1386,6 +1436,7 @@ "type": { "type": "string", "required": true, + "required_value": "wallpaper", "default": "wallpaper" }, "document": { @@ -1409,6 +1460,7 @@ "type": { "type": "string", "required": true, + "required_value": "pattern", "default": "pattern" }, "document": { @@ -1436,6 +1488,7 @@ "type": { "type": "string", "required": true, + "required_value": "chat_theme", "default": "chat_theme" }, "theme_name": { @@ -1462,7 +1515,8 @@ "type": "string" } }, - "ForumTopicClosed": {}, + "ForumTopicClosed": { + }, "ForumTopicEdited": { "name": { "type": "string" @@ -1471,9 +1525,12 @@ "type": "string" } }, - "ForumTopicReopened": {}, - "GeneralForumTopicHidden": {}, - "GeneralForumTopicUnhidden": {}, + "ForumTopicReopened": { + }, + "GeneralForumTopicHidden": { + }, + "GeneralForumTopicUnhidden": { + }, "SharedUser": { "user_id": { "type": "integer", @@ -1541,7 +1598,8 @@ "required": true } }, - "VideoChatStarted": {}, + "VideoChatStarted": { + }, "VideoChatEnded": { "duration": { "type": "integer", @@ -1683,7 +1741,10 @@ "photos": { "type": "array", "required": true, - "items": "array" + "items": { + "type": "array", + "items": "PhotoSize" + } } }, "File": { @@ -1712,19 +1773,27 @@ "keyboard": { "type": "array", "required": true, - "items": "array" + "items": { + "type": "array", + "items": "KeyboardButton" + } }, "is_persistent": { - "type": "boolean" + "type": "boolean", + "default": false }, "resize_keyboard": { - "type": "boolean" + "type": "boolean", + "default": false }, "one_time_keyboard": { - "type": "boolean" + "type": "boolean", + "default": false }, "input_field_placeholder": { - "type": "string" + "type": "string", + "min_size": 1, + "max_size": 64 }, "selective": { "type": "boolean" @@ -1835,7 +1904,10 @@ "inline_keyboard": { "type": "array", "required": true, - "items": "array" + "items": { + "type": "array", + "items": "InlineKeyboardButton" + } } }, "InlineKeyboardButton": { @@ -1868,7 +1940,7 @@ "type": "CopyTextButton" }, "callback_game": { - "type": null + "type": "CallbackGame" }, "pay": { "type": "boolean" @@ -1909,7 +1981,9 @@ "CopyTextButton": { "text": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 256 } }, "CallbackQuery": { @@ -1945,7 +2019,9 @@ "default": true }, "input_field_placeholder": { - "type": "string" + "type": "string", + "min_size": 1, + "max_size": 64 }, "selective": { "type": "boolean" @@ -2098,11 +2174,21 @@ "type": "boolean" } }, - "ChatMember": {}, + "ChatMember": { + "type": [ + "ChatMemberOwner", + "ChatMemberAdministrator", + "ChatMemberMember", + "ChatMemberRestricted", + "ChatMemberLeft", + "ChatMemberBanned" + ] + }, "ChatMemberOwner": { "status": { "type": "string", "required": true, + "required_value": "creator", "default": "creator" }, "user": { @@ -2121,6 +2207,7 @@ "status": { "type": "string", "required": true, + "required_value": "administrator", "default": "administrator" }, "user": { @@ -2195,6 +2282,7 @@ "status": { "type": "string", "required": true, + "required_value": "member", "default": "member" }, "user": { @@ -2209,6 +2297,7 @@ "status": { "type": "string", "required": true, + "required_value": "restricted", "default": "restricted" }, "user": { @@ -2284,6 +2373,7 @@ "status": { "type": "string", "required": true, + "required_value": "left", "default": "left" }, "user": { @@ -2295,6 +2385,7 @@ "status": { "type": "string", "required": true, + "required_value": "kicked", "default": "kicked" }, "user": { @@ -2435,14 +2526,23 @@ }, "address": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 64 } }, - "ReactionType": {}, + "ReactionType": { + "type": [ + "ReactionTypeEmoji", + "ReactionTypeCustomEmoji", + "ReactionTypePaid" + ] + }, "ReactionTypeEmoji": { "type": { "type": "string", "required": true, + "required_value": "emoji", "default": "emoji" }, "emoji": { @@ -2454,6 +2554,7 @@ "type": { "type": "string", "required": true, + "required_value": "custom_emoji", "default": "custom_emoji" }, "custom_emoji_id": { @@ -2465,6 +2566,7 @@ "type": { "type": "string", "required": true, + "required_value": "paid", "default": "paid" } }, @@ -2500,12 +2602,12 @@ "old_reaction": { "type": "array", "required": true, - "items": null + "items": "ReactionType" }, "new_reaction": { "type": "array", "required": true, - "items": null + "items": "ReactionType" } }, "MessageReactionCountUpdated": { @@ -2547,18 +2649,33 @@ "BotCommand": { "command": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 32 }, "description": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 256 } }, - "BotCommandScope": {}, + "BotCommandScope": { + "type": [ + "BotCommandScopeDefault", + "BotCommandScopeAllPrivateChats", + "BotCommandScopeAllGroupChats", + "BotCommandScopeAllChatAdministrators", + "BotCommandScopeChat", + "BotCommandScopeChatAdministrators", + "BotCommandScopeChatMember" + ] + }, "BotCommandScopeDefault": { "type": { "type": "string", "required": true, + "required_value": "default", "default": "default" } }, @@ -2566,6 +2683,7 @@ "type": { "type": "string", "required": true, + "required_value": "all_private_chats", "default": "all_private_chats" } }, @@ -2573,6 +2691,7 @@ "type": { "type": "string", "required": true, + "required_value": "all_group_chats", "default": "all_group_chats" } }, @@ -2580,6 +2699,7 @@ "type": { "type": "string", "required": true, + "required_value": "all_chat_administrators", "default": "all_chat_administrators" } }, @@ -2587,6 +2707,7 @@ "type": { "type": "string", "required": true, + "required_value": "chat", "default": "chat" }, "chat_id": { @@ -2601,6 +2722,7 @@ "type": { "type": "string", "required": true, + "required_value": "chat_administrators", "default": "chat_administrators" }, "chat_id": { @@ -2615,6 +2737,7 @@ "type": { "type": "string", "required": true, + "required_value": "chat_member", "default": "chat_member" }, "chat_id": { @@ -2647,11 +2770,18 @@ "required": true } }, - "MenuButton": {}, + "MenuButton": { + "type": [ + "MenuButtonCommands", + "MenuButtonWebApp", + "MenuButtonDefault" + ] + }, "MenuButtonCommands": { "type": { "type": "string", "required": true, + "required_value": "commands", "default": "commands" } }, @@ -2659,6 +2789,7 @@ "type": { "type": "string", "required": true, + "required_value": "web_app", "default": "web_app" }, "text": { @@ -2674,14 +2805,22 @@ "type": { "type": "string", "required": true, + "required_value": "default", "default": "default" } }, - "ChatBoostSource": {}, + "ChatBoostSource": { + "type": [ + "ChatBoostSourcePremium", + "ChatBoostSourceGiftCode", + "ChatBoostSourceGiveaway" + ] + }, "ChatBoostSourcePremium": { "source": { "type": "string", "required": true, + "required_value": "premium", "default": "premium" }, "user": { @@ -2693,6 +2832,7 @@ "source": { "type": "string", "required": true, + "required_value": "gift_code", "default": "gift_code" }, "user": { @@ -2704,6 +2844,7 @@ "source": { "type": "string", "required": true, + "required_value": "giveaway", "default": "giveaway" }, "giveaway_message_id": { @@ -2823,11 +2964,20 @@ "type": "integer" } }, - "InputMedia": {}, + "InputMedia": { + "type": [ + "InputMediaAnimation", + "InputMediaDocument", + "InputMediaAudio", + "InputMediaPhoto", + "InputMediaVideo" + ] + }, "InputMediaPhoto": { "type": { "type": "string", "required": true, + "required_value": "photo", "default": "photo" }, "media": { @@ -2835,7 +2985,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -2855,6 +3006,7 @@ "type": { "type": "string", "required": true, + "required_value": "video", "default": "video" }, "media": { @@ -2862,13 +3014,11 @@ "required": true }, "thumbnail": { - "type": [ - "InputFile", - "string" - ] + "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -2900,6 +3050,7 @@ "type": { "type": "string", "required": true, + "required_value": "animation", "default": "animation" }, "media": { @@ -2907,13 +3058,11 @@ "required": true }, "thumbnail": { - "type": [ - "InputFile", - "string" - ] + "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -2942,6 +3091,7 @@ "type": { "type": "string", "required": true, + "required_value": "audio", "default": "audio" }, "media": { @@ -2949,13 +3099,11 @@ "required": true }, "thumbnail": { - "type": [ - "InputFile", - "string" - ] + "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -2978,6 +3126,7 @@ "type": { "type": "string", "required": true, + "required_value": "document", "default": "document" }, "media": { @@ -2985,13 +3134,11 @@ "required": true }, "thumbnail": { - "type": [ - "InputFile", - "string" - ] + "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3004,12 +3151,17 @@ "type": "boolean" } }, - "InputFile": {}, - "InputPaidMedia": {}, + "InputPaidMedia": { + "type": [ + "InputPaidMediaPhoto", + "InputPaidMediaVideo" + ] + }, "InputPaidMediaPhoto": { "type": { "type": "string", "required": true, + "required_value": "photo", "default": "photo" }, "media": { @@ -3021,6 +3173,7 @@ "type": { "type": "string", "required": true, + "required_value": "video", "default": "video" }, "media": { @@ -3028,10 +3181,7 @@ "required": true }, "thumbnail": { - "type": [ - "InputFile", - "string" - ] + "type": "string" }, "width": { "type": "integer" @@ -3143,10 +3293,7 @@ }, "InputSticker": { "sticker": { - "type": [ - "InputFile", - "string" - ], + "type": "string", "required": true }, "format": { @@ -3199,14 +3346,40 @@ "type": "WebAppInfo" }, "start_parameter": { - "type": "string" - } + "type": "string", + "min_size": 1, + "max_size": 64 + } + }, + "InlineQueryResult": { + "type": [ + "InlineQueryResultCachedAudio", + "InlineQueryResultCachedDocument", + "InlineQueryResultCachedGif", + "InlineQueryResultCachedMpeg4Gif", + "InlineQueryResultCachedPhoto", + "InlineQueryResultCachedSticker", + "InlineQueryResultCachedVideo", + "InlineQueryResultCachedVoice", + "InlineQueryResultArticle", + "InlineQueryResultAudio", + "InlineQueryResultContact", + "InlineQueryResultGame", + "InlineQueryResultDocument", + "InlineQueryResultGif", + "InlineQueryResultLocation", + "InlineQueryResultMpeg4Gif", + "InlineQueryResultPhoto", + "InlineQueryResultVenue", + "InlineQueryResultVideo", + "InlineQueryResultVoice" + ] }, - "InlineQueryResult": {}, "InlineQueryResultArticle": { "type": { "type": "string", "required": true, + "required_value": "article", "default": "article" }, "id": { @@ -3247,6 +3420,7 @@ "type": { "type": "string", "required": true, + "required_value": "photo", "default": "photo" }, "id": { @@ -3274,7 +3448,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3297,6 +3472,7 @@ "type": { "type": "string", "required": true, + "required_value": "gif", "default": "gif" }, "id": { @@ -3328,7 +3504,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3351,6 +3528,7 @@ "type": { "type": "string", "required": true, + "required_value": "mpeg4_gif", "default": "mpeg4_gif" }, "id": { @@ -3382,7 +3560,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3405,6 +3584,7 @@ "type": { "type": "string", "required": true, + "required_value": "video", "default": "video" }, "id": { @@ -3428,7 +3608,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3463,6 +3644,7 @@ "type": { "type": "string", "required": true, + "required_value": "audio", "default": "audio" }, "id": { @@ -3478,7 +3660,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3504,6 +3687,7 @@ "type": { "type": "string", "required": true, + "required_value": "voice", "default": "voice" }, "id": { @@ -3519,7 +3703,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3542,6 +3727,7 @@ "type": { "type": "string", "required": true, + "required_value": "document", "default": "document" }, "id": { @@ -3553,7 +3739,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3593,6 +3780,7 @@ "type": { "type": "string", "required": true, + "required_value": "location", "default": "location" }, "id": { @@ -3643,6 +3831,7 @@ "type": { "type": "string", "required": true, + "required_value": "venue", "default": "venue" }, "id": { @@ -3697,6 +3886,7 @@ "type": { "type": "string", "required": true, + "required_value": "contact", "default": "contact" }, "id": { @@ -3737,6 +3927,7 @@ "type": { "type": "string", "required": true, + "required_value": "game", "default": "game" }, "id": { @@ -3755,6 +3946,7 @@ "type": { "type": "string", "required": true, + "required_value": "photo", "default": "photo" }, "id": { @@ -3772,7 +3964,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3795,6 +3988,7 @@ "type": { "type": "string", "required": true, + "required_value": "gif", "default": "gif" }, "id": { @@ -3809,7 +4003,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3832,6 +4027,7 @@ "type": { "type": "string", "required": true, + "required_value": "mpeg4_gif", "default": "mpeg4_gif" }, "id": { @@ -3846,7 +4042,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3869,6 +4066,7 @@ "type": { "type": "string", "required": true, + "required_value": "sticker", "default": "sticker" }, "id": { @@ -3890,6 +4088,7 @@ "type": { "type": "string", "required": true, + "required_value": "document", "default": "document" }, "id": { @@ -3908,7 +4107,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3928,6 +4128,7 @@ "type": { "type": "string", "required": true, + "required_value": "video", "default": "video" }, "id": { @@ -3946,7 +4147,8 @@ "type": "string" }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -3969,6 +4171,7 @@ "type": { "type": "string", "required": true, + "required_value": "voice", "default": "voice" }, "id": { @@ -3984,7 +4187,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -4004,6 +4208,7 @@ "type": { "type": "string", "required": true, + "required_value": "audio", "default": "audio" }, "id": { @@ -4015,7 +4220,8 @@ "required": true }, "caption": { - "type": "string" + "type": "string", + "max_size": 1024 }, "parse_mode": { "type": "string" @@ -4031,11 +4237,21 @@ "type": "InputMessageContent" } }, - "InputMessageContent": {}, + "InputMessageContent": { + "type": [ + "InputTextMessageContent", + "InputLocationMessageContent", + "InputVenueMessageContent", + "InputContactMessageContent", + "InputInvoiceMessageContent" + ] + }, "InputTextMessageContent": { "message_text": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 4096 }, "parse_mode": { "type": "string" @@ -4119,11 +4335,15 @@ "InputInvoiceMessageContent": { "title": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 32 }, "description": { "type": "string", - "required": true + "required": true, + "min_size": 1, + "max_size": 255 }, "payload": { "type": "string", @@ -4330,6 +4550,7 @@ "currency": { "type": "string", "required": true, + "required_value": "XTR", "default": "XTR" }, "total_amount": { @@ -4404,11 +4625,18 @@ "required": true } }, - "RevenueWithdrawalState": {}, + "RevenueWithdrawalState": { + "type": [ + "RevenueWithdrawalStatePending", + "RevenueWithdrawalStateSucceeded", + "RevenueWithdrawalStateFailed" + ] + }, "RevenueWithdrawalStatePending": { "type": { "type": "string", "required": true, + "required_value": "pending", "default": "pending" } }, @@ -4416,6 +4644,7 @@ "type": { "type": "string", "required": true, + "required_value": "succeeded", "default": "succeeded" }, "date": { @@ -4431,14 +4660,24 @@ "type": { "type": "string", "required": true, + "required_value": "failed", "default": "failed" } }, - "TransactionPartner": {}, + "TransactionPartner": { + "type": [ + "TransactionPartnerUser", + "TransactionPartnerFragment", + "TransactionPartnerTelegramAds", + "TransactionPartnerTelegramApi", + "TransactionPartnerOther" + ] + }, "TransactionPartnerUser": { "type": { "type": "string", "required": true, + "required_value": "user", "default": "user" }, "user": { @@ -4450,7 +4689,7 @@ }, "paid_media": { "type": "array", - "items": null + "items": "PaidMedia" }, "paid_media_payload": { "type": "string" @@ -4460,6 +4699,7 @@ "type": { "type": "string", "required": true, + "required_value": "fragment", "default": "fragment" }, "withdrawal_state": { @@ -4470,6 +4710,7 @@ "type": { "type": "string", "required": true, + "required_value": "telegram_ads", "default": "telegram_ads" } }, @@ -4477,6 +4718,7 @@ "type": { "type": "string", "required": true, + "required_value": "telegram_api", "default": "telegram_api" }, "request_count": { @@ -4488,6 +4730,7 @@ "type": { "type": "string", "required": true, + "required_value": "other", "default": "other" } }, @@ -4597,11 +4840,24 @@ "required": true } }, - "PassportElementError": {}, + "PassportElementError": { + "type": [ + "PassportElementErrorDataField", + "PassportElementErrorFrontSide", + "PassportElementErrorReverseSide", + "PassportElementErrorSelfie", + "PassportElementErrorFile", + "PassportElementErrorFiles", + "PassportElementErrorTranslationFile", + "PassportElementErrorTranslationFiles", + "PassportElementErrorUnspecified" + ] + }, "PassportElementErrorDataField": { "source": { "type": "string", "required": true, + "required_value": "data", "default": "data" }, "type": { @@ -4625,6 +4881,7 @@ "source": { "type": "string", "required": true, + "required_value": "front_side", "default": "front_side" }, "type": { @@ -4644,6 +4901,7 @@ "source": { "type": "string", "required": true, + "required_value": "reverse_side", "default": "reverse_side" }, "type": { @@ -4663,6 +4921,7 @@ "source": { "type": "string", "required": true, + "required_value": "selfie", "default": "selfie" }, "type": { @@ -4682,6 +4941,7 @@ "source": { "type": "string", "required": true, + "required_value": "file", "default": "file" }, "type": { @@ -4701,6 +4961,7 @@ "source": { "type": "string", "required": true, + "required_value": "files", "default": "files" }, "type": { @@ -4721,6 +4982,7 @@ "source": { "type": "string", "required": true, + "required_value": "translation_file", "default": "translation_file" }, "type": { @@ -4740,6 +5002,7 @@ "source": { "type": "string", "required": true, + "required_value": "translation_files", "default": "translation_files" }, "type": { @@ -4760,6 +5023,7 @@ "source": { "type": "string", "required": true, + "required_value": "unspecified", "default": "unspecified" }, "type": { @@ -4790,7 +5054,8 @@ "items": "PhotoSize" }, "text": { - "type": "string" + "type": "string", + "max_size": 4096 }, "text_entities": { "type": "array", @@ -4800,7 +5065,8 @@ "type": "Animation" } }, - "CallbackGame": {}, + "CallbackGame": { + }, "GameHighScore": { "position": { "type": "integer",