Mastering Frappe Framework – Part 10: Advanced Customization with Scripts, Webhooks & Background Jobs

Why Advanced Customization Matters

Once your Frappe app is live, you’ll want to:

  • Add custom logic without changing core code
  • Automate actions based on events
  • Integrate with external services
  • Process heavy tasks in the background

This is where Client Scripts, Server Scripts, Webhooks, and Background Jobs shine.


1. Client Scripts

Client scripts run in the browser (frontend).

Use them to customize forms, validate data, or trigger actions without a page reload.

Example: Auto-fill a field based on another

frappe.ui.form.on('Sales Invoice', {
    customer: function(frm) {
        if (frm.doc.customer) {
            frappe.call({
                method: 'frappe.client.get',
                args: {
                    doctype: 'Customer',
                    name: frm.doc.customer
                },
                callback: function(r) {
                    if (r.message) {
                        frm.set_value('contact_email', r.message.email_id);
                    }
                }
            });
        }
    }
});

💡 Save this in Custom Script for “Sales Invoice” from the Frappe UI.


2. Server Scripts

Server scripts run on the backend in Python.

They can be triggered before/after document events or on API calls.

Example: Auto-set Discount Before Saving

# Type: Document Event
# Reference Doctype: Sales Order
# Event: before_save

if doc.grand_total > 10000:
    doc.discount_amount = doc.grand_total * 0.05

💡 Go to Server Script in Frappe and paste this with type Document Event.


3. Webhooks

Webhooks let you push data from Frappe to another system whenever something happens.

Example: Notify Slack when a new Lead is created

  • Create Webhook:
    • Doctype: Lead
    • Webhook URL: Slack Incoming Webhook URL
    • Method: POST
    • Data: JSON payload with lead details.

Sample Payload:

{
  "text": "New Lead Created: {{name}} - {{lead_name}}"
}

4. Background Jobs

Some tasks are too heavy to run instantly (PDF generation, API sync).

Use Frappe’s Background Jobs to offload them.

Example: Sending a bulk email in the background

import frappe
from frappe.utils.background_jobs import enqueue

def send_bulk_email():
    recipients = frappe.get_all('Customer', pluck='email_id')
    for email in recipients:
        frappe.sendmail(recipients=email, subject="Hello!", message="Thanks for being with us!")

# Enqueue the job
enqueue(send_bulk_email, queue='long', timeout=300)

5. API Rate Limiting

To avoid abuse of your API, limit requests per minute.

Example in hooks.py:

limits = {
    "api": {
        "default": {
            "limit": 100,  # requests
            "window": 60   # seconds
        }
    }
}

Best Practices

✅ Use client scripts for small, UI-related changes.

✅ Use server scripts for data logic & automation.

✅ Use webhooks for real-time integrations.

✅ Always enqueue heavy tasks to keep the UI fast.

✅ Monitor background jobs with bench worker –queue long.


Key Takeaways from Part 10

  • Client scripts modify UI behavior dynamically.
  • Server scripts automate backend logic without touching core code.
  • Webhooks integrate Frappe with external services.
  • Background jobs handle long-running tasks efficiently.
  • API limits protect your SaaS from overload.

Leave a Reply