telegram-bot-rb / telegram-bot

Ruby gem for building Telegram Bot with optional Rails integration
MIT License
635 stars 117 forks source link

how can I make additional dispatcher in TelegramWebhookController? #232

Closed gorrus39 closed 6 months ago

gorrus39 commented 6 months ago

How can I make it possible to transfer further conditional processing in the TelegramWebhookController controller to another controller?

# frozen_string_literal: true

class TelegramWebhookController < Telegram::Bot::UpdatesController
  before_action :dispatch

  private

  def dispatch
    if from_group_chat?
      delegate_to GroupChat::MainController
    elsif from_private_chat?
      delegate_to PrivateChat::MainController
    end
  end
end

for example, have a file structure like this

telegram_webhook_controller.rb
- private_chat
-- main_controller.rb
- group_chat
-- main_controller.rb
gorrus39 commented 6 months ago

I accomplished it this way

Can this be done somehow better?

telegram_dispatcher_controller.rb

# frozen_string_literal: true

require_relative 'telegram/private_chat/commands'
require_relative 'telegram/checkers'

class TelegramDispatcherController
  class << self
    def dispatch(bot, update)
      instance = new(bot, update)
      checks_handled = instance.handle_checkers
      instance.dispatch if checks_handled
    end
  end

  attr_reader :bot, :update

  def initialize(bot, update)
    @bot = bot
    @update = update
  end

  CHECKS = %i[
    user_allowed?
  ].freeze

  def handle_checkers
    checker = Telegram::Checkers.new(update)
    result = true
    CHECKS.each do |check|
      result = checker.send(check) == :next
      break unless result
    end
    result
  end

  def dispatch
    some_condition = true
    if some_condition
      Telegram::PrivateChat::Command.dispatch(bot, update)
    else
      # another class
    end
  end
end

checkers.rb

# frozen_string_literal: true

module Telegram
  class Checkers < Telegram::Bot::UpdatesController
    def initializer(update)
      @update = update
    end

    def user_allowed?
      :next
    end
  end
end

commands.rb


module Telegram
  module PrivateChat
    class Command < Telegram::Bot::UpdatesController
      def start!(*)
        respond_with :message, text: t('.content')
      end
    end
  end
end

file structure

application_controller.rb
- telegram
-- private_chat
--- commands.rb
-- checkers.rb
printercu commented 6 months ago

https://github.com/telegram-bot-rb/telegram-bot/wiki/Multiple-controllers-for-single-bot