Class: Message

Inherits:
Object
  • Object
show all
Includes:
SlackRubyBot::Loggable
Defined in:
src/models/message.rb

Overview

Describes and provides operations on a particular Slack message

This object is usually constructed by methods that operate on messages and message listeners such as SkillActions.listen_for and SlackMessageAbilities#say.

See https://api.slack.com/events/message for documentation of most fields.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#channel_idString (readonly)

Returns the channel id

Returns:

  • (String)

    the channel id



14
15
16
# File 'src/models/message.rb', line 14

def channel_id
  @channel_id
end

#tsString (readonly) Also known as: id

Returns the message id

Returns:

  • (String)

    the message id



17
18
19
# File 'src/models/message.rb', line 17

def ts
  @ts
end

#typeString (readonly)

Returns the message type, usually "message"

Returns:

  • (String)

    the message type, usually "message"



11
12
13
# File 'src/models/message.rb', line 11

def type
  @type
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Compare messages by ID (timestamp) and channel

Parameters:

  • other (Message)

    The other message to compare to.

Returns:

  • (Boolean)

    The comparison result.



97
98
99
# File 'src/models/message.rb', line 97

def ==(other)
  @channel_id == other.channel.id && @ts == other.ts
end

#channelChannel

Get the channel the message was sent on

Returns:



145
146
147
# File 'src/models/message.rb', line 145

def channel
  @_channel ||= Channel.new(@app, @channel_id)
end

#deletevoid

This method returns an undefined value.

Delete the message

The message sender must be Zayo, otherwise an exception will be thrown.



221
222
223
224
225
226
227
228
229
# File 'src/models/message.rb', line 221

def delete
  web_client.chat_delete(
    channel: channel.id,
    ts: @ts,
    as_user: true
  )

  logger.info "Deleted message '#{@ts}' in channel '#{@channel_id}'"
end

#direct_message?Boolean

Check if this is a direct message

Returns:

  • (Boolean)

See Also:



119
120
121
# File 'src/models/message.rb', line 119

def direct_message?
  channel.direct_message?
end

#duckling_dataDucklingService::Response

Request datetime parse of the message from Duckling



194
195
196
# File 'src/models/message.rb', line 194

def duckling_data
  @_duckling_data ||= @app.request_duckling_data(text_without_formatting)
end

#entitiesWitQueryService::WitData

Query Wit.ai for entities



186
187
188
# File 'src/models/message.rb', line 186

def entities
  @_entities ||= @app.request_wit_data(text_without_formatting)
end

#extracted_time(future: nil, past: nil) ⇒ Time?

Request a single datetime parse of the message from Duckling

If multiple datetimes are found, clarifies with the user which one should be chosen before returning a value.

Parameters:

  • future (Boolean)

    Are only future dates allowed?

  • past (Boolean)

    Are only past dates allowed?

Returns:

  • (Time, nil)


206
207
208
209
210
211
212
213
214
# File 'src/models/message.rb', line 206

def extracted_time(future: nil, past: nil)
  options = duckling_data.time.options

  if options.empty?
    nil
  else
    TimeClarificationInteraction.new(options, future: future, past: past).clarify
  end
end

#in_thread?Boolean

Is the message in a thread?

Returns true for thread starters as well.

Returns:

  • (Boolean)


56
57
58
59
60
# File 'src/models/message.rb', line 56

def in_thread?
  load_message_data if @need_more_data

  !!@thread_ts
end

#react_with(reaction) ⇒ Boolean

React on the message

If the bot has already reacted to this message, does nothing and returns false.

Parameters:

  • reaction (String)

    The name of the reaction with or without :.

Returns:

  • (Boolean)

    true if a new reaction was added, false if it was already present.



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'src/models/message.rb', line 237

def react_with(reaction)
  reaction = reaction.to_s.gsub(/\:/, '')

  @app.client.web_client.reactions_add(
    name: reaction,
    channel: @channel_id,
    timestamp: @ts,
    as_user: true
  )
  logger.info "Reacted with ':#{reaction.to_s}:' to '#{@ts}' in channel '#{@channel_id}'"

  true
rescue Slack::Web::Api::Errors::SlackError => error
  if error.message == 'already_reacted'
    logger.info "Already reacted with ':#{reaction.to_s}:' to '#{@ts}' in channel '#{@channel_id}'"

    false
  else
    raise
  end
end

#reactionsArray<Reaction>

Get all reactions for this message

This makes a call to the Slack API each time it is called. Make sure to assign the result to a variable if used multiple times.

Returns:

  • (Array<Reaction>)

    The list of reactions



129
130
131
132
133
134
135
136
137
138
139
140
# File 'src/models/message.rb', line 129

def reactions
  response = web_client.reactions_get(
    channel: @channel_id,
    timestamp: @ts,
    full: true
  )
  reactions = response.message.reactions

  return [] unless reactions

  reactions.map { |reaction| Reaction.new(@app, reaction.name, reaction.count, reaction.users) }
end

#sent_by_me?Boolean

Is this message sent from the bot user?

Returns:

  • (Boolean)


111
112
113
# File 'src/models/message.rb', line 111

def sent_by_me?
  @user_id == @app.user_id
end

#textString

Returns The text of the message.

Returns:

  • (String)

    The text of the message.



45
46
47
48
49
# File 'src/models/message.rb', line 45

def text
  load_message_data if @need_more_data

  @text
end

#text_without_formattingString

Get the message text without any formatting

Returns:

  • (String)


173
174
175
176
177
178
179
180
181
# File 'src/models/message.rb', line 173

def text_without_formatting
  @_text_without_formatting ||=
    Slack::Messages::Formatting.unescape(text_without_mention)
      .gsub("\n", ' ')
      .gsub(/\A[\s\t,\.!?]+|[\s\t,\.!?]+\z/, '')
      .gsub(/\:[a-z0-9\-\_\+]+:/i, '')
      .gsub(/\:\+1\:/, 'да')
      .gsub(/\:\-1\:/, 'не')
end

#text_without_mentionString

Get the message text without any mentions or greetings

Returns:

  • (String)


161
162
163
164
165
166
167
168
# File 'src/models/message.rb', line 161

def text_without_mention
  @_text_without_mention ||= begin
    aliases = ENV.fetch('ALIASES', 'zayo').split(',')
    alias_regex = /^((ой|ехо|ей|хей|йо|yo|hi|hey)[,\s]+)?(<@#{@app.user_id}>|#{aliases.join('|')})[:,\s]*|<@#{@app.user_id}>/i

    text.sub(alias_regex, '')
  end
end

#threadMessageThread

Returns:



63
64
65
66
67
# File 'src/models/message.rb', line 63

def thread
  load_message_data if @need_more_data

  @_thread ||= MessageThread.new(@app, @thread_ts || @ts)
end

#userUser

Get the user the message was sent by

Returns:



152
153
154
155
156
# File 'src/models/message.rb', line 152

def user
  load_message_data if !@user_id && @need_more_data

  @_user ||= User.new(@app, @user_id)
end