Skip to content

Commit 2fbc5ed

Browse files
authored
Merge pull request #1414 from operable/nmohoric/chat_service
Chat service POC
2 parents 5545203 + aaf29df commit 2fbc5ed

File tree

6 files changed

+127
-2
lines changed

6 files changed

+127
-2
lines changed

lib/cog/command/service/chat.ex

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
defmodule Cog.Command.Service.Chat do
2+
require Logger
3+
4+
alias Cog.Chat.Adapter
5+
6+
def send_message(destination, message) do
7+
{:ok, provider} = Cog.Util.Misc.chat_provider_module
8+
9+
case build_target(provider, destination) do
10+
{:ok, target} ->
11+
Cog.Chat.Adapter.send(provider, target, message, %{originating_room_id: target.id})
12+
{:error, reason} ->
13+
Logger.debug("Invalid message destination: #{inspect destination}")
14+
{:error, reason}
15+
end
16+
end
17+
18+
defp build_target(provider, "@" <> handle) do
19+
case Adapter.lookup_user(provider, handle) do
20+
{:ok, %{id: user_id}} ->
21+
{:ok, %{provider: provider, id: user_id, name: handle, is_dm: true}}
22+
_ ->
23+
{:error, :unknown_handle}
24+
end
25+
end
26+
defp build_target(provider, "#" <> room) do
27+
case Adapter.lookup_room(provider, name: "##{room}") do
28+
{:ok, %{id: room_id}} ->
29+
{:ok, %{provider: provider, id: room_id, name: room, is_dm: false}}
30+
_ ->
31+
{:error, :unknown_room}
32+
end
33+
end
34+
defp build_target(_provider, _destination) do
35+
{:error, :invalid_destination}
36+
end
37+
38+
end

lib/cog/repository/services.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ defmodule Cog.Repository.Services do
1212
# TODO: Eventually, we'll want to introspect the system for this
1313
# information. For now, though, this will be effectively duplicating
1414
# information contained in the service router.
15-
[%{name: "memory",
16-
version: "1.0.0"}]
15+
[
16+
%{name: "memory", version: "1.0.0"},
17+
%{name: "chat", version: "1.0.0"}
18+
]
1719
end
1820

1921
def deployed(name),
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
defmodule Cog.V1.ChatServiceControllerTest do
2+
use Cog.ConnCase
3+
4+
@moduletag :services
5+
@endpoint Cog.ServiceEndpoint
6+
7+
@path "/v1/services/chat/1.0.0"
8+
9+
alias Cog.Command.Service.Tokens
10+
11+
setup do
12+
# This makes the test process look like a pipeline executor,
13+
# because the token will be registered to it.
14+
token = Tokens.new
15+
conn = tokened_connection(token)
16+
{:ok, [conn: conn]}
17+
end
18+
19+
defp tokened_connection(token) do
20+
build_conn()
21+
|> Plug.Conn.put_req_header("content-type", "application/json")
22+
|> Plug.Conn.put_req_header("authorization", "pipeline #{token}")
23+
end
24+
25+
test "requests without a token are denied" do
26+
conn = post(build_conn(), @path <> "/send_message")
27+
assert response(conn, 401)
28+
end
29+
30+
test "sending message to an unknown user is an error", %{conn: conn} do
31+
conn = post(conn, @path <> "/send_message", Poison.encode!(%{destination: "@fake_user", message: "taco"}))
32+
assert %{"error" => "Unable to find chat user for @fake_user"} == json_response(conn, 404)
33+
end
34+
35+
test "sending message to an unknown room is an error", %{conn: conn} do
36+
conn = post(conn, @path <> "/send_message", Poison.encode!(%{destination: "#fake_room", message: "taco"}))
37+
assert %{"error" => "Unable to find chat room for #fake_room"} == json_response(conn, 404)
38+
end
39+
40+
test "sending message to an invalid destination is an error", %{conn: conn} do
41+
conn = post(conn, @path <> "/send_message", Poison.encode!(%{destination: "definitely_fake", message: "taco"}))
42+
assert %{"error" => "Invalid chat destination URI definitely_fake"} == json_response(conn, 404)
43+
end
44+
45+
test "sending message to a good message results in a success", %{conn: conn} do
46+
conn = post(conn, @path <> "/send_message", Poison.encode!(%{destination: "#ci_bot_testing", message: "taco"}))
47+
assert %{"status" => "sent"} == json_response(conn, 200)
48+
end
49+
50+
end

test/support/test_provider.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defmodule Cog.Chat.Test.Provider do
2828
provider: @provider_name,
2929
email: handle}
3030
end
31+
def lookup_user("fake_user"), do: {:error, :unknown_user}
3132
def lookup_user(handle) do
3233
%Cog.Chat.User{id: handle,
3334
first_name: handle,
@@ -49,6 +50,7 @@ defmodule Cog.Chat.Test.Provider do
4950
provider: @provider_name,
5051
is_dm: false}
5152
end
53+
def lookup_room({:name, "#fake_room"}), do: {:error, :unknown_room}
5254
def lookup_room({:name, name}) do
5355
%Cog.Chat.Room{id: name,
5456
name: name,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
defmodule Cog.V1.ChatServiceController do
2+
use Cog.Web, :controller
3+
require Logger
4+
5+
plug Cog.Plug.ServiceAuthentication
6+
7+
alias Cog.Command.Service.Chat
8+
9+
def send_message(conn, %{"destination" => destination, "message" => message}) do
10+
case Chat.send_message(destination, message) do
11+
{:error, reason} when reason == :unknown_handle or reason == :unknown_room or reason == :invalid_destination ->
12+
conn
13+
|> put_status(:not_found)
14+
|> json(%{"error" => destination_error(destination, reason)})
15+
_ ->
16+
conn
17+
|> put_status(:ok)
18+
|> json(%{"status": "sent"})
19+
end
20+
end
21+
22+
defp destination_error(destination, :unknown_handle) do
23+
"Unable to find chat user for #{destination}"
24+
end
25+
defp destination_error(destination, :unknown_room) do
26+
"Unable to find chat room for #{destination}"
27+
end
28+
defp destination_error(destination, _reason) do
29+
"Invalid chat destination URI #{destination}"
30+
end
31+
32+
end

web/service_router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ defmodule Cog.ServiceRouter do
1717
put "/memory/1.0.0/:key", V1.MemoryServiceController, :update
1818
post "/memory/1.0.0/:key", V1.MemoryServiceController, :change
1919

20+
post "/chat/1.0.0/send_message", V1.ChatServiceController, :send_message
2021
end
2122
end

0 commit comments

Comments
 (0)