Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Reply in thread #145

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion lib/lita-slack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
File.join("..", "..", "locales", "*.yml"), __FILE__
)]

require "lita/adapters/slack"
require_relative "lita/source"
require_relative "lita/adapters/slack"
18 changes: 7 additions & 11 deletions lib/lita/adapters/slack.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'lita/adapters/slack/chat_service'
require 'lita/adapters/slack/rtm_connection'
require_relative 'slack/chat_service'
require_relative 'slack/rtm_connection'

module Lita
module Adapters
Expand Down Expand Up @@ -40,7 +40,11 @@ def roster(target)

def send_messages(target, strings)
api = API.new(config)
api.send_messages(channel_for(target), strings)
if target.respond_to?(:thread)
api.send_messages(target.room || target.user&.id, strings, thread_ts: target.thread)
else
api.send_messages(target.room || target.user&.id, strings)
end
end

def set_topic(target, topic)
Expand All @@ -60,14 +64,6 @@ def shut_down

attr_reader :rtm_connection

def channel_for(target)
if target.private_message?
rtm_connection.im_for(target.user.id)
else
target.room
end
end

def channel_roster(room_id, api)
response = api.channels_info room_id
response['channel']['members']
Expand Down
34 changes: 18 additions & 16 deletions lib/lita/adapters/slack/api.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require 'faraday'

require 'lita/adapters/slack/team_data'
require 'lita/adapters/slack/slack_im'
require 'lita/adapters/slack/slack_user'
require 'lita/adapters/slack/slack_channel'
require_relative 'team_data'
require_relative 'slack_im'
require_relative 'slack_user'
require_relative 'slack_channel'

module Lita
module Adapters
Expand Down Expand Up @@ -55,29 +55,31 @@ def send_attachments(room_or_user, attachments)
)
end

def send_messages(channel_id, messages)
call_api(
"chat.postMessage",
**post_message_config,
as_user: true,
def send_messages(channel_id, messages, additional_payload = {})
data = {
channel: channel_id,
as_user: true,
text: messages.join("\n"),
)
}.merge(post_message_config)
.merge(additional_payload)

call_api( "chat.postMessage", **data )
end

def set_topic(channel, topic)
call_api("channels.setTopic", channel: channel, topic: topic)
end

def rtm_start
response_data = call_api("rtm.start")
def rtm_connect
response_data = call_api("rtm.connect")

raise RuntimeError, response_data["error"] if response_data["ok"] != true

TeamData.new(
SlackIM.from_data_array(response_data["ims"]),
response_data["team"]["id"],
response_data["team"]["name"],
response_data["team"]["domain"],
SlackUser.from_data(response_data["self"]),
SlackUser.from_data_array(response_data["users"]),
SlackChannel.from_data_array(response_data["channels"]) +
SlackChannel.from_data_array(response_data["groups"]),
response_data["url"],
)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/lita/adapters/slack/chat_service.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require "lita/adapters/slack/attachment"
require_relative "attachment"

module Lita
module Adapters
Expand Down
6 changes: 5 additions & 1 deletion lib/lita/adapters/slack/message_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,13 @@ def channel
data["channel"]
end

def thread
data["thread_ts"]
end

def dispatch_message(user)
room = Lita::Room.find_by_id(channel)
source = Source.new(user: user, room: room || channel)
source = Source.new(user: user, room: room || channel, thread: thread)
source.private_message! if channel && channel[0] == "D"
message = Message.new(robot, body, source)
message.command! if source.private_message?
Expand Down
22 changes: 7 additions & 15 deletions lib/lita/adapters/slack/rtm_connection.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
require 'faye/websocket'
require 'multi_json'

require 'lita/adapters/slack/api'
require 'lita/adapters/slack/event_loop'
require 'lita/adapters/slack/im_mapping'
require 'lita/adapters/slack/message_handler'
require 'lita/adapters/slack/room_creator'
require 'lita/adapters/slack/user_creator'
require_relative 'api'
require_relative 'event_loop'
require_relative 'im_mapping'
require_relative 'message_handler'
require_relative 'room_creator'
require_relative 'user_creator'

module Lita
module Adapters
Expand All @@ -17,23 +17,15 @@ class RTMConnection

class << self
def build(robot, config)
new(robot, config, API.new(config).rtm_start)
new(robot, config, API.new(config).rtm_connect)
end
end

def initialize(robot, config, team_data)
@robot = robot
@config = config
@im_mapping = IMMapping.new(API.new(config), team_data.ims)
@websocket_url = team_data.websocket_url
@robot_id = team_data.self.id

UserCreator.create_users(team_data.users, robot, robot_id)
RoomCreator.create_rooms(team_data.channels, robot)
end

def im_for(user_id)
im_mapping.im_for(user_id)
end

def run(queue = nil, options = {})
Expand Down
2 changes: 1 addition & 1 deletion lib/lita/adapters/slack/team_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Lita
module Adapters
# @api private
class Slack < Adapter
TeamData = Struct.new(:ims, :self, :users, :channels, :websocket_url)
TeamData = Struct.new(:id, :name, :domain, :self, :websocket_url)
end
end
end
35 changes: 35 additions & 0 deletions lib/lita/source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Lita
class Source

