diff options
-rw-r--r-- | lib/lsg/telegram.ex | 68 | ||||
-rw-r--r-- | lib/lsg_irc/tell_plugin.ex | 55 | ||||
-rw-r--r-- | lib/lsg_irc/user_mention_plugin.ex | 49 |
3 files changed, 101 insertions, 71 deletions
diff --git a/lib/lsg/telegram.ex b/lib/lsg/telegram.ex index 02d7115..747f272 100644 --- a/lib/lsg/telegram.ex +++ b/lib/lsg/telegram.ex @@ -11,6 +11,7 @@ defmodule LSG.Telegram do end def init() do + Logger.info("Telegram starting") # Create users in track: IRC.UserTrack.connected(...) :ok end @@ -79,24 +80,6 @@ defmodule LSG.Telegram do start_upload(token, "animation", data) end - def start_upload(token, _, %{"message" => m = %{"chat" => %{"id" => id, "type" => "private"}}}) do - account = IRC.Account.find_meta_account("telegram-id", id) - if account do - text = if(m["text"], do: m["text"], else: nil) - targets = IRC.Membership.of_account(account) - |> Enum.map(fn({net, chan}) -> "#{net}/#{chan}" end) - |> Enum.map(fn(i) -> %{"text" => i, "callback_data" => i} end) - kb = if Enum.count(targets) > 1 do - [%{"text" => "everywhere", "callback_data" => "everywhere"}] ++ targets - else - targets - end - |> Enum.chunk_every(2) - keyboard = %{"inline_keyboard" => kb} - Telegram.Api.request(token, "sendMessage", chat_id: id, text: "Where should I send this file?", reply_markup: keyboard, reply_to_message_id: m["message_id"]) - end - end - #[debug] Unhandled update: %{"callback_query" => # %{ # "chat_instance" => "-7948978714441865930", "data" => "evolu.net/#dmz", @@ -111,8 +94,8 @@ defmodule LSG.Telegram do # } # , "update_id" => 218161568} - def handle_update(t, %{"callback_query" => cb = %{"data" => "resend", "id" => id, "message" => m = %{"message_id" => m_id, "chat" => %{"id" => chat_id}, "reply_to_message" => op}}}) do - end + #def handle_update(t, %{"callback_query" => cb = %{"data" => "resend", "id" => id, "message" => m = %{"message_id" => m_id, "chat" => %{"id" => chat_id}, "reply_to_message" => op}}}) do + #end def handle_update(t, %{"callback_query" => cb = %{"data" => target, "id" => id, "message" => m = %{"message_id" => m_id, "chat" => %{"id" => chat_id}, "reply_to_message" => op}}}) do account = IRC.Account.find_meta_account("telegram-id", chat_id) @@ -213,41 +196,26 @@ defmodule LSG.Telegram do trigger: IRC.Connection.extract_trigger(trigger_text), at: nil } - IO.puts("converted telegram to message: #{inspect message}") IRC.Connection.publish(message, ["message:private", "message:telegram"]) message end - command "start" do - text = "Hello to beautte! Query the bot on IRC and say \"enable-telegram\" to continue." - request("sendMessage", chat_id: update["chat"]["id"], - text: text) - end - - command "start", args do - IO.inspect(update) - key = "none" - account = IRC.Account.find_meta_account("telegram-validation-code", String.downcase(key)) - text = if account do - net = IRC.Account.get_meta(account, "telegram-validation-target") - IRC.Account.put_meta(account, "telegram-id", update["chat"]["id"]) - IRC.Account.delete_meta(account, "telegram-validation-code") - IRC.Account.delete_meta(account, "telegram-validation-target") - IRC.Connection.broadcast_message(net, account, "Telegram account added!") - "Yay! Linked to account #{account.name}\n\nThe bot doesn't work by sending telegram commands, just send what you would usually send on IRC." - else - "Token invalid" + defp start_upload(token, _, %{"message" => m = %{"chat" => %{"id" => id, "type" => "private"}}}) do + account = IRC.Account.find_meta_account("telegram-id", id) + if account do + text = if(m["text"], do: m["text"], else: nil) + targets = IRC.Membership.of_account(account) + |> Enum.map(fn({net, chan}) -> "#{net}/#{chan}" end) + |> Enum.map(fn(i) -> %{"text" => i, "callback_data" => i} end) + kb = if Enum.count(targets) > 1 do + [%{"text" => "everywhere", "callback_data" => "everywhere"}] ++ targets + else + targets + end + |> Enum.chunk_every(2) + keyboard = %{"inline_keyboard" => kb} + Telegram.Api.request(token, "sendMessage", chat_id: id, text: "Where should I send this file?", reply_markup: keyboard, reply_to_message_id: m["message_id"]) end - request("sendMessage", chat_id: update["chat"]["id"], text: text) end - command unknown do - request("sendMessage", chat_id: update["chat"]["id"], - text: "Hey! You sent me a command #{unknown} #{inspect update}") - end - - message do - request("sendMessage", chat_id: update["chat"]["id"], - text: "Hey! You sent me a message: #{inspect update}") - end end diff --git a/lib/lsg_irc/tell_plugin.ex b/lib/lsg_irc/tell_plugin.ex index a683b43..2c9e3c8 100644 --- a/lib/lsg_irc/tell_plugin.ex +++ b/lib/lsg_irc/tell_plugin.ex @@ -16,6 +16,10 @@ defmodule LSG.IRC.TellPlugin do (LSG.data_path() <> "/tell.dets") |> String.to_charlist() end + def tell(m, target, message) do + GenServer.cast(__MODULE__, {:tell, m, target, message}) + end + def init([]) do regopts = [plugin: __MODULE__] {:ok, _} = Registry.register(IRC.PubSub, "account", regopts) @@ -24,27 +28,13 @@ defmodule LSG.IRC.TellPlugin do {:ok, %{dets: dets}} end - def handle_info({:irc, :trigger, "tell", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: [nick_target | message]}}}, state) do - target = IRC.Account.find_always_by_nick(m.network, m.channel, nick_target) - message = Enum.join(message, " ") - with \ - {:target, %IRC.Account{} = target} <- {:target, target}, - {:same, false} <- {:same, target.id == m.account.id}, - target_user = IRC.UserTrack.find_by_account(m.network, target), - target_nick = if(target_user, do: target_user.nick, else: target.name), - present? = if(target_user, do: Map.has_key?(target_user.last_active, m.channel)), - {:absent, true, _} <- {:absent, !present?, target_nick}, - {:message, message} <- {:message, message} - do - obj = { {m.network, m.channel, target.id}, m.account.id, message, NaiveDateTime.utc_now()} - :dets.insert(state.dets, obj) - m.replyfun.("will tell to #{target_nick}") - else - {:same, _} -> m.replyfun.("are you so stupid that you need a bot to tell yourself things ?") - {:target, _} -> m.replyfun.("#{nick_target} unknown") - {:absent, _, nick} -> m.replyfun.("#{nick} is here, tell yourself!") - {:message, _} -> m.replyfun.("can't tell without a message") - end + def handle_cast({:tell, m, target, message}, state) do + do_tell(state, m, target, message) + {:noreply, state} + end + + def handle_info({:irc, :trigger, "tell", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: [target | message]}}}, state) do + do_tell(state, m, target, message) {:noreply, state} end @@ -90,4 +80,27 @@ defmodule LSG.IRC.TellPlugin do :ok end + defp do_tell(state, m, nick_target, message) do + target = IRC.Account.find_always_by_nick(m.network, m.channel, nick_target) + message = Enum.join(message, " ") + with \ + {:target, %IRC.Account{} = target} <- {:target, target}, + {:same, false} <- {:same, target.id == m.account.id}, + target_user = IRC.UserTrack.find_by_account(m.network, target), + target_nick = if(target_user, do: target_user.nick, else: target.name), + present? = if(target_user, do: Map.has_key?(target_user.last_active, m.channel)), + {:absent, true, _} <- {:absent, !present?, target_nick}, + {:message, message} <- {:message, message} + do + obj = { {m.network, m.channel, target.id}, m.account.id, message, NaiveDateTime.utc_now()} + :dets.insert(state.dets, obj) + m.replyfun.("will tell to #{target_nick}") + else + {:same, _} -> m.replyfun.("are you so stupid that you need a bot to tell yourself things ?") + {:target, _} -> m.replyfun.("#{nick_target} unknown") + {:absent, _, nick} -> m.replyfun.("#{nick} is here, tell yourself!") + {:message, _} -> m.replyfun.("can't tell without a message") + end + end + end diff --git a/lib/lsg_irc/user_mention_plugin.ex b/lib/lsg_irc/user_mention_plugin.ex new file mode 100644 index 0000000..5f7b10a --- /dev/null +++ b/lib/lsg_irc/user_mention_plugin.ex @@ -0,0 +1,49 @@ +defmodule LSG.IRC.UserMentionPlugin do + @moduledoc """ + # mention + + * **@`<nick>` `<message>`**: notifie si possible le nick immédiatement via Telegram, SMS, ou équivalent à `!tell`. + """ + + require Logger + + def short_irc_doc, do: false + def irc_doc, do: @moduledoc + + def start_link() do + GenServer.start_link(__MODULE__, [], name: __MODULE__) + end + + def init(_) do + {:ok, _} = Registry.register(IRC.PubSub, "triggers", plugin: __MODULE__) + {:ok, nil} + 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 + target = IRC.Account.find_always_by_nick(network, channel, nick) + if target do + telegram = IRC.Account.get_meta(target, "telegram-id") + sms = IRC.Account.get_meta(target, "sms-number") + text = "#{channel} <#{sender.nick}> #{Enum.join(content, " ")}" + + cond do + telegram -> + LSG.Telegram.send_message(telegram, "`#{channel}` <**#{sender.nick}**> #{Enum.join(content, " ")}") + sms -> + case LSG.IRC.SmsPlugin.send_sms(sms, text) do + {:error, code} -> message.replyfun("#{sender.nick}: erreur #{code} (sms)") + end + true -> + LSG.IRC.TellPlugin.tell(message, nick, content) + end + else + message.replyfun.("#{nick} m'est inconnu") + end + {:noreply, state} + end + + def handle_info(_, state) do + {:noreply, state} + end + +end |