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:
41
lib/simpleshop_theme/webhooks/product_delete_worker.ex
Normal file
41
lib/simpleshop_theme/webhooks/product_delete_worker.ex
Normal file
@@ -0,0 +1,41 @@
|
||||
defmodule SimpleshopTheme.Webhooks.ProductDeleteWorker do
|
||||
@moduledoc """
|
||||
Oban worker for deleting products removed from POD providers.
|
||||
"""
|
||||
|
||||
use Oban.Worker, queue: :sync, max_attempts: 3
|
||||
|
||||
alias SimpleshopTheme.Products
|
||||
|
||||
require Logger
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Oban.Job{args: %{"provider_product_id" => provider_product_id}}) do
|
||||
case Products.get_provider_connection_by_type("printify") do
|
||||
nil ->
|
||||
Logger.warning("No Printify connection found for product deletion")
|
||||
{:cancel, :no_connection}
|
||||
|
||||
conn ->
|
||||
case Products.get_product_by_provider(conn.id, provider_product_id) do
|
||||
nil ->
|
||||
Logger.info("Product #{provider_product_id} already deleted or not found")
|
||||
:ok
|
||||
|
||||
product ->
|
||||
Logger.info("Deleting product #{product.id} (provider: #{provider_product_id})")
|
||||
|
||||
case Products.delete_product(product) do
|
||||
{:ok, _} -> :ok
|
||||
{:error, reason} -> {:error, reason}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enqueue(provider_product_id) do
|
||||
%{provider_product_id: to_string(provider_product_id)}
|
||||
|> new()
|
||||
|> Oban.insert()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user