# The room the message came from or should be sent to, as a string.
# @return [String, NilClass] A string uniquely identifying the room.
attr_reader :thread

# @param user [Lita::User] The user who sent the message or should receive
# the outgoing message.
# @param room [Lita::Room, String] A string or {Lita::Room} uniquely identifying the room
# the user sent the message from, or the room where a reply should go. The format of this
# string (or the ID of the {Lita::Room} object) will differ depending on the chat service.
# @param private_message [Boolean] A flag indicating whether or not the
# message was sent privately.
def initialize(user: nil, room: nil, thread: nil, private_message: false)
@user = user
@thread = thread

case room
when String
@room = room
@room_object = Room.new(room)
when Room
@room = room.id
@room_object = room
end

@private_message = private_message

raise ArgumentError, I18n.t("lita.source.user_or_room_required") if user.nil? && room.nil?

@private_message = true if room.nil?
end
end
end
2 changes: 1 addition & 1 deletion lita-slack.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency "lita", ">= 4.7.1"
spec.add_runtime_dependency "multi_json"

spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "bundler"
spec.add_development_dependency "pry-byebug"
spec.add_development_dependency "rack-test"
spec.add_development_dependency "rake"
Expand Down
25 changes: 5 additions & 20 deletions spec/lita/adapters/slack/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -637,11 +637,11 @@ def stubs(postMessage_options = {})
end
end

describe "#rtm_start" do
describe "#rtm_connect" do
let(:http_status) { 200 }
let(:stubs) do
Faraday::Adapter::Test::Stubs.new do |stub|
stub.post('https://slack.com/api/rtm.start', token: token) do
stub.post('https://slack.com/api/rtm.connect', token: token) do
[http_status, {}, http_response]
end
end
Expand All @@ -652,34 +652,19 @@ def stubs(postMessage_options = {})
MultiJson.dump({
ok: true,
url: 'wss://example.com/',
users: [{ id: 'U023BECGF' }],
ims: [{ id: 'D024BFF1M' }],
self: { id: 'U12345678' },
channels: [{ id: 'C1234567890' }],
groups: [{ id: 'G0987654321' }],
team: { id: 'T0987654321' },
})
end

it "has data on the bot user" do
response = subject.rtm_start
response = subject.rtm_connect

expect(response.self.id).to eq('U12345678')
end

it "has an array of IMs" do
response = subject.rtm_start

expect(response.ims[0].id).to eq('D024BFF1M')
end

it "has an array of users" do
response = subject.rtm_start

expect(response.users[0].id).to eq('U023BECGF')
end

it "has a WebSocket URL" do
response = subject.rtm_start
response = subject.rtm_connect

expect(response.websocket_url).to eq('wss://example.com/')
end
Expand Down
35 changes: 33 additions & 2 deletions spec/lita/adapters/slack/message_handler_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
require "spec_helper"
# require_relative '../../../../lib/lita/adapters/slack/slack_source'

describe Lita::Adapters::Slack::MessageHandler, lita: true do
subject { described_class.new(robot, robot_id, data) }

before do
allow(robot).to receive(:trigger)
allow(robot).to receive(:alias)
allow(robot).to receive(:receive)
Lita::Adapters::Slack::RoomCreator.create_room(channel, robot)
end

Expand Down Expand Up @@ -44,7 +47,8 @@
allow(Lita::Room).to receive(:find_by_id).and_return(room)
allow(Lita::Source).to receive(:new).with(
user: user,
room: room
room: room,
thread: nil,
).and_return(source)
allow(Lita::Message).to receive(:new).with(robot, "Hello", source).and_return(message)
allow(robot).to receive(:receive).with(message)
Expand Down Expand Up @@ -74,7 +78,8 @@
allow(Lita::Room).to receive(:find_by_id).and_return(nil)
allow(Lita::Source).to receive(:new).with(
user: user,
room: "D2147483705"
room: "D2147483705",
thread: nil,
).and_return(source)
allow(source).to receive(:private_message!).and_return(true)
allow(source).to receive(:private_message?).and_return(true)
Expand Down Expand Up @@ -156,6 +161,32 @@
end
end

context "when the message is in a thread" do
let(:data) do
{
"type" => "message",
"channel" => "C2147483705",
"user" => "U023BECGF",
"text" => "Hello",
"ts" => "1234.5678",
"thread_ts" => "1234.5678",
}
end
let(:source) { instance_double('Lita::Source', room: room, private_message?: false) }

before do
allow(Lita::Source).to receive(:new).with(
user: user,
room: room,
thread: "1234.5678",
).and_return(source)
end

it "records the room thread" do
subject.handle
end
end

describe "Removing message formatting" do

let(:user) { instance_double('Lita::User', id: 'U123',name: 'name', mention_name: 'label') }
Expand Down
Loading