summaryrefslogtreecommitdiff
path: root/lib/plugins/finance.ex
diff options
context:
space:
mode:
authorJordan Bracco <href@random.sh>2025-06-25 19:22:59 +0200
committerJordan Bracco <href@random.sh>2025-06-25 19:22:59 +0200
commitc934e79e5852e05f714b2d542cc2678e287c49b8 (patch)
tree55779a0168260fce03e4775eacdd613ffc945588 /lib/plugins/finance.ex
parentupdates (diff)
format.
Diffstat (limited to 'lib/plugins/finance.ex')
-rw-r--r--lib/plugins/finance.ex172
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