diff options
Diffstat (limited to 'lib/nola_plugins/youtube_plugin.ex')
-rw-r--r-- | lib/nola_plugins/youtube_plugin.ex | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/nola_plugins/youtube_plugin.ex b/lib/nola_plugins/youtube_plugin.ex new file mode 100644 index 0000000..fb9bea2 --- /dev/null +++ b/lib/nola_plugins/youtube_plugin.ex @@ -0,0 +1,104 @@ +defmodule Nola.IRC.YouTubePlugin do + require Logger + + @moduledoc """ + # youtube + + * **!yt `<recherche>`**, !youtube `<recherche>`: retourne le premier résultat de la `<recherche>` YouTube + """ + + defstruct client: nil + + def irc_doc, do: @moduledoc + + def start_link() do + GenServer.start_link(__MODULE__, [], name: __MODULE__) + end + + def init([]) do + for t <- ["trigger:yt", "trigger:youtube"], do: {:ok, _} = Registry.register(IRC.PubSub, t, [plugin: __MODULE__]) + {:ok, %__MODULE__{}} + end + + def handle_info({:irc, :trigger, _, message = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: args}}}, state) do + irc_search(Enum.join(args, " "), message) + {:noreply, state} + end + + def handle_info(info, state) do + {:noreply, state} + end + + defp irc_search(query, message) do + case search(query) do + {:ok, %{"items" => [item | _]}} -> + url = "https://youtube.com/watch?v=" <> item["id"] + snippet = item["snippet"] + duration = item["contentDetails"]["duration"] |> String.replace("PT", "") |> String.downcase + date = snippet["publishedAt"] + |> DateTime.from_iso8601() + |> elem(1) + |> Timex.format("{relative}", :relative) + |> elem(1) + + info_line = "— #{duration} — uploaded by #{snippet["channelTitle"]} — #{date}" + <> " — #{item["statistics"]["viewCount"]} views, #{item["statistics"]["likeCount"]} likes," + <> " #{item["statistics"]["dislikeCount"]} dislikes" + message.replyfun.("#{snippet["title"]} — #{url}") + message.replyfun.(info_line) + {:error, error} -> + message.replyfun.("Erreur YouTube: "<>error) + _ -> + nil + end + end + + defp search(query) do + query = query + |> String.strip + key = Application.get_env(:nola, :youtube)[:api_key] + params = %{ + "key" => key, + "maxResults" => 1, + "part" => "id", + "safeSearch" => "none", + "type" => "video", + "q" => query, + } + url = "https://www.googleapis.com/youtube/v3/search" + case HTTPoison.get(url, [], params: params) do + {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> + {:ok, json} = Jason.decode(body) + item = List.first(json["items"]) + if item do + video_id = item["id"]["videoId"] + params = %{ + "part" => "snippet,contentDetails,statistics", + "id" => video_id, + "key" => key + } + headers = [] + options = [params: params] + case HTTPoison.get("https://www.googleapis.com/youtube/v3/videos", [], options) do + {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> + Jason.decode(body) + {:ok, %HTTPoison.Response{status_code: code, body: body}} -> + Logger.error "YouTube HTTP #{code}: #{inspect body}" + {:error, "http #{code}"} + error -> + Logger.error "YouTube http error: #{inspect error}" + :error + end + else + :error + end + {:ok, %HTTPoison.Response{status_code: code, body: body}} -> + Logger.error "YouTube HTTP #{code}: #{inspect body}" + {:error, "http #{code}"} + error -> + Logger.error "YouTube http error: #{inspect error}" + :error + end + end + +end |