defmodule PingPong.Service.Telegram do
@moduledoc """
Telegram Bot API notification service.
This service sends text messages through Telegram's `sendMessage` endpoint.
The public PingPong payload uses `:content`; the service maps it to Telegram's
`text` field before sending the request.
"""
@behaviour PingPong.ServiceBehaviour
@typedoc "Telegram notification payload."
@type payload :: %{required(:content) => binary(), required(:chat_id) => binary()}
@typedoc "Telegram delivery options."
@type options :: %{required(:token) => binary()}
@base_url "https://api.telegram.org"
@doc """
Sends a Telegram message.
Required payload:
%{
content: "Message text",
chat_id: "123456789"
}
Required options:
%{token: "123456:telegram-bot-token"}
Missing required values return `{:error, {:missing_required_params}, nil}`.
"""
@spec call(payload(), options()) :: PingPong.result()
def call(payload = _, options = _)
when not (is_map(payload) and is_map(options) and is_map_key(payload, :content) and
is_map_key(payload, :chat_id) and is_map_key(options, :token)),
do: {:error, {:missing_required_params}, nil}
def call(payload, options) do
token = Map.get(options, :token)
url = "#{@base_url}/bot#{token}/sendMessage"
send_telegram(payload, url)
end
defp send_telegram(payload, url) do
body = %{
chat_id: Map.get(payload, :chat_id),
text: Map.get(payload, :content)
}
PingPong.Service.HTTP.post(url, body)
end
end