diff options
author | Jordan Bracco <href@random.sh> | 2022-12-20 02:19:42 +0000 |
---|---|---|
committer | Jordan Bracco <href@random.sh> | 2022-12-20 19:29:41 +0100 |
commit | 9958e90eb5eb5a2cc171c40860745e95a96bd429 (patch) | |
tree | b49cdb1d0041b9c0a81a14950d38c0203896f527 /lib/nola_telegram/room.ex | |
parent | Rename to Nola (diff) |
Actually do not prefix folders with nola_ refs T77
Diffstat (limited to 'lib/nola_telegram/room.ex')
-rw-r--r-- | lib/nola_telegram/room.ex | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/lib/nola_telegram/room.ex b/lib/nola_telegram/room.ex deleted file mode 100644 index ca8a437..0000000 --- a/lib/nola_telegram/room.ex +++ /dev/null @@ -1,188 +0,0 @@ -defmodule Nola.TelegramRoom do - require Logger - @behaviour Telegram.ChatBot - alias Telegram.Api - - @couch "bot-telegram-rooms" - - def rooms(), do: rooms(:with_docs) - - @spec rooms(:with_docs | :ids) :: [Map.t | integer( )] - def rooms(:with_docs) do - case Couch.get(@couch, :all_docs, include_docs: true) do - {:ok, %{"rows" => rows}} -> {:ok, for(%{"doc" => doc} <- rows, do: doc)} - error = {:error, _} -> error - end - end - - def rooms(:ids) do - case Couch.get(@couch, :all_docs) do - {:ok, %{"rows" => rows}} -> {:ok, for(%{"id" => id} <- rows, do: id)} - error = {:error, _} -> error - end - end - - def room(id, opts \\ []) do - Couch.get(@couch, id, opts) - end - - # TODO: Create couch - def setup() do - :ok - end - - def after_start() do - for id <- room(:ids), do: Telegram.Bot.ChatBot.Chat.Session.Supervisor.start_child(Nola.Telegram, Integer.parse(id) |> elem(0)) - end - - @impl Telegram.ChatBot - def init(id) when is_integer(id) and id < 0 do - token = Keyword.get(Application.get_env(:nola, :telegram, []), :key) - {:ok, chat} = Api.request(token, "getChat", chat_id: id) - Logger.metadata(transport: :telegram, id: id, telegram_room_id: id) - tg_room = case room(id) do - {:ok, tg_room = %{"network" => _net, "channel" => _chan}} -> tg_room - {:error, :not_found} -> - [net, chan] = String.split(chat["title"], "/", parts: 2) - {net, chan} = case IRC.Connection.get_network(net, chan) do - %IRC.Connection{} -> {net, chan} - _ -> {nil, nil} - end - {:ok, _id, _rev} = Couch.post(@couch, %{"_id" => id, "network" => net, "channel" => nil}) - {:ok, tg_room} = room(id) - tg_room - end - %{"network" => net, "channel" => chan} = tg_room - Logger.info("Starting ChatBot for room #{id} \"#{chat["title"]}\" #{inspect tg_room}") - irc_plumbed = if net && chan do - {:ok, _} = Registry.register(IRC.PubSub, "#{net}/#{chan}:messages", plugin: __MODULE__) - {:ok, _} = Registry.register(IRC.PubSub, "#{net}/#{chan}:triggers", plugin: __MODULE__) - {:ok, _} = Registry.register(IRC.PubSub, "#{net}/#{chan}:outputs", plugin: __MODULE__) - true - else - Logger.warn("Did not found telegram match for #{id} \"#{chat["title"]}\"") - false - end - {:ok, %{id: id, net: net, chan: chan, irc: irc_plumbed}} - end - - def init(id) do - Logger.error("telegram_room: bad id (not room id)", transport: :telegram, id: id, telegram_room_id: id) - :ignoree - end - - defp find_or_create_meta_account(from = %{"id" => user_id}, state) do - if account = IRC.Account.find_meta_account("telegram-id", user_id) do - account - else - first_name = Map.get(from, "first_name") - last_name = Map.get(from, "last_name") - name = [first_name, last_name] - |> Enum.filter(& &1) - |> Enum.join(" ") - - username = Map.get(from, "username", first_name) - - account = username - |> IRC.Account.new_account() - |> IRC.Account.update_account_name(name) - |> IRC.Account.put_meta("telegram-id", user_id) - - Logger.info("telegram_room: created account #{account.id} for telegram user #{user_id}") - account - end - end - - def handle_update(%{"message" => %{"from" => from = %{"id" => user_id}, "text" => text}}, _token, state) do - account = find_or_create_meta_account(from, state) - connection = IRC.Connection.get_network(state.net) - IRC.send_message_as(account, state.net, state.chan, text, true) - {:ok, state} - end - - def handle_update(data = %{"message" => %{"from" => from = %{"id" => user_id}, "location" => %{"latitude" => lat, "longitude" => lon}}}, _token, state) do - account = find_or_create_meta_account(from, state) - 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 - - def handle_info({:irc, _, _, message}, state) do - handle_info({:irc, nil, message}, state) - end - - def handle_info({:irc, _, message = %IRC.Message{sender: %{nick: nick}, text: text}}, state) do - if Map.get(message.meta, :from) == self() do - else - body = if Map.get(message.meta, :self), do: text, else: "<#{nick}> #{text}" - Nola.Telegram.send_message(state.id, body) - end - {:ok, state} - end - - def handle_info(info, state) do - Logger.info("UNhandled #{inspect info}") - {:ok, state} - end - - defp upload(_type, %{"message" => m = %{"chat" => %{"id" => chat_id}, "from" => from = %{"id" => user_id}}}, token, state) do - account = find_or_create_meta_account(from, state) - 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(Nola.GenMagic, {:bytes, smol_body}), - bucket = Application.get_env(:nola, :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 = NolaWeb.Router.Helpers.url(NolaWeb.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 |