Skip to main content
ClaudeWave
Skill125 estrellas del repoactualizado 2mo ago

frappe-core-notifications

>

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/Impertio-Studio/Frappe_Claude_Skill_Package /tmp/frappe-core-notifications && cp -r /tmp/frappe-core-notifications/skills/source/core/frappe-core-notifications ~/.claude/skills/frappe-core-notifications
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# 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:

```python
# 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

```html
<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

```python
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:

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

---

## frappe.publish_realtime(): System Notifications

```python
frappe.publish_realtime(
    event="msgprint",                      # event name
    message={"msg": "Task completed!"},    # dict payload
    user="user@example.com",               # target specific user
    doctype="Sales Invoice",               # broadcast to doctype room
    docname="SINV-00001",                  # broadcast to document room
    after_commit=True,                     # emit after transaction commits
)
```

### Room Types

| Room | Audience |
|------|----------|
| `user:{email}` | Single user (set `user=`) |
| `doctype:{dt}` | All users viewing that list |
| `doc:{dt}/{dn}` | All users viewing that document |
| `all` | All Desk users site-wide |
| `task_progress:{id}` | Background task progress |

### Built-in Events

| Event | Purpose |
|-------|---------|
| `msgprint` | Show message dialog to user |
| `list_update` | Refresh document list view |
| `docinfo_update` | Refresh document info sidebar |
| `progress` | Show progress bar |

ALWAYS set `after_commit=True` when