feat: add Printify webhook endpoint for real-time product updates
- Add /webhooks/printify endpoint with HMAC-SHA256 signature verification - Add Webhooks context to handle product:updated, product:deleted events - Add ProductDeleteWorker for async product deletion - Add webhook API methods to Printify client (create, list, delete) - Add register_webhooks/2 to Printify provider - Add mix register_webhooks task for one-time webhook registration - Cache raw request body in endpoint for signature verification Usage: 1. Generate webhook secret: openssl rand -hex 20 2. Add to provider connection config as "webhook_secret" 3. Register with Printify: mix register_webhooks https://yourshop.com/webhooks/printify Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
69
lib/mix/tasks/register_webhooks.ex
Normal file
69
lib/mix/tasks/register_webhooks.ex
Normal file
@@ -0,0 +1,69 @@
|
||||
defmodule Mix.Tasks.RegisterWebhooks do
|
||||
@moduledoc """
|
||||
Registers Printify webhooks for a shop.
|
||||
|
||||
Usage:
|
||||
mix register_webhooks https://yourshop.com/webhooks/printify
|
||||
|
||||
Prerequisites:
|
||||
- Printify provider connection must exist with shop_id configured
|
||||
- webhook_secret must be set in the connection config
|
||||
|
||||
Generate a webhook secret with:
|
||||
openssl rand -hex 20
|
||||
"""
|
||||
|
||||
use Mix.Task
|
||||
|
||||
@shortdoc "Register Printify webhooks for product updates"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([url]) do
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
alias SimpleshopTheme.Products
|
||||
alias SimpleshopTheme.Providers.Printify
|
||||
|
||||
case Products.get_provider_connection_by_type("printify") do
|
||||
nil ->
|
||||
Mix.shell().error("No Printify connection found. Create one at /admin/providers first.")
|
||||
|
||||
conn ->
|
||||
Mix.shell().info("Registering webhooks for URL: #{url}")
|
||||
|
||||
case Printify.register_webhooks(conn, url) do
|
||||
{:ok, results} ->
|
||||
Enum.each(results, fn
|
||||
{:ok, event, response} ->
|
||||
Mix.shell().info("✓ Registered: #{event} (ID: #{response["id"]})")
|
||||
|
||||
{:error, event, reason} ->
|
||||
Mix.shell().error("✗ Failed: #{event} - #{inspect(reason)}")
|
||||
end)
|
||||
|
||||
Mix.shell().info("\nDone!")
|
||||
|
||||
{:error, :no_webhook_secret} ->
|
||||
Mix.shell().error("""
|
||||
No webhook secret configured.
|
||||
|
||||
Generate one with: openssl rand -hex 20
|
||||
|
||||
Then add it to your provider connection config as "webhook_secret".
|
||||
""")
|
||||
|
||||
{:error, reason} ->
|
||||
Mix.shell().error("Failed: #{inspect(reason)}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.shell().error("""
|
||||
Usage: mix register_webhooks <url>
|
||||
|
||||
Example:
|
||||
mix register_webhooks https://yourshop.com/webhooks/printify
|
||||
""")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user