AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Frappe Webhook Manager

skill-venkateshvenki404224-frappe-apps-manager-frappe-webhook-manager · by Venkateshvenki404224

Create webhook handlers for Frappe integrations. Use when implementing webhooks, event-driven integrations, or external system notifications.

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add skill-venkateshvenki404224-frappe-apps-manager-frappe-webhook-manager

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-venkateshvenki404224-frappe-apps-manager-frappe-webhook-manager)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Frappe Webhook Manager? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Frappe Webhook Manager

Generate secure webhook receivers and senders for Frappe integrations with external systems.

Global Rules

These Frappe conventions apply to everything this skill generates, and override any conflicting example below.

  • Bench commands: use bare bench (never ./env/bin/bench or a full path). Always pass --site explicitly — never run a bare bench migrate / bench run-tests. Run bench start in the background and only if it isn't already running. Don't run discovery commands (which bench, bench --version).
  • DocType files live at apps////doctype//.json — the app name appears twice (directory + Python package) — with an empty __init__.py alongside. Never mkdir the folder; write the JSON and run bench --site migrate to create the structure. Don't add creation, modified, owner, modified_by, or docstatus as fields — Frappe manages them.
  • Database & ORM: prefer frappe.qb.get_query() over raw frappe.db.sql(). Use frappe.db.get_all() for server logic (ignores permissions) and frappe.db.get_list() for user-facing APIs (enforces them). Never use frappe.db.set_value() on a field with validation or lifecycle logic — load the doc and doc.save() so controller hooks run. Batch-fetch related records; never query inside a loop (N+1).
  • Never call frappe.db.commit() in controllers, request handlers, background jobs, or patches — Frappe auto-commits on success and rolls back on uncaught errors. Flush manually only to make a write visible to a subsequent frappe.enqueue() (or pass enqueue_after_commit=True).
  • Permissions & APIs: put permission checks inside controller methods (enforced on every call path), not in API wrappers. Type-hint every @frappe.whitelist() parameter so Frappe validates and casts it, and pass methods=[...] to pin the HTTP verb.

When to Use This Skill

Claude should invoke this skill when:

  • User wants to receive webhooks from external services
  • User needs to send webhooks to external systems
  • User mentions webhook, event-driven integration, or external notifications
  • User wants to integrate payment gateways, APIs, or third-party services
  • User needs to handle real-time events from external systems

Capabilities

1. Webhook Receiver

Secure Webhook Endpoint: verify the signature BEFORE trusting any of the payload, and pin the verb to POST.

import frappe
from frappe import _
import hmac
import hashlib

@frappe.whitelist(allow_guest=True, methods=["POST"])
def webhook_receiver():
    """Receive webhook from external service"""
    # Get signature
    signature = frappe.get_request_header('X-Webhook-Signature') or ''

    # Verify signature against the raw body FIRST — never trust the payload before this
    secret = frappe.conf.get('webhook_secret')
    expected = hmac.new(
        secret.encode(),
        frappe.request.data,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        frappe.throw(_('Invalid signature'), frappe.AuthenticationError)

    # Only now is it safe to parse the payload
    payload = frappe.parse_json(frappe.request.data)

    # Process webhook (offload anything slow to a background job)
    event = payload.get('event')
    if event == 'payment.success':
        handle_payment_success(payload)
    elif event == 'customer.updated':
        handle_customer_update(payload)

    # Return only a status — never echo sensitive fields back
    return {'status': 'success'}

2. Outgoing Webhook

Trigger outbound webhooks from doc_events in hooks.py rather than inside the DocType controller, and enqueue delivery — never send inline inside the document event (a slow/failed receiver must not block or roll back the save).

Wire the trigger in hooks.py (handlers are dotted paths to importable functions):

# apps/myapp/myapp/hooks.py
doc_events = {
    "Sales Invoice": {
        "on_submit": "myapp.webhooks.queue_invoice_webhook",
    }
}

Enqueue delivery (the handler receives doc and the event method):

# apps/myapp/myapp/webhooks.py
import frappe

def queue_invoice_webhook(doc, method):
    """doc_events handler: enqueue, don't send inline."""
    frappe.enqueue(
        "myapp.webhooks.send_webhook",
        queue="short",
        timeout=120,
        job_id=f"webhook::{doc.name}::invoice.submitted",  # stable id
        deduplicate=True,                  # skip if an identical job is already queued
        enqueue_after_commit=True,         # only fire after the save commits
        event="invoice.submitted",
        data=doc.as_dict(),
    )

Send with HMAC signature and a bounded retry:

# apps/myapp/myapp/webhooks.py
import frappe
import hmac
import hashlib
import json
import requests

def send_webhook(event, data):
    """Runs in a worker. No frappe.db.commit() — Frappe auto-commits on success."""
    webhook_url = frappe.conf.get("external_webhook_url")
    secret = frappe.conf.get("webhook_secret")

    payload = {"event": event, "data": data, "timestamp": frappe.utils.now()}
    body = json.dumps(payload)
    signature = hmac.new(secret.encode(), body.encode(), hashlib.sha256).hexdigest()

    headers = {"Content-Type": "application/json", "X-Webhook-Signature": signature}

    last_error = None
    for attempt in range(3):  # bounded retry
        try:
            resp = requests.post(webhook_url, data=body, headers=headers, timeout=10)
            if resp.status_code == 200:
                return True
            last_error = f"HTTP {resp.status_code}"
        except Exception:
            last_error = frappe.get_traceback()

    frappe.log_error(last_error, f"Webhook failed: {event} -> {webhook_url}")
    return False

Refer to the background-jobs reference for the full set of frappe.enqueue options (job_id, deduplicate, enqueue_after_commit, queues, timeouts).

References

Frappe Webhook Implementation:

  • Webhook DocType: https://github.com/frappe/frappe/tree/develop/frappe/integrations/doctype/webhook
  • Integration Request: https://github.com/frappe/frappe/tree/develop/frappe/integrations/doctype/integration_request

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.