diff options
Diffstat (limited to '')
-rw-r--r-- | lib/irc.ex | 11 | ||||
-rw-r--r-- | lib/irc/puppet_connection.ex | 28 | ||||
-rw-r--r-- | lib/lsg/telegram.ex | 7 | ||||
-rw-r--r-- | lib/lsg/telegram_room.ex | 65 | ||||
-rw-r--r-- | lib/lsg_irc/say_plugin.ex | 3 | ||||
-rw-r--r-- | lib/lsg_irc/user_mention_plugin.ex | 3 |
6 files changed, 104 insertions, 13 deletions
@@ -15,6 +15,17 @@ defmodule IRC do defstruct [:type, :trigger, :args] end + def send_message_as(account, network, channel, text, force_puppet \\ false) do + connection = IRC.Connection.get_network(network) + if connection && (force_puppet || IRC.PuppetConnection.whereis(account, connection)) do + IRC.PuppetConnection.start_and_send_message(account, connection, channel, text) + else + user = IRC.UserTrack.find_by_account(network, account) + nick = if(user, do: user.nick, else: account.name) + IRC.Connection.broadcast_message(network, channel, "<#{nick}> #{text}") + end + end + def register(key) do case Registry.register(IRC.PubSub, key, []) do {:ok, _} -> :ok diff --git a/lib/irc/puppet_connection.ex b/lib/irc/puppet_connection.ex index 88b4f8a..68f1425 100644 --- a/lib/irc/puppet_connection.ex +++ b/lib/irc/puppet_connection.ex @@ -26,10 +26,28 @@ defmodule IRC.PuppetConnection do end end + def whereis(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}) do + {:global, name} = name(account_id, connection_id) + case :global.whereis_name(name) do + :undefined -> nil + pid -> pid + end + end + def send_message(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do - pid = case IRC.PuppetConnection.Supervisor.start_child(account, connection) do - {:ok, pid} -> pid - {:error, {:already_started, pid}} -> pid + GenServer.cast(name(account_id, connection_id), {:send_message, channel, text}) + end + + def start_and_send_message(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do + {:global, name} = name(account_id, connection_id) + pid = whereis(account, connection) + pid = if !pid do + case IRC.PuppetConnection.Supervisor.start_child(account, connection) do + {:ok, pid} -> pid + {:error, {:already_started, pid}} -> pid + end + else + pid end GenServer.cast(pid, {:send_message, channel, text}) end @@ -74,7 +92,7 @@ defmodule IRC.PuppetConnection do end def handle_continue(:connected, state) do - state = Enum.reduce(state.buffer, state, fn(b, state) -> + state = Enum.reduce(Enum.reverse(state.buffer), state, fn(b, state) -> {:noreply, state} = handle_cast(b, state) state end) @@ -105,7 +123,7 @@ defmodule IRC.PuppetConnection do end def handle_info(:idle, state) do - ExIRC.Client.quit(state.client, "Puppet is idle for too long") + ExIRC.Client.quit(state.client, "Puppet was idle for too long") ExIRC.Client.stop!(state.client) {:stop, :normal, state} end diff --git a/lib/lsg/telegram.ex b/lib/lsg/telegram.ex index e5790da..e8758e3 100644 --- a/lib/lsg/telegram.ex +++ b/lib/lsg/telegram.ex @@ -66,7 +66,6 @@ defmodule LSG.Telegram do {:ok, %{account: account.id}} end - #[debug] Unhandled update: %{"message" => # %{"chat" => %{"first_name" => "J", "id" => 2075406, "type" => "private", "username" => "ahref"}, # "date" => 1591096015, @@ -145,10 +144,8 @@ defmodule LSG.Telegram do do path = LSGWeb.Router.Helpers.url(LSGWeb.Endpoint) <> "/files/#{s3path}" sent = for {net, chan} <- target do - user = IRC.UserTrack.find_by_account(net, account) - nick = if(user, do: user.nick, else: account.name) - txt = "#{nick} sent#{type}#{text} #{path}" - IRC.Connection.broadcast_message(net, chan, txt) + txt = "sent#{type}#{text} #{path}" + IRC.send_message_as(account, net, chan, txt) "#{net}/#{chan}" end if caption = op["caption"], do: as_irc_message(chat_id, caption, account) diff --git a/lib/lsg/telegram_room.ex b/lib/lsg/telegram_room.ex index f973c58..9504cd4 100644 --- a/lib/lsg/telegram_room.ex +++ b/lib/lsg/telegram_room.ex @@ -23,10 +23,23 @@ defmodule LSG.TelegramRoom do def handle_update(%{"message" => %{"from" => %{"id" => user_id}, "text" => text}}, _token, state) do account = IRC.Account.find_meta_account("telegram-id", user_id) connection = IRC.Connection.get_network(state.net) - IRC.PuppetConnection.send_message(account, connection, state.chan, text) + IRC.send_message_as(account, state.net, state.chan, text, true) {:ok, state} end + def handle_update(data = %{"message" => %{"from" => %{"id" => user_id}, "location" => %{"latitude" => lat, "longitude" => lon}}}, _token, state) do + account = IRC.Account.find_meta_account("telegram-id", user_id) + connection = IRC.Connection.get_network(state.net) + IRC.send_message_as(account, state.net, state.chan, "@ #{lat}, #{lon}", true) + {:ok, state} + end + + for type <- ~w(photo voice video document animation) do + def handle_update(data = %{"message" => %{unquote(type) => _}}, token, state) do + upload(unquote(type), data, token, state) + end + end + def handle_update(update, token, state) do {:ok, state} end @@ -50,4 +63,54 @@ defmodule LSG.TelegramRoom do {:ok, state} end + defp upload(_type, %{"message" => m = %{"chat" => %{"id" => chat_id}, "from" => %{"id" => user_id}}}, token, state) do + account = IRC.Account.find_meta_account("telegram-id", user_id) + if account do + {content, type} = cond do + m["photo"] -> {m["photo"], "photo"} + m["voice"] -> {m["voice"], "voice message"} + m["video"] -> {m["video"], "video"} + m["document"] -> {m["document"], "file"} + m["animation"] -> {m["animation"], "gif"} + end + + file = if is_list(content) && Enum.count(content) > 1 do + Enum.sort_by(content, fn(p) -> p["file_size"] end, &>=/2) + |> List.first() + else + content + end + + file_id = file["file_id"] + file_unique_id = file["file_unique_id"] + text = if(m["caption"], do: m["caption"] <> " ", else: "") + + spawn(fn() -> + with \ + {:ok, file} <- Telegram.Api.request(token, "getFile", file_id: file_id), + path = "https://api.telegram.org/file/bot#{token}/#{file["file_path"]}", + {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- HTTPoison.get(path), + <<smol_body::binary-size(20), _::binary>> = body, + {:ok, magic} <- GenMagic.Pool.perform(LSG.GenMagic, {:bytes, smol_body}), + bucket = Application.get_env(:lsg, :s3, []) |> Keyword.get(:bucket), + ext = Path.extname(file["file_path"]), + s3path = "#{account.id}/#{file_unique_id}#{ext}", + s3req = ExAws.S3.put_object(bucket, s3path, body, acl: :public_read, content_type: magic.mime_type), + {:ok, _} <- ExAws.request(s3req) + do + path = LSGWeb.Router.Helpers.url(LSGWeb.Endpoint) <> "/files/#{s3path}" + txt = "#{type}: #{text}#{path}" + connection = IRC.Connection.get_network(state.net) + IRC.send_message_as(account, state.net, state.chan, txt, true) + else + error -> + Telegram.Api.request(token, "sendMessage", chat_id: chat_id, text: "File upload failed, sorry.") + Logger.error("Failed upload from Telegram: #{inspect error}") + end + end) + + {:ok, state} + end + end + end diff --git a/lib/lsg_irc/say_plugin.ex b/lib/lsg_irc/say_plugin.ex index c385e77..085ca92 100644 --- a/lib/lsg_irc/say_plugin.ex +++ b/lib/lsg_irc/say_plugin.ex @@ -62,8 +62,7 @@ defmodule LSG.IRC.SayPlugin do chan2 = String.replace(chan, "#", "") if (target == "#{net}/#{chan}" || target == "#{net}/#{chan2}" || target == chan || target == chan2) do if with_nick? do - connection = IRC.Connection.get_network(net) - IRC.PuppetConnection.send_message(account, connection, chan, text) + IRC.send_message_as(account, net, chan, text) else IRC.Connection.broadcast_message(net, chan, text) end diff --git a/lib/lsg_irc/user_mention_plugin.ex b/lib/lsg_irc/user_mention_plugin.ex index 5f7b10a..ca743c4 100644 --- a/lib/lsg_irc/user_mention_plugin.ex +++ b/lib/lsg_irc/user_mention_plugin.ex @@ -20,6 +20,9 @@ defmodule LSG.IRC.UserMentionPlugin do end def handle_info({:irc, :trigger, nick, message = %IRC.Message{sender: sender, account: account, network: network, channel: channel, trigger: %IRC.Trigger{type: :at, args: content}}}, state) do + nick = nick + |> String.trim(":") + |> String.trim(",") target = IRC.Account.find_always_by_nick(network, channel, nick) if target do telegram = IRC.Account.get_meta(target, "telegram-id") |