lib/dingtalk/robot.rb in dingtalk-robot-0.1.0 vs lib/dingtalk/robot.rb in dingtalk-robot-0.2.0

- old
+ new

@@ -1,11 +1,78 @@ # frozen_string_literal: true -require 'dingtalk/robot/version' +require 'active_support/all' +require 'net/http' +require 'dingtalk/robot/configurable' +require 'dingtalk/robot/errors' +require 'dingtalk/robot/strategies/text_strategy' +require 'dingtalk/robot/strategies/markdown_strategy' module Dingtalk # DingTalk Group Robot # @see https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq - module Robot - # Your code goes here... + class Robot + include Configurable + delegate :notify, to: :message_strategy + + # @param channel [#to_sym] Set both api token and message template + # @param message_type [#to_sym] (:text) Message type + # @example + # # Config api token and message template directory + # Dingtalk::Robot.config.tokens = { order: 'WEBHOOK...' } + # Dingtalk::Robot.config.template_dir = '.' + # system %q(echo 'hello, <%= @name %>' > order.text.erb) + # + # # Notify message + # robot = Dingtalk::Robot.new(:order) { @name = 'Pine Wong' } + # robot.notify + def initialize(channel, message_type = nil, &context_block) + @channel = channel.to_sym + self.message_type = message_type&.to_sym + @context_block = context_block + end + + private + + attr_reader :channel, :message_type, :context_block + delegate :config, to: :class + + # @param message_type [Symbol, nil] + def message_type=(message_type) + @message_type = message_type || begin + template_paths = Dir["#{config.template_dir}/#{channel}.*.erb"] + if template_paths.empty? + raise ArgumentError, "Undefined channel template, channel: #{channel}, template_dir: #{config.template_dir}" + end + types = template_paths.map do |template_path| + template_path[%r{#{config.template_dir}/#{channel}.([a-zA-Z]+).erb}, 1].to_sym + end + types.include?(config.message_type) ? config.message_type : types.first + end + valid = VALID_MESSAGE_TYPES.include?(@message_type) + raise ConfigurationError.new(:message_type, @message_type, VALID_MESSAGE_TYPES) unless valid + end + + def message_strategy + self.class.const_get("#{message_type.to_s.camelize}Strategy").new(webhook_url, message) + end + + def webhook_url + token = config.tokens[channel] + raise ArgumentError, "Undefined channel token, channel: #{channel}, tokens: #{config.tokens}" unless token + "#{WEBHOOK_BASE_URL}#{token}" + end + + def message + path = "#{config.template_dir}/#{channel}.#{message_type}.erb" + ERB.new(File.read(path)).result(context) + rescue Errno::ENOENT + raise ArgumentError, "Undefined channel template, channel: #{channel}, path: #{path}" + end + + def context + blank_object = Object.new + blank_object.instance_eval(&context_block) if context_block + blank_object.instance_eval { binding } + end end end