1 defmodule Pleroma.Akkoma.Translators.DeepL do
2 @behaviour Pleroma.Akkoma.Translator
8 defp base_url(:free) do
9 "https://api-free.deepl.com/v2/"
12 defp base_url(:pro) do
13 "https://api.deepl.com/v2/"
17 Config.get([:deepl, :api_key])
21 Config.get([:deepl, :tier])
24 @impl Pleroma.Akkoma.Translator
26 with {:ok, %{status: 200} = response} <- do_languages(),
27 {:ok, body} <- Jason.decode(response.body) do
29 Enum.map(body, fn %{"language" => code, "name" => name} -> %{code: code, name: name} end)
33 {:ok, %{status: status} = response} ->
34 Logger.warning("DeepL: Request rejected: #{inspect(response)}")
35 {:error, "DeepL request failed (code #{status})"}
42 @impl Pleroma.Akkoma.Translator
43 def translate(string, from_language, to_language) do
44 with {:ok, %{status: 200} = response} <-
45 do_request(api_key(), tier(), string, from_language, to_language),
46 {:ok, body} <- Jason.decode(response.body) do
47 %{"translations" => [%{"text" => translated, "detected_source_language" => detected}]} =
50 {:ok, detected, translated}
52 {:ok, %{status: status} = response} ->
53 Logger.warning("DeepL: Request rejected: #{inspect(response)}")
54 {:error, "DeepL request failed (code #{status})"}
61 defp do_request(api_key, tier, string, from_language, to_language) do
63 base_url(tier) <> "translate",
67 target_lang: to_language,
70 |> maybe_add_source(from_language),
74 {"authorization", "DeepL-Auth-Key #{api_key}"},
75 {"content-type", "application/x-www-form-urlencoded"}
80 defp maybe_add_source(opts, nil), do: opts
81 defp maybe_add_source(opts, lang), do: Map.put(opts, :source_lang, lang)
83 defp do_languages() do
85 base_url(tier()) <> "languages?type=target",
87 {"authorization", "DeepL-Auth-Key #{api_key()}"}