Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions lib/slacker/matcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,35 @@ defmodule Slacker.Matcher do

# some integrations don't provide a "text" field, ignore them
def handle_cast({:handle_incoming, "message", %{"text" => _} = msg}, state) do
match!(self, msg)
state = match!(self, msg, state)
{:noreply, state}
end
end
end

defmacro __before_compile__(_env) do
quote do
def match!(slacker, %{"text" => text} = msg) do
Enum.each(@regex_patterns, fn {pattern, [m, f]} ->
match = Regex.run(pattern, text)
if match do
[_text | captures] = match
:erlang.apply(m, f, [slacker, msg] ++ captures)
end
end)
def match!(slacker, %{"text" => text} = msg, state) do
case @strategy || :many do
:one ->
match = Enum.find(Enum.reverse(@regex_patterns), fn {pattern, [m, f]} ->
text =~ pattern
end)
if {pattern, [m, f]} = match do
[_text | captures] = Regex.run(pattern, text)
apply(m, f, [slacker, msg] ++ captures ++ [state])
end
:many ->
Enum.reduce(@regex_patterns, state, fn {pattern, [m, f]}, state ->
match = Regex.run(pattern, text)
if match do
[_text | captures] = match
:erlang.apply(m, f, [slacker, msg] ++ captures ++ [state])
else
state
end
end)
end
end
end
end
Expand All @@ -41,8 +54,8 @@ defmodule Slacker.Matcher do

quote do
if is_binary(unquote(pattern)) do
def match!(slacker, %{"text" => unquote(pattern)} = msg) do
:erlang.apply(unquote(m), unquote(f), [slacker, msg])
def match!(slacker, %{"text" => unquote(pattern)} = msg, state) do
:erlang.apply(unquote(m), unquote(f), [slacker, msg, state])
end
else
@regex_patterns {unquote(pattern), [unquote(m), unquote(f)]}
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
"poison": {:hex, :poison, "1.4.0"},
"ranch": {:hex, :ranch, "1.0.0"},
"ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.4"},
"websocket_client": {:git, "git://github.com/jeremyong/websocket_client.git", "f465f229958293949e4a192bea65a7e47bb2f762", []}}
"websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "f465f229958293949e4a192bea65a7e47bb2f762", []}}
16 changes: 8 additions & 8 deletions test/slacker/matcher_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,36 @@ defmodule Slacker.MatcherTest do
match ~r/say hi to robot #([0-9]+)/, :say_hello
match ~r/say bye to robot #([0-9]+)/, :say_goodbye

def say_hi(pid, msg) do
def say_hi(pid, msg, _state) do
send pid, "#{msg["text"]} there"
end

def say_hello(pid, msg) do
def say_hello(pid, msg, _state) do
send pid, "#{msg["text"]} again"
end

def say_hello(pid, _msg, robot_number) do
def say_hello(pid, _msg, robot_number, _state) do
send pid, "hello, robot #{robot_number}"
end

def say_goodbye(pid, _msg, robot_number) do
def say_goodbye(pid, _msg, robot_number, _state) do
send pid, "bye, robot #{robot_number}"
end
end

test "match!/2 matches strings" do
Test.match!(self, %{"text" => "hi"})
Test.match!(self, %{"text" => "hi"}, %{})
assert_receive "hi there"

Test.match!(self, %{"text" => "hello"})
Test.match!(self, %{"text" => "hello"}, %{})
assert_receive "hello again"
end

test "match!/3 matches regexes" do
Test.match!(self, %{"text" => "say hi to robot #123"})
Test.match!(self, %{"text" => "say hi to robot #123"}, %{})
assert_receive "hello, robot 123"

Test.match!(self, %{"text" => "say bye to robot #123"})
Test.match!(self, %{"text" => "say bye to robot #123"}, %{})
assert_receive "bye, robot 123"
end
end