Class: Telegem::Webhook::Server
- Inherits:
-
Object
- Object
- Telegem::Webhook::Server
- Defined in:
- lib/webhook/server.rb
Instance Attribute Summary collapse
-
#bot ⇒ Object
readonly
Returns the value of attribute bot.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#running ⇒ Object
readonly
Returns the value of attribute running.
-
#secret_token ⇒ Object
readonly
Returns the value of attribute secret_token.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#ssl_mode ⇒ Object
readonly
Returns the value of attribute ssl_mode.
Instance Method Summary collapse
- #delete_webhook ⇒ Object
- #determine_ssl_mode(ssl_options) ⇒ Object
- #get_webhook_info ⇒ Object
- #handle_request(request) ⇒ Object
- #handle_webhook_request(request) ⇒ Object
- #health_endpoint(request) ⇒ Object
-
#initialize(bot, port: nil, host: '0.0.0.0', secret_token: nil, logger: nil, ssl: nil) ⇒ Server
constructor
A new instance of Server.
- #load_certificate_files(cert_path, key_path) ⇒ Object
- #log_configuration ⇒ Object
- #process_webhook_update(update_data) ⇒ Object
- #run ⇒ Object
- #running? ⇒ Boolean
- #set_webhook(**options) ⇒ Object
- #stop ⇒ Object
- #validate_ssl_setup ⇒ Object
- #webhook_url ⇒ Object
Constructor Details
#initialize(bot, port: nil, host: '0.0.0.0', secret_token: nil, logger: nil, ssl: nil) ⇒ Server
Returns a new instance of Server.
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/webhook/server.rb', line 15 def initialize(bot, port: nil, host: '0.0.0.0', secret_token: nil, logger: nil, ssl: nil) @bot = bot @port = port || ENV['PORT'] || 3000 @host = host @secret_token = secret_token || ENV['WEBHOOK_SECRET_TOKEN'] || SecureRandom.hex(16) @logger = logger || Logger.new($stdout) @running = false @server = nil @ssl_mode, @ssl_context = determine_ssl_mode(ssl) log_configuration validate_ssl_setup end |
Instance Attribute Details
#bot ⇒ Object (readonly)
Returns the value of attribute bot.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def bot @bot end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def host @host end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def logger @logger end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def port @port end |
#running ⇒ Object (readonly)
Returns the value of attribute running.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def running @running end |
#secret_token ⇒ Object (readonly)
Returns the value of attribute secret_token.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def secret_token @secret_token end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def server @server end |
#ssl_mode ⇒ Object (readonly)
Returns the value of attribute ssl_mode.
13 14 15 |
# File 'lib/webhook/server.rb', line 13 def ssl_mode @ssl_mode end |
Instance Method Details
#delete_webhook ⇒ Object
172 173 174 175 |
# File 'lib/webhook/server.rb', line 172 def delete_webhook @bot.delete_webhook @logger.info("Webhook deleted") end |
#determine_ssl_mode(ssl_options) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/webhook/server.rb', line 29 def determine_ssl_mode() return [:none, nil] if == false if File.exist?('.telegem-ssl') config = YAML.load_file('.telegem-ssl') cert_path = config['cert_path'] key_path = config['key_path'] if cert_path && key_path && File.exist?(cert_path) && File.exist?(key_path) return [:cli, load_certificate_files(cert_path, key_path)] end end if && [:cert_path] && [:key_path] return [:manual, load_certificate_files([:cert_path], [:key_path])] end if ENV['TELEGEM_WEBHOOK_URL'] && URI(ENV['TELEGEM_WEBHOOK_URL']).scheme == 'https' return [:cloud, nil] end [:none, nil] end |
#get_webhook_info ⇒ Object
177 178 179 |
# File 'lib/webhook/server.rb', line 177 def get_webhook_info @bot.get_webhook_info end |
#handle_request(request) ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/webhook/server.rb', line 106 def handle_request(request) case request.path when @secret_token, "/#{@secret_token}" handle_webhook_request(request) when '/health', '/healthz' health_endpoint(request) else [404, {}, ["Not Found"]] end end |
#handle_webhook_request(request) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/webhook/server.rb', line 117 def handle_webhook_request(request) return [405, {}, ["Method Not Allowed"]] unless request.post? begin body = request.body.read update_data = JSON.parse(body) process_webhook_update(update_data) [200, {}, ["OK"]] rescue [500, {}, ["Internal Server Error"]] end end |
#health_endpoint(request) ⇒ Object
136 137 138 139 140 141 142 |
# File 'lib/webhook/server.rb', line 136 def health_endpoint(request) [200, { 'Content-Type' => 'application/json' }, [{ status: 'ok', mode: @ssl_mode.to_s, ssl: @ssl_mode != :none }.to_json]] end |
#load_certificate_files(cert_path, key_path) ⇒ Object
53 54 55 56 57 58 59 60 |
# File 'lib/webhook/server.rb', line 53 def load_certificate_files(cert_path, key_path) ctx = OpenSSL::SSL::SSLContext.new ctx.cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) ctx.key = OpenSSL::PKey::RSA.new(File.read(key_path)) ctx rescue nil end |
#log_configuration ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/webhook/server.rb', line 72 def log_configuration @logger.info("Webhook Server Configuration:") @logger.info(" Mode: #{@ssl_mode.to_s.upcase}") @logger.info(" Port: #{@port}") @logger.info(" Host: #{@host}") @logger.info(" Secret: #{@secret_token[0..8]}...") end |
#process_webhook_update(update_data) ⇒ Object
130 131 132 133 134 |
# File 'lib/webhook/server.rb', line 130 def process_webhook_update(update_data) @bot.process(update_data) rescue => e @logger.error("Process error: #{e}") end |
#run ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/webhook/server.rb', line 80 def run return if @running @running = true case @ssl_mode when :cli, :manual endpoint = Async::HTTP::Endpoint.parse("https://#{@host}:#{@port}", ssl_context: @ssl_context) @logger.info("Starting HTTPS server with local certificates") when :cloud endpoint = Async::HTTP::Endpoint.parse("http://#{@host}:#{@port}") @logger.info("Starting HTTP server (cloud platform handles SSL)") else endpoint = Async::HTTP::Endpoint.parse("http://#{@host}:#{@port}") @logger.warn("Starting HTTP server (Telegram requires HTTPS)") end @server = Async::HTTP::Server.for(endpoint) do |request| handle_request(request) end Async do |task| @server.run task.sleep while @running end end |
#running? ⇒ Boolean
181 182 183 |
# File 'lib/webhook/server.rb', line 181 def running? @running end |
#set_webhook(**options) ⇒ Object
164 165 166 167 168 169 170 |
# File 'lib/webhook/server.rb', line 164 def set_webhook(**) url = webhook_url params = { url: url }.merge() @bot.set_webhook(**params) @logger.info("Webhook set to: #{url}") url end |
#stop ⇒ Object
144 145 146 147 148 149 150 |
# File 'lib/webhook/server.rb', line 144 def stop return unless @running @running = false @server&.close @logger.info("Server stopped") @server = nil end |
#validate_ssl_setup ⇒ Object
62 63 64 65 66 67 68 69 70 |
# File 'lib/webhook/server.rb', line 62 def validate_ssl_setup case @ssl_mode when :cli, :manual raise "SSL certificate files not found or invalid" if @ssl_context.nil? when :cloud url = URI(ENV['TELEGEM_WEBHOOK_URL']) raise "TELEGEM_WEBHOOK_URL must be HTTPS" unless url.scheme == 'https' end end |
#webhook_url ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/webhook/server.rb', line 152 def webhook_url case @ssl_mode when :cli, :manual "https://#{@host}:#{@port}#{@secret_token}" when :cloud cloud_url = ENV['TELEGEM_WEBHOOK_URL'].chomp('/') "#{cloud_url}#{@secret_token}" else "http://#{@host}:#{@port}#{@secret_token}" end end |