TopggEx.Webhook (topgg_ex v0.1.3)
View SourceTop.gg Webhook handler for Plug-based HTTP servers.
This module provides webhook handling functionality for receiving vote notifications from Top.gg, compatible with Phoenix and other Plug-based HTTP servers.
Examples
# In your Phoenix router or Plug router:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import TopggEx.Webhook
pipeline :webhook do
plug :accepts, ["json"]
plug TopggEx.Webhook, authorization: "your_webhook_auth_token"
end
scope "/webhooks" do
pipe_through :webhook
post "/topgg", YourController, :handle_vote
end
end
# In your controller:
defmodule YourController do
use MyAppWeb, :controller
def handle_vote(conn, _params) do
case conn.assigns.topgg_payload do
%{"user" => user_id, "type" => "upvote"} ->
# Handle the vote
IO.puts("User #{user_id} voted!")
send_resp(conn, 204, "")
%{"user" => user_id, "type" => "test"} ->
# Handle test webhook
IO.puts("Test webhook from user #{user_id}")
send_resp(conn, 204, "")
_ ->
send_resp(conn, 400, "Invalid payload")
end
end
end
Functional API
You can also use the functional API for more control:
# Verify and parse a webhook request
case TopggEx.Webhook.verify_and_parse(conn, "your_auth_token") do
{:ok, payload} ->
# Handle the vote payload
IO.inspect(payload)
{:error, :unauthorized} ->
# Handle unauthorized request
send_resp(conn, 403, Jason.encode!(%{error: "Unauthorized"}))
{:error, :invalid_body} ->
# Handle malformed request
send_resp(conn, 400, Jason.encode!(%{error: "Invalid body"}))
end
Webhook Data Schema
The webhook payload typically contains:
user
- The ID of the user who votedtype
- The type of vote ("upvote" or "test")bot
- The ID of the bot that was voted forisWeekend
- Whether the vote was cast on a weekend (counts as 2 votes)query
- Query parameters from the vote page (if any)
Links
Summary
Functions
Creates a functional webhook handler that can be used in controllers or other contexts.
Verifies the authorization header and parses the webhook payload.
Types
Functions
@spec listener((webhook_payload(), Plug.Conn.t() -> Plug.Conn.t()), webhook_options()) :: (Plug.Conn.t(), any() -> Plug.Conn.t())
Creates a functional webhook handler that can be used in controllers or other contexts.
Parameters
handler_fun
- Function that takes the payload and connectionopts
- Options including:authorization
and:error_handler
Returns
A function that can be used as a Plug or called directly.
Examples
webhook_handler = TopggEx.Webhook.listener(fn payload, conn ->
IO.puts("User #{payload["user"]} voted!")
send_resp(conn, 204, "")
end, authorization: "my_auth_token")
# Use in a router
post "/webhook", webhook_handler
@spec verify_and_parse(Plug.Conn.t(), String.t() | nil) :: {:ok, webhook_payload()} | {:error, atom()}
Verifies the authorization header and parses the webhook payload.
Parameters
conn
- The Plug connectionexpected_auth
- The expected authorization token (optional)
Returns
{:ok, payload}
- Successfully parsed webhook payload{:error, :unauthorized}
- Authorization header doesn't match{:error, :invalid_body}
- Request body is not valid JSON{:error, :malformed_request}
- Error reading request body
Examples
case TopggEx.Webhook.verify_and_parse(conn, "my_auth_token") do
{:ok, payload} ->
IO.puts("Received vote from user: #{payload["user"]}")
{:error, reason} ->
IO.puts("Webhook error: #{inspect(reason)}")
end