Class: WeChat::Bot::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/wechat/bot/message.rb

Overview

微信消息

Defined Under Namespace

Modules: Kind

Constant Summary collapse

GROUP_MESSAGE_REGEX =
/^(@\w+):<br\/>(.*)$/
AT_MESSAGE_REGEX =
/@([^\s]+) (.*)/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw, bot) ⇒ Message

Returns a new instance of Message.



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/wechat/bot/message.rb', line 61

def initialize(raw, bot)
  @raw = raw
  @bot = bot

  @events  = []
  @time    = Time.now
  @statusmsg_mode = nil

  parse

  @bot.logger.verbose "Message Raw: #{@raw}"
end

Instance Attribute Details

#botCore (readonly)

Returns:



34
35
36
# File 'lib/wechat/bot/message.rb', line 34

def bot
  @bot
end

#eventsArray<Symbol> (readonly)

事件列表

Returns:

  • (Array<Symbol>)


31
32
33
# File 'lib/wechat/bot/message.rb', line 31

def events
  @events
end

#fromContact (readonly)

消息发送者

用户或者群组

Returns:



51
52
53
# File 'lib/wechat/bot/message.rb', line 51

def from
  @from
end

#kindMessage::Kind (readonly)

消息类型

Returns:



41
42
43
# File 'lib/wechat/bot/message.rb', line 41

def kind
  @kind
end

#media_idObject (readonly)

Returns the value of attribute media_id.



57
58
59
# File 'lib/wechat/bot/message.rb', line 57

def media_id
  @media_id
end

#messageString (readonly)

消息正文

Returns:



55
56
57
# File 'lib/wechat/bot/message.rb', line 55

def message
  @message
end

#meta_dataObject (readonly)

Returns the value of attribute meta_data.



59
60
61
# File 'lib/wechat/bot/message.rb', line 59

def 
  @meta_data
end

#rawHash<Object, Object> (readonly)

原始消息

Returns:

  • (Hash<Object, Object>)


27
28
29
# File 'lib/wechat/bot/message.rb', line 27

def raw
  @raw
end

#sourceContact::Kind (readonly)

消息来源

Returns:



45
46
47
# File 'lib/wechat/bot/message.rb', line 45

def source
  @source
end

#timeTime (readonly)

Returns:

  • (Time)


37
38
39
# File 'lib/wechat/bot/message.rb', line 37

def time
  @time
end

Instance Method Details

#at_message(message) ⇒ String

尝试解析群聊中的 @ 消息

群消息格式:

@ToNickNameUserName Message

Parameters:

  • message (String)

    原始消息

Returns:

  • (String)

    文本消息,如果不是 @ 消息返回原始消息



274
275
276
277
278
279
280
# File 'lib/wechat/bot/message.rb', line 274

def at_message(message)
  if match = AT_MESSAGE_REGEX.match(message)
    return match[2].strip
  end

  message
end

#at_message?Boolean

Returns:

  • (Boolean)


140
141
142
# File 'lib/wechat/bot/message.rb', line 140

def at_message?
  @at_mesage == true
end

#group_message(message) ⇒ Array<Object>

解析用户的群消息

群消息格式:

@FromUserName:<br>Message

Parameters:

  • message (String)

    原始消息

Returns:

  • (Array<Object>)

    返回两个值的数组

    • 0 from_username

    • 1 message



259
260
261
262
263
264
265
# File 'lib/wechat/bot/message.rb', line 259

def group_message(message)
  if match = GROUP_MESSAGE_REGEX.match(message)
    return [match[1], at_message(match[2])]
  end

  false
end

#match(regexp, type) ⇒ MatchData

消息匹配

Parameters:

Returns:

  • (MatchData)

    匹配结果



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/wechat/bot/message.rb', line 121

def match(regexp, type)
  # text = ""
  # case type
  # when :ctcp
  #   text = ctcp_message
  # when :action
  #   text = action_message
  # else
  #   text = message.to_s
  #   type = :other
  # end

  # if strip_colors
  #   text = Cinch::Formatting.unformat(text)
  # end

  @message.match(regexp)
end

#parsevoid

This method returns an undefined value.

解析微信消息



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/wechat/bot/message.rb', line 92

def parse
  parse_source
  parse_kind

  message = @raw["Content"].convert_emoji
  message = CGI.unescape_html(message) if @kinde != Message::Kind::Text
  if match = group_message(message)
    # from_username = match[0]
    message = match[1]
  end

  @message = message
  # TODO: 来自于特殊账户无法获取联系人信息,需要单独处理
  @from = @bot.contact_list.find(username: @raw["FromUserName"])
  parse_emoticon if @kind == Message::Kind::Emoticon

  case @kind
  when Message::Kind::ShareCard
    @meta_data = MessageData::ShareCard.parse(@message)
  end

  parse_events
end

#parse_emoticonvoid

This method returns an undefined value.

解析表情

表情分为两种:

1. 微信商店表情
1. 自定义表情


234
235
236
237
238
239
240
241
242
243
# File 'lib/wechat/bot/message.rb', line 234

def parse_emoticon
  if @message.empty?
    @media_id = @raw["MediaId"]
    # TODO: 解决微信商店表情
    # file = @bot.client.download_image(@raw["NewMsgId"])
  else
    data = MultiXml.parse(@message)
    @media_id = data["msg"]["emoji"]["md5"]
  end
end

#parse_eventsvoid

This method returns an undefined value.

解析 Handler 的事件

- `:message` 用户消息
  - `:text` 文本消息
  - `:image` 图片消息
  - `:voice` 语音消息
  - `:short_video` 短视频消息
- `:group` 群聊消息
  - `:at_message` @ 消息


215
216
217
218
219
220
221
222
223
224
225
# File 'lib/wechat/bot/message.rb', line 215

def parse_events
  @events << :message
  @events << @kind
  @events << @source

  @at_mesage = false
  if @source == :group && @raw["Content"] =~ /@([^\s]+)\s+(.*)/
    @events << :at_message
    @at_mesage = true
  end
end

#parse_kindvoid

This method returns an undefined value.

解析消息类型

- 1: Text 文本消息
- 3: Image 图片消息
- 34: Voice 语言消息
- 37: 验证消息
- 42: BusinessCard 名片消息
- 47: Emoticon 微信表情
- 49: ShareCard 分享链接消息
- 62: ShortVideo 短视频消息
- 1000: System 系统消息
- Unkown 未知消息


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/wechat/bot/message.rb', line 179

def parse_kind
  @kind = case @raw["MsgType"]
          when 1
            Message::Kind::Text
          when 3
            Message::Kind::Image
          when 34
            Message::Kind::Voice
          when 37
            Message::Kind::Verify
          when 42
            Message::Kind::BusinessCard
          when 62
            Message::Kind::ShortVideo
          when 47
            Message::Kind::Emoticon
          when 49
            Message::Kind::ShareCard
          when 10000
            Message::Kind::System
          else
            Message::Kind::Unkown
          end
end

#parse_shareObject



245
246
247
248
# File 'lib/wechat/bot/message.rb', line 245

def parse_share
  # TODO: 完成解析
  data = MultiXml.parse(@message)
end

#parse_sourcevoid

This method returns an undefined value.

解析消息来源

特殊账户/群聊/公众号/用户



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/wechat/bot/message.rb', line 149

def parse_source
  @source = if @bot.config.special_users.include?(@raw["FromUserName"])
              # 特殊账户
              Contact::Kind::Special
            elsif @raw["FromUserName"].include?("@@")
              # 群聊
              Contact::Kind::Group
            elsif (@raw["RecommendInfo"]["VerifyFlag"] & 8) != 0
              # 公众号
              Contact::Kind::MP
            else
              # 普通用户
              Contact::Kind::User
            end
end

#reply(text, **args) ⇒ Object

回复消息



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/wechat/bot/message.rb', line 75

def reply(text, **args)
  to_user = args[:username] || @from.username
  to_user = @bot.contact_list.find(nickname: args[:nickname]) if args[:nickname]

  message_type = args[:type] || :text

  # if @bot.config.special_users.include?(to_user) && to_user != 'filehelper'
  #   @bot.logger.error "特殊账户无法回复: #{to_user}"
  #   raise NoReplyException, "特殊账户无法回复: #{to_user}"
  # end

  @bot.client.send(message_type, to_user, text)
end