diff options
author | Jordan Bracco <href@random.sh> | 2025-06-25 19:22:59 +0200 |
---|---|---|
committer | Jordan Bracco <href@random.sh> | 2025-06-25 19:22:59 +0200 |
commit | c934e79e5852e05f714b2d542cc2678e287c49b8 (patch) | |
tree | 55779a0168260fce03e4775eacdd613ffc945588 /lib/plugins/finance.ex | |
parent | updates (diff) |
format.
Diffstat (limited to 'lib/plugins/finance.ex')
-rw-r--r-- | lib/plugins/finance.ex | 172 |
1 files changed, 112 insertions, 60 deletions
diff --git a/lib/plugins/finance.ex b/lib/plugins/finance.ex index b083df8..68afc48 100644 --- a/lib/plugins/finance.ex +++ b/lib/plugins/finance.ex @@ -27,25 +27,31 @@ defmodule Nola.Plugins.Finance do @crypto_list "http://www.alphavantage.co/digital_currency_list/" HTTPoison.start() - load_currency = fn(url) -> + + load_currency = fn url -> resp = HTTPoison.get!(url) + resp.body |> String.strip() |> String.split("\n") |> Enum.drop(1) - |> Enum.map(fn(line) -> - [symbol, name] = line - |> String.strip() - |> String.split(",", parts: 2) + |> Enum.map(fn line -> + [symbol, name] = + line + |> String.strip() + |> String.split(",", parts: 2) + {symbol, name} end) - |> Enum.into(Map.new) + |> Enum.into(Map.new()) end + fiat = load_currency.(@currency_list) crypto = load_currency.(@crypto_list) @currencies Map.merge(fiat, crypto) def irc_doc, do: @moduledoc + def start_link() do GenServer.start_link(__MODULE__, [], name: __MODULE__) end @@ -58,58 +64,77 @@ defmodule Nola.Plugins.Finance do {:ok, nil} end - - def handle_info({:irc, :trigger, "stocks", message = %{trigger: %{type: :query, args: args = search}}}, state) do + def handle_info( + {:irc, :trigger, "stocks", message = %{trigger: %{type: :query, args: args = search}}}, + state + ) do search(search, message) {:noreply, state} end defp search(search, message) do search = Enum.join(search, "%20") - url = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=#{search}&apikey=#{api_key()}" + + url = + "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=#{search}&apikey=#{api_key()}" + case HTTPoison.get(url) do {:ok, %HTTPoison.Response{status_code: 200, body: data}} -> data = Poison.decode!(data) IO.inspect(data) + if error = Map.get(data, "Error Message") do - Logger.error("AlphaVantage API invalid request #{url} - #{inspect error}") + Logger.error("AlphaVantage API invalid request #{url} - #{inspect(error)}") message.replyfun.("stocks: requête invalide") else - items = for item <- Map.get(data, "bestMatches") do - symbol = Map.get(item, "1. symbol") - name = Map.get(item, "2. name") - type = Map.get(item, "3. type") - region = Map.get(item, "4. region") - currency = Map.get(item, "8. currency") - "#{symbol}: #{name} (#{region}; #{currency}; #{type})" - end - |> Enum.join(", ") - items = if items == "" do - "no results!" - else - items - end + items = + for item <- Map.get(data, "bestMatches") do + symbol = Map.get(item, "1. symbol") + name = Map.get(item, "2. name") + type = Map.get(item, "3. type") + region = Map.get(item, "4. region") + currency = Map.get(item, "8. currency") + "#{symbol}: #{name} (#{region}; #{currency}; #{type})" + end + |> Enum.join(", ") + + items = + if items == "" do + "no results!" + else + items + end + message.replyfun.(items) end + {:ok, resp = %HTTPoison.Response{status_code: code}} -> - Logger.error "AlphaVantage API error: #{code} #{url} - #{inspect resp}" + Logger.error("AlphaVantage API error: #{code} #{url} - #{inspect(resp)}") message.replyfun.("forex: erreur (api #{code})") + {:error, %HTTPoison.Error{reason: error}} -> - Logger.error "AlphaVantage HTTP error: #{inspect error}" - message.replyfun.("forex: erreur (http #{inspect error})") + Logger.error("AlphaVantage HTTP error: #{inspect(error)}") + message.replyfun.("forex: erreur (http #{inspect(error)})") end end - def handle_info({:irc, :trigger, "stocks", message = %{trigger: %{type: :bang, args: args = [symbol]}}}, state) do - url = "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=#{symbol}&apikey=#{api_key()}" + def handle_info( + {:irc, :trigger, "stocks", message = %{trigger: %{type: :bang, args: args = [symbol]}}}, + state + ) do + url = + "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=#{symbol}&apikey=#{api_key()}" + case HTTPoison.get(url) do {:ok, %HTTPoison.Response{status_code: 200, body: data}} -> data = Poison.decode!(data) IO.inspect(data) + case data do %{"Error Message" => error} -> - Logger.error("AlphaVantage API invalid request #{url} - #{inspect error}") + Logger.error("AlphaVantage API invalid request #{url} - #{inspect(error)}") message.replyfun.("stocks: error: #{error}") + %{"Global Quote" => data = %{"01. symbol" => _}} -> open = Map.get(data, "02. open") high = Map.get(data, "03. high") @@ -120,39 +145,54 @@ defmodule Nola.Plugins.Finance do change = Map.get(data, "09. change") change_pct = Map.get(data, "10. change percent") - msg = "#{symbol}: #{price} #{change} [#{change_pct}] (high: #{high}, low: #{low}, open: #{open}, prev close: #{prev_close}) (volume: #{volume})" + msg = + "#{symbol}: #{price} #{change} [#{change_pct}] (high: #{high}, low: #{low}, open: #{open}, prev close: #{prev_close}) (volume: #{volume})" + message.replyfun.(msg) + _ -> message.replyfun.("stocks: unknown symbol: #{symbol}") search([symbol], message) end + {:ok, resp = %HTTPoison.Response{status_code: code}} -> - Logger.error "AlphaVantage API error: #{code} #{url} - #{inspect resp}" + Logger.error("AlphaVantage API error: #{code} #{url} - #{inspect(resp)}") message.replyfun.("stocks: erreur (api #{code})") + {:error, %HTTPoison.Error{reason: error}} -> - Logger.error "AlphaVantage HTTP error: #{inspect error}" - message.replyfun.("stocks: erreur (http #{inspect error})") + Logger.error("AlphaVantage HTTP error: #{inspect(error)}") + message.replyfun.("stocks: erreur (http #{inspect(error)})") end + {:noreply, state} end + def handle_info( + {:irc, :trigger, "forex", message = %{trigger: %{type: :bang, args: args = [_ | _]}}}, + state + ) do + {amount, from, to} = + case args do + [amount, from, to] -> + {amount, _} = Float.parse(amount) + {amount, from, to} + + [from, to] -> + {1, from, to} + + [from] -> + {1, from, "EUR"} + end + + url = + "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=#{from}&to_currency=#{to}&apikey=#{api_key()}" - def handle_info({:irc, :trigger, "forex", message = %{trigger: %{type: :bang, args: args = [_ | _]}}}, state) do - {amount, from, to} = case args do - [amount, from, to] -> - {amount, _} = Float.parse(amount) - {amount, from, to} - [from, to] -> - {1, from, to} - [from] -> - {1, from, "EUR"} - end - url = "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=#{from}&to_currency=#{to}&apikey=#{api_key()}" case HTTPoison.get(url) do {:ok, %HTTPoison.Response{status_code: 200, body: data}} -> data = Poison.decode!(data) + if error = Map.get(data, "Error Message") do - Logger.error("AlphaVantage API invalid request #{url} - #{inspect error}") + Logger.error("AlphaVantage API invalid request #{url} - #{inspect(error)}") message.replyfun.("forex: requête invalide") else data = Map.get(data, "Realtime Currency Exchange Rate") @@ -160,34 +200,47 @@ defmodule Nola.Plugins.Finance do to_name = Map.get(data, "4. To_Currency Name") rate = Map.get(data, "5. Exchange Rate") {rate, _} = Float.parse(rate) - value = amount*rate - message.replyfun.("#{amount} #{from} (#{from_name}) -> #{value} #{to} (#{to_name}) (#{rate})") + value = amount * rate + + message.replyfun.( + "#{amount} #{from} (#{from_name}) -> #{value} #{to} (#{to_name}) (#{rate})" + ) end + {:ok, resp = %HTTPoison.Response{status_code: code}} -> - Logger.error "AlphaVantage API error: #{code} #{url} - #{inspect resp}" + Logger.error("AlphaVantage API error: #{code} #{url} - #{inspect(resp)}") message.replyfun.("forex: erreur (api #{code})") + {:error, %HTTPoison.Error{reason: error}} -> - Logger.error "AlphaVantage HTTP error: #{inspect error}" - message.replyfun.("forex: erreur (http #{inspect error})") + Logger.error("AlphaVantage HTTP error: #{inspect(error)}") + message.replyfun.("forex: erreur (http #{inspect(error)})") end + {:noreply, state} end - def handle_info({:irc, :trigger, "currency", message = %{trigger: %{type: :query, args: args = search}}}, state) do + def handle_info( + {:irc, :trigger, "currency", message = %{trigger: %{type: :query, args: args = search}}}, + state + ) do search = Enum.join(search, " ") - results = Enum.filter(@currencies, fn({symbol, name}) -> - String.contains?(String.downcase(name), String.downcase(search)) || String.contains?(String.downcase(symbol), String.downcase(search)) - end) - |> Enum.map(fn({symbol, name}) -> - "#{symbol}: #{name}" - end) - |> Enum.join(", ") + + results = + Enum.filter(@currencies, fn {symbol, name} -> + String.contains?(String.downcase(name), String.downcase(search)) || + String.contains?(String.downcase(symbol), String.downcase(search)) + end) + |> Enum.map(fn {symbol, name} -> + "#{symbol}: #{name}" + end) + |> Enum.join(", ") if results == "" do message.replyfun.("no results!") else message.replyfun.(results) end + {:noreply, state} end @@ -195,5 +248,4 @@ defmodule Nola.Plugins.Finance do Application.get_env(:nola, :alphavantage, []) |> Keyword.get(:api_key, "demo") end - end |