Friday, September 20, 2024 4:28:34 AM
> settings

Customize


Authenticate

> lifecycle.rb
# frozen_string_literal: true

module ESM
  module Command
    class Base
      module Lifecycle
        extend ActiveSupport::Concern

        class_methods do
          #
          # The entry point of a command
          # This is registered with Discordrb and is called as part of an interaction lifecycle
          #
          # @note This method will gracefully handle 99% of the errors automatically.
          # I recommend avoiding manually handling exceptions in a command's lifecycle so this system can handle it. But the choice is up to you
          #
          # @!visibility private
          #
          def event_hook(event)
            event = ESM::Event::ApplicationCommand.new(event)
            event.on_execution(self)
          end
        end

        #
        # Called internally by #execute, this method handles when a command has been executed on Discord.
        #
        def from_discord!
          # Check for these BEFORE validating the arguments so even if an argument was invalid, it doesn't matter since these take priority
          timers.time!(:access_checks) do
            check_for_dev_only!
            check_for_registered!
            check_for_text_only!
            check_for_dm_only!
            check_for_player_mode!
            check_for_permissions!
          end

          # Now ensure the user hasn't smoked too much lead
          timers.time!(:argument_validation) do
            arguments.validate!
          end

          # Adding a comment to make this look better is always a weird idea
          info!(to_h)

          # Finish up the checks
          timers.time!(:before_execute) do
            check_for_nil_target_community! unless skipped_actions.nil_target_community?
            check_for_nil_target_server! unless skipped_actions.nil_target_server?
            check_for_nil_target_user! unless skipped_actions.nil_target_user?
            check_for_connected_server! unless skipped_actions.connected_server?
            check_for_cooldown! unless skipped_actions.cooldown?
            check_for_different_community! unless skipped_actions.different_community?
          end

          # Now execute the command
          result = nil
          timers.time!(:on_execute) do
            load_v1_code! if v1_code_needed? # V1

            result = on_execute
          end

          timers.time!(:after_execute) do
            # Update the cooldown after the command has ran just in case there are issues
            create_or_update_cooldown unless skipped_actions.cooldown?
          end

          result
        end

        # @param request [ESM::Request] The request to build this command with
        # @note Don't load `target_user` from the request. If the arguments contain a target, it will handle it
        def from_request(request)
          @request = request
          @current_channel = ESM.bot.channel(request.requested_from_channel_id)
          @current_user = request.requestor

          # Initialize our command from the request
          arguments.merge!(request.command_arguments.symbolize_keys) if request.command_arguments.present?

          timers.time!(:from_request) do
            load_v1_code! if v1_code_needed? # V1

            if @request.accepted
              on_request_accepted
            else
              # Reset the cooldown since the request was declined.
              current_cooldown.reset! if current_cooldown.present?

              on_request_declined
            end
          end
        end

        def on_execute
        end

        def on_request_accepted
        end

        def on_request_declined
        end
      end
    end
  end
end
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8