summaryrefslogtreecommitdiff
path: root/lib/nola_plugins/youtube_plugin.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nola_plugins/youtube_plugin.ex')
-rw-r--r--lib/nola_plugins/youtube_plugin.ex104
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