Skill125 estrellas del repoactualizado 2mo ago
frappe-core-notifications
>
Instalar en Claude Code
Copiargit 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-notificationsDespués abre una sesión nueva de Claude Code; el skill carga automáticamente.
Definición
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