class Rubirai::MessageChain
@!attribute [r] has_interpolation
@return [Boolean] if this message chain has interpolation called by {#interpolated_str}
Message
chain
@!attribute [r] bot
@return [Bot] the bot object
@!attribute [r] id
@return [Integer, nil] the message id, may be `nil`
@!attribute [r] raw
@return [Hash{String => Object}, nil] the raw message chain, may be `nil`
@!attribute [r] send_time
@return [Integer, nil] the send time of the message chain, may be `nil`
@!attribute [r] messages
@return [Array<Message>] the raw message array
Constants
- OBJ_INTERP_CHAR
- OBJ_INTERP_LEN
Attributes
Public Class Methods
Makes a message chain from a list of messages
@param messages [Array<Rubirai::Message, Rubirai::MessageChain
, Hash
, String
, Object>] a list of messages @param bot [Rubirai::Bot, nil] @return [Rubirai::MessageChain] the message chain
# File lib/rubirai/messages/message_chain.rb, line 29 def self.make(*messages, bot: nil) chain = new(bot) result = [] messages.map { |msg| Message.to_message(msg, bot) }.each do |msg| if !result.empty? && result[-1].is_a?(PlainMessage) && msg.is_a?(PlainMessage) result[-1] = PlainMessage.from(text: result[-1].text + msg.text, bot: bot) else result.append msg end end chain.extend(*result) chain end
Don't use the constructor. Use {.make}.
@private @param bot [Rubirai::Bot, nil] @param source [Array, nil]
# File lib/rubirai/messages/message_chain.rb, line 93 def initialize(bot = nil, source = nil) @bot = bot @messages = [] @has_interpolation = false @interpolated_str = nil @ipl_objs_map = {} @raw = source return unless source raise(MiraiError, 'source is not array') unless source.is_a? Array raise(MiraiError, 'length is zero') if source.empty? if source[0]['type'] == 'Source' @id = source[0]['id'] @send_time = source[0]['time'] extend(*source.drop(1)) else extend(*source) end end
Public Instance Methods
# File lib/rubirai/messages/message_chain.rb, line 68 def [](idx) @messages[idx] end
Get a new chain from interpolated string generated from the original message chain. The given interpolated string can be a substring of original one so that elements can be extracted easily.
@param str [String] the interpolated string @return [MessageChain] the message chain constructed
# File lib/rubirai/messages/interpolation.rb, line 35 def chain_from_interpolated(str) _interpolate_with_objects(str) end
Concats this message chain with another one
@param msg_chain [MessageChain] another message chain @return [MessageChain] self
# File lib/rubirai/messages/message_chain.rb, line 61 def concat!(msg_chain) msg_chain.messages.each do |msg| internal_append msg end self end
# File lib/rubirai/messages/message_chain.rb, line 72 def each(&block) @messages.each(&block) end
# File lib/rubirai/messages/message_chain.rb, line 84 def empty? @messages.empty? end
Append messages to this message chain
@param messages [Array<Rubirai::Message, Hash>] a list of messages @return [Rubirai::MessageChain] self
# File lib/rubirai/messages/message_chain.rb, line 47 def extend(*messages) messages.each do |msg| internal_append msg end self end
Get the interpolated object by given id
@param obj_id [String] the object id @return [Message, nil] the message. `nil` if `obj_id` is malformed or not found.
# File lib/rubirai/messages/interpolation.rb, line 25 def get_object(obj_id) _get_object(obj_id) end
Convert the message chain to an interpolated string.
@return [String]
# File lib/rubirai/messages/interpolation.rb, line 14 def interpolated_str return @interpolated_str if @has_interpolation @interpolated_str = _gen_interp_str @has_interpolation = true @interpolated_str end
# File lib/rubirai/messages/message_chain.rb, line 76 def length @messages.length end
# File lib/rubirai/messages/message_chain.rb, line 80 def size @messages.size end
Convert the message chain to an array of hashes.
@return [Array<Hash{String => Object}>]
# File lib/rubirai/messages/message_chain.rb, line 116 def to_a @messages.map(&:to_h) end
Private Instance Methods
# File lib/rubirai/messages/interpolation.rb, line 44 def _gen_interp_str result = +'' @messages.each do |msg| result << case msg when PlainMessage _transform_plain_txt(msg.text) else _transform_object(msg) end end result end
# File lib/rubirai/messages/interpolation.rb, line 68 def _get_object(obj_id) return nil if obj_id.length != OBJ_INTERP_LEN && obj_id.length != (OBJ_INTERP_LEN + 2) return @ipl_objs_map[obj_id] if obj_id.length == OBJ_INTERP_LEN return nil if obj_id[0] != OBJ_INTERP_CHAR || obj_id[-1] != OBJ_INTERP_CHAR @ipl_objs_map[obj_id[1...-1]] end
@private @param str [String]
# File lib/rubirai/messages/interpolation.rb, line 78 def _interpolate_with_objects(str) sb = +'' result = MessageChain.new(bot) i = 0 while i < str.length if i == str.length - 1 sb << str[i] break end if str[i] != OBJ_INTERP_CHAR sb << str[i] i += 1 next end if str[i + 1] == OBJ_INTERP_CHAR sb << OBJ_INTERP_CHAR i += 1 else result.append PlainMessage.from(text: sb) unless sb.empty? sb = str[i...i + OBJ_INTERP_LEN + 2] obj = _get_object(sb) i += OBJ_INTERP_LEN + 1 unless obj.nil? result.append obj sb = +'' end end i += 1 end result.append PlainMessage.from(text: sb) unless sb.nil? || sb.empty? result end
# File lib/rubirai/messages/interpolation.rb, line 61 def _transform_object(obj) obj_id = Utils.random_str(OBJ_INTERP_LEN) obj_id = Utils.random_str(OBJ_INTERP_LEN) while @ipl_objs_map.include?(obj_id) @ipl_objs_map[obj_id] = obj "#{OBJ_INTERP_CHAR}#{obj_id}#{OBJ_INTERP_CHAR}" end
# File lib/rubirai/messages/interpolation.rb, line 57 def _transform_plain_txt(str) str.gsub(OBJ_INTERP_CHAR, OBJ_INTERP_CHAR * 2) end
# File lib/rubirai/messages/message_chain.rb, line 122 def internal_append(msg) msg.must_be! [Message, MessageChain, Hash], RubiraiError, 'msg must be Message, MessageChain, or Hash' case msg when Message @messages.append msg when MessageChain @messages.append(*msg.messages) else @messages.append Message.build_from(msg, @bot) end self end