Skip to content

Commit

Permalink
feat: add streaming finder feature (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
papey authored Aug 10, 2024
1 parent 142d4f3 commit e55b6b8
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/o2m.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ defmodule O2M do
case reaction.emoji.name do
"📌" -> Reminder.remind(reaction)
"👀" -> Reminder.delete(reaction)
"🔗" -> StreamingFinder.handle(reaction)
_ -> :ignore
end
end
Expand Down
50 changes: 50 additions & 0 deletions lib/streaming_finder.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule StreamingFinder do
@url_regex ~r/(https?:\/\/[^\s]+)/i
@max_urls 3

def handle(reaction) do
{:ok, origin} = Nostrum.Api.get_channel_message(reaction.channel_id, reaction.message_id)

case extract_urls(origin.content) do
[] ->
Nostrum.Api.create_reaction(origin.channel_id, origin.id, "🖕")

urls ->
for url <- urls |> Enum.take(@max_urls) do
case Odesli.get(url) do
{:ok, %Odesli.Response{artist: artist, title: title, urls: urls}} ->
Odesli.get(url)

Nostrum.Api.create_message(origin.channel_id,
embed: message(artist, title, urls),
message_reference: %{message_id: origin.id}
)

{:error, :no_match} ->
Nostrum.Api.create_reaction(origin.channel_id, origin.id, "🤷")
end
end
end
end

defp message(artist, title, urls) do
formatted_links =
urls
|> Enum.map(fn {platform, url} ->
"[#{String.capitalize(platform)}](<#{url}>)"
end)
|> Enum.join(" - ")

%Nostrum.Struct.Embed{
:title => "#{artist} - #{title}",
:color => 431_948,
:description => formatted_links
}
end

defp extract_urls(content) do
Regex.scan(@url_regex, content)
|> List.flatten()
|> Enum.uniq()
end
end
44 changes: 44 additions & 0 deletions lib/utils/odesli.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
defmodule Odesli do
@api_version "v1-alpha.1"
@base_url "https://api.song.link"
@links_url "#{@base_url}/#{@api_version}/links"

@platforms ["spotify", "deezer", "appleMusic", "youtube", "bandcamp", "tidal"]

defmodule Response do
defstruct [:artist, :title, :urls]
end

def get(url) do
{:ok, resp} = HTTPoison.get("#{@links_url}?#{URI.encode_query(%{url: url})}")

case resp do
%HTTPoison.Response{status_code: 200} ->
parsed = Jason.decode!(resp.body)

meta = parsed["entitiesByUniqueId"] |> Map.values() |> List.first()

{:ok,
%Response{
artist: meta["artistName"],
title: meta["title"],
urls: plateform_urls(parsed)
}}

_ ->
{:error, :no_match}
end
end

defp plateform_urls(%{"linksByPlatform" => links}) do
Enum.reduce(@platforms, %{}, fn plt, acc ->
link = links[plt]["url"]

if link do
Map.put(acc, plt, link)
else
acc
end
end)
end
end

0 comments on commit e55b6b8

Please sign in to comment.