Skip to content
AI & Agents
Skill

/frappe-core-notifications

Use when implementing email notifications, system alerts, Assignment Rules, Auto Repeat, or ToDo items. Prevents misconfigured Email Accounts, broken notification templates, and silent delivery failures. Covers frappe.sendmail, Notification DocType, Email Account setup, Jinja

From plugin
frappe-claude-skill-package
17861 skills
Install
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-core-notifications --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/frappe-core-notifications

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when implementing email notifications, system alerts, Assignment Rules, Auto Repeat, or ToDo items. Prevents misconfigured Email Accounts, broken notification templates, and silent delivery failures. Covers frappe.sendmail, Notification DocType, Email Account setup, Jinja

SKILL.md

frappe-core-notifications.SKILL.md
name: frappe-core-notifications
description: >
  Use when implementing email notifications, system alerts, Assignment Rules, Auto Repeat, or ToDo items.
  Prevents misconfigured Email Accounts, broken notification templates, and silent delivery failures.
  Covers frappe.sendmail, Notification DocType, Email Account setup, Jinja email templates, Assignment Rules, Auto Repeat scheduling, ToDo API.
  Keywords: notification, email, sendmail, Email Account, Assignment Rule, Auto Repeat, ToDo, alert, template, notify on approval, email when status changes, alert, email not sending, notification not working..
license: MIT
compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16."
metadata:
  author: OpenAEC-Foundation
  version: "2.0"

Frappe Notification System

Quick Reference

| Channel | Method | Use Case | |---------|--------|----------| | Email | `frappe.sendmail()` | Programmatic email with full control | | Email | Notification DocType (Email) | No-code email on document events | | System | `frappe.publish_realtime()` | In-app real-time alerts via socket.io | | System | Notification DocType (System) | No-code in-app alerts | | SMS | Notification DocType (SMS) | No-code SMS on document events | | Slack | Notification DocType (Slack) | No-code Slack webhook messages | | Assignment | `frappe.desk.form.assign_to.add()` | Assign document to user (creates ToDo) | | ToDo | `frappe.get_doc({"doctype": "ToDo", ...})` | Direct task creation | | Comment | `doc.add_comment("Comment", text)` | Timeline comment on document | | Tag | `doc.add_tag("tag_name")` | Document tagging for filtering |

---

Decision Tree

What notification mechanism do you need?
│
├─ Email on document event (no code)?
│  └─ Notification DocType → Channel: Email
│
├─ Programmatic email with custom logic?
│  └─ frappe.sendmail() in server script or hook
│
├─ Real-time in-app notification?
│  ├─ No-code → Notification DocType → Channel: System Notification
│  └─ Programmatic → frappe.publish_realtime()
│
├─ SMS on document event?
│  └─ Notification DocType → Channel: SMS (requires SMS Settings)
│
├─ Assign document to user?
│  ├─ No-code → Assignment Rule DocType
│  └─ Programmatic → frappe.desk.form.assign_to.add()
│
├─ Recurring document creation?
│  └─ Auto Repeat DocType
│
└─ Add comment or tag?
   ├─ Comment → doc.add_comment("Comment", text="...")
   └─ Tag → doc.add_tag("tag_name")

---

Notification DocType

The Notification DocType enables no-code alerts across four channels.

Event Triggers

| Event | Fires When | |-------|------------| | New | Document is created | | Save | Document is saved | | Submit | Document is submitted | | Cancel | Document is cancelled | | Value Change | Specific field value changes | | Days Before | N days before a date field value | | Days After | N days after a date field value | | Method | Custom Python method is called |

Condition Syntax

ALWAYS use Python expressions in the Condition field:

# Status-based
doc.status == "Open"

# Date-based
doc.due_date == nowdate()

# Threshold-based
doc.grand_total > 40000

# Combined
doc.status == "Overdue" and doc.grand_total > 10000

Available context: `doc`, `nowdate()`, `frappe.utils.*`.

Recipient Configuration

| Source | Description | |--------|-------------| | Document Field | Email/phone field on the document | | Role | All users with specified role | | Custom | Hard-coded email address | | All Assignees | All users assigned to the document | | Condition | Jinja expression to filter recipients |

Jinja Message Template

<h3>Order Overdue</h3>
<p>Transaction {{ doc.name }} has exceeded its due date.</p>

{% if comments %}
Last comment: {{ comments[-1].comment }} by {{ comments[-1].by }}
{% endif %}

<ul>
  <li>Customer: {{ doc.customer }}</li>
  <li>Amount: {{ doc.grand_total }}</li>
</ul>

Template variables: `{{ doc }}`, `{{ doc.fieldname }}`, `{{ comments }}`, `{{ nowdate() }}`.

Attach Print

Set **Attach Print** to include a PDF of the document. Select a **Print Format** for custom layout.

---

frappe.sendmail(): Programmatic Email

frappe.sendmail(
    recipients=["user@example.com"],       # list of email addresses
    subject="Invoice Due",                  # email subject
    message="<p>Your invoice is due.</p>",  # HTML body
    template="invoice_reminder",            # Jinja template name (optional)
    args={"customer": "ACME"},              # template context variables
    attachments=[{"fname": "inv.pdf", "fcontent": pdf_bytes}],
    reference_doctype="Sales Invoice",      # links email to document
    reference_name="SINV-00001",
    delayed=True,                           # queue via Email Queue (default)
    now=False,                              # True = send immediately, skip queue
    sender="noreply@example.com",           # override sender
    cc=["manager@example.com"],
    bcc=["audit@example.com"],
    reply_to="support@example.com",
    expose_recipients="header",             # show recipients in email header
)

**Rules**:

  • ALWAYS set `reference_doctype` and `reference_name` when the email relates to a document — this links the email in the document timeline.
  • NEVER set `now=True` in production — it blocks the request. Use `delayed=True` (default) to queue via Email Queue.
  • ALWAYS ensure an Email Account with "Enable Outgoing" is configured before calling `frappe.sendmail`.

Email Queue

Emails are queued in the **Email Queue** DocType and sent by the scheduler. Check queue status:

# Check pending emails
pending = frappe.get_all("Email Queue", filters={"status": "Not Sent"}, limit=10)

---

frappe.publish_realtime(): System Notifications

frappe.publish_realtime(
    event="msgprint",                      # event name
    message={"msg": "Task completed!"},    # dict payload
    user="user@example.com",               # target specific user
    doctype="Sales Invoice",
Read more
Ships withfrappe-claude-skill-package

60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations

Get the whole plugin
Stats
178
Stars
53
Forks
Maintained
Maintenance
Python
Language
2mo ago
Last commit
8mo ago
Created
14d ago
Added

Repo: Impertio-Studio/Frappe_Claude_Skill_Package