Packages
ex_gram
0.55.1
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.1
0.55.0
0.54.0
0.53.0
0.52.2
0.52.1
0.52.0
0.51.1
0.51.0
0.50.2
0.50.1
0.50.0
0.41.0
0.40.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.5.0-rc6
0.5.0-rc5
0.5.0-rc4
0.5.0-rc3
0.5.0-rc2
Telegram Bot API low level and framework
Current section
Files
Jump to
Current section
Files
lib/ex_gram/plug.ex
if Code.ensure_loaded?(Plug) do
defmodule ExGram.Plug do
@moduledoc false
@behaviour Plug
import Plug.Conn
alias Plug.Conn
require Logger
@impl true
def init(opts), do: opts
@impl true
def call(%Conn{method: "POST"} = conn, _) do
if "telegram" in conn.path_info do
handle_update(conn)
else
conn
end
end
def call(conn, _), do: conn
defp handle_update(conn) do
{:ok, body, conn} = Plug.Conn.read_body(conn)
{status, message} =
case conn
|> get_req_header("x-telegram-bot-api-secret-token")
|> check_secret_token() do
:ok -> handle_update(conn, ExGram.Encoder.decode(body, keys: :atoms))
{:error, error} -> {400, %{error: error}}
end
conn
|> put_resp_content_type("application/json")
|> send_resp(status, ExGram.Encoder.encode!(message))
|> halt()
end
defp handle_update(conn, {:ok, update}) do
token_hash = token_hash(conn.path_info)
update
|> ExGram.Cast.cast(ExGram.Model.Update)
|> ExGram.Updates.Webhook.update(token_hash)
{200, %{ok: true}}
end
defp handle_update(_conn, {:error, error}), do: {400, %{error: error}}
defp check_secret_token([]) do
Logger.debug(
"The secret token is not configured in webhook mode. For security purposes, it is recommended to set one."
)
:ok
end
defp check_secret_token([secret_token]) do
config_token = ExGram.Config.get(:ex_gram, :webhook)[:secret_token]
case {secret_token, config_token} do
{_secret_token, nil} ->
message =
"The secret token exists in the request header but is not configured in the application's settings."
Logger.error(message)
{:error, message}
{secret_token, config_token} when secret_token != config_token ->
message =
"The secret token in the request header does not match the one configured in the webhook mode."
Logger.error(message)
{:error, message}
{secret_token, config_token} when secret_token == config_token ->
:ok
end
end
defp token_hash([path]) when is_binary(path), do: path
defp token_hash([_ | tl]), do: token_hash(tl)
end
end