Notifications — Complete Setup (Email · Events · All Fields)
Table: sysevent_email_action (Notification)
Scope: HR Leave (x_786686_hr_leave)Fixes common mistakes:
- Table = HR Employee on notification form → wrong — must be Leave Request (x_786686_hr_leave_req_v2)
- Event not registered → notification never sends
- BR2/BR4 not active → event never queued
- PDI email not configured → notification runs but no mail
- Users/Groups in fields empty → no recipientالأسلوب: عربية + إنجليزية تكمّلان بعضهما — بدون ترجمة حرفية لأسماء الشاشات.
Architecture (how it works)
Leave Request state change
│
├─ submitted → BR2 → gs.eventQueue('...submitted') → Notification 1 → u_approver_user
├─ approved → BR4 → gs.eventQueue('...approved') → Notification 2 → u_requested_for_user
└─ rejected → BR4 → gs.eventQueue('...rejected') → Notification 3 → u_requested_for_user
| Step | Component | File |
|---|---|---|
| 1 | Event Registry (3 events) | ../events/events.md |
| 2 | BR2 fires submitted | ../business_rules/BR2_on_submit_event.js |
| 3 | BR4 fires approved / rejected | ../business_rules/BR4_on_approve_reject_event.js |
| 4 | Notifications (this doc) | 3 records on sysevent_email_action |
| 5 | Flow sets state after approval | ../../flow/approval_flow.md |
Phase 0 — Application scope (DO THIS FIRST)
Create notifications while HR Leave application is selected — not Global. — اختر تطبيق HR Leave من قائمة التطبيقات قبل New على الإشعار.
- Top-right Application picker → HR Leave.
- Verify notification Application field = HR Leave after save.
Phase 1 — Prerequisites (before Notification New)
1.1 Register events (mandatory)
Navigate: All > System Policy > Events > Registry → New (×3) — Open direct
| Field | Notification 1 | Notification 2 | Notification 3 |
|---|---|---|---|
| Name | x_786686_hr_leave.leave_v2.submitted | x_786686_hr_leave.leave_v2.approved | x_786686_hr_leave.leave_v2.rejected |
| Table | Leave Request / x_786686_hr_leave_req_v2 | same | same |
| Active | true | true | true |
| Description | Fired when leave submitted | Fired when approved | Fired when rejected |
بدون تسجيل الحدث في Registry، حقل Event name في الإشعار لن يجد الحدث أو لن يرسل.
Direct list: sysevent.list → filter Name contains leave_v2
1.2 Business rules that queue events
| Rule | Table | When | Order | Script file |
|---|---|---|---|---|
| BR2 | x_786686_hr_leave_req_v2 | after, insert+update | 200 | BR2_on_submit_event.js |
| BR4 | x_786686_hr_leave_req_v2 | after, update only | 250 | BR4_on_approve_reject_event.js |
Navigate: All > System Definition > Business Rules → verify Active = true. — Open direct
BR2 condition (in script): current.u_state.changesTo(‘submitted’)
BR4 condition (in script): changesTo(‘approved’) or changesTo(‘rejected’)
1.3 Users must have email
Navigate: All > User Administration > Users — Open direct
| User | Email required | Role in test |
|---|---|---|
| employee1 | yes | requester (u_requested_for_user) |
| manager1 | yes | approver (u_approver_user) |
BR1 must set u_approver_user from employee manager before submit — see approval_flow.md.
1.4 PDI / instance email (or notifications “succeed” with no inbox)
Navigate: All > System Properties > Email Properties — Open direct
| Check | Action |
|---|---|
| Email sending enabled | Configure SMTP or use System Mailboxes for dev |
| Outgoing email | Test from System Definition > Email > Email Client |
على PDI قد تحتاج Email Diagnostics أو صندوق وارد داخلي — راجع System Mailboxes.
Phase 2 — Open Notification form
Navigate: All > System Notification > Email > Notifications → New — Open direct
Direct: sysevent_email_action.do?sys_id=-1
Alternative paths (same table):
| Option | Navigate |
|---|---|
| A | All > System Notification > Email > Notifications · Open direct |
| B | Filter sysevent_email_action.list → Application = HR Leave |
| C | Studio → HR Leave → Create → Notification |
Phase 3 — Header fields (top of form — all 3 notifications)
Fill before tabs. These apply to every notification record.
| Field | Notification 1 | Notification 2 | Notification 3 |
|---|---|---|---|
| Name | HRLX Leave Submitted | HRLX Leave Approved | HRLX Leave Rejected |
| Table | Leave Request [x_786686_hr_leave_req_v2] | same | same |
| Active | ✓ checked | ✓ checked | ✓ checked |
| Category | Uncategorized or create HR Leave | same | same |
| Application | HR Leave | HR Leave | HR Leave |
| Allow Digest | ☐ unchecked (lab) | ☐ | ☐ |
Critical fix from your screenshot
Your form showed Table = HR Employee — change to Leave Request (x_786686_hr_leave_req_v2).
Events and fields (u_number, u_approver_user) are on the leave request table, not employee.
جدول الإشعار = جدول طلب الإجازة وليس جدول الموظف.
Advanced view (optional — click Advanced view at bottom)
| Field | Recommended value | Purpose |
|---|---|---|
| Weight | 0 (default) or 10 | Higher weight wins if multiple notifications match same event |
| Order | 100 | Processing order among notifications |
| Omit if already sent | false (lab) / true (prod optional) | Dedup same event+record |
| Send self | false | Don’t email the user who triggered |
| Include attachment | false | No attachments for leave |
| Importance | Normal | Email priority header |
Phase 4 — Tab: When to send
This matches your screenshot (Event is fired + event name).
4.1 Notification 1 — Leave Submitted
| Field | Value to enter |
|---|---|
| Send when | Event is fired |
| Event name | x_786686_hr_leave.leave_v2.submitted |
| Condition | (leave empty for lab) |
Optional condition (only notify when approver exists):
current.u_approver_user != ''
Or condition builder: Approver is not empty
4.2 Notification 2 — Leave Approved
| Field | Value |
|---|---|
| Send when | Event is fired |
| Event name | x_786686_hr_leave.leave_v2.approved |
| Condition | (empty) |
4.3 Notification 3 — Leave Rejected
| Field | Value |
|---|---|
| Send when | Event is fired |
| Event name | x_786686_hr_leave.leave_v2.rejected |
| Condition | (empty) |
Send when — other options (not used in this app)
| Send when | Use when |
|---|---|
| Event is fired | Our pattern — BR2/BR4 call gs.eventQueue |
| Record inserted | Direct insert trigger (no event) |
| Record updated | State change without event |
| Run script | Custom if in Advanced |
Phase 5 — Tab: Who will receive
This matches your screenshot (Users / Groups / Users-Groups in fields).
5.1 Notification 1 — to approver
| Field | Value |
|---|---|
| Users | (leave empty — use field instead) |
| Groups | (leave empty) |
| Users/Groups in fields | Approver → u_approver_user |
| Select target record | (empty — event passes record automatically) |
| Enter email address | (empty) |
| Subscribable | ☐ unchecked |
Steps in UI:
- In Users/Groups in fields, click the magnifier (reference).
- Table is already Leave Request — pick field u_approver_user (label may show Approver).
- Do not pick u_requested_for_user here — that is the employee, not the manager. — المستلم = حقل u_approver_user (المدير المعتمد).
5.2 Notification 2 & 3 — to requester
| Field | Value |
|---|---|
| Users/Groups in fields | Requested For → u_requested_for_user |
| All other recipient fields | empty |
Recipient options (A / B / C)
| Option | When | Config |
|---|---|---|
| A — Field on record | Recommended | Users/Groups in fields = u_approver_user or u_requested_for_user |
| B — Fixed user | Lab only | Users = pick manager1 |
| C — Script (Advanced) | Dynamic logic | Advanced view → recipient script |
Option C example (notify approver + HR admin):
// Recipients script (Advanced) — optional
var recipients = [];
if (current.u_approver_user)
recipients.push(current.u_approver_user.toString());
// add hr admin group member if needed
return recipients;
Phase 6 — Tab: What it will contain
This matches your screenshot (Email template, Subject, Message HTML, Select variables).
6.1 Email template field
| Option | Value |
|---|---|
| A — No template (recommended for lab) | Leave Email template empty — use Subject + Message HTML below |
| B — Use template | Pick template — then Subject/HTML here override template unless left blank |
Blue info banner on form:
When using an Email Template, Subject and Message are picked from template unless specified here.
6.2 Notification 1 — Submitted (full content)
| Field | Value |
|---|---|
| Subject | Leave ${u_number} needs your approval |
| Message HTML | see below |
Message HTML (paste in editor, or use Select variables → Fields):
<p>Hi,</p>
<p>A leave request <strong>${u_number}</strong> was submitted and needs your approval.</p>
<ul>
<li><strong>Requested for:</strong> ${u_requested_for_user}</li>
<li><strong>Type:</strong> ${u_leave_type}</li>
<li><strong>Dates:</strong> ${u_start_date} to ${u_end_date}</li>
<li><strong>Days:</strong> ${u_days_count}</li>
<li><strong>Reason:</strong> ${u_reason}</li>
</ul>
<p><a href="${URI_REF}">Open leave request</a></p>
Select variables sidebar (insert these):
| Variable | Field on x_786686_hr_leave_req_v2 |
|---|---|
| ${u_number} | Number |
| ${u_requested_for_user} | Requested For |
| ${u_leave_type} | Leave Type |
| ${u_start_date} | Start Date |
| ${u_end_date} | End Date |
| ${u_days_count} | Days |
| ${u_reason} | Reason |
| ${URI_REF} | System variable — link to record |
| ${mail_script:…} | Advanced — only if using mail script |
6.3 Notification 2 — Approved
| Field | Value |
|---|---|
| Subject | Your leave ${u_number} was approved |
| Message HTML |
<p>Hi ${u_requested_for_user},</p>
<p>Your leave request <strong>${u_number}</strong> has been <strong>approved</strong>.</p>
<p><strong>Type:</strong> ${u_leave_type}<br/>
<strong>From:</strong> ${u_start_date} <strong>To:</strong> ${u_end_date}<br/>
<strong>Days:</strong> ${u_days_count}</p>
<p><a href="${URI_REF}">View request</a></p>
6.4 Notification 3 — Rejected
| Field | Value |
|---|---|
| Subject | Your leave ${u_number} was rejected |
| Message HTML |
<p>Hi ${u_requested_for_user},</p>
<p>Your leave request <strong>${u_number}</strong> was <strong>rejected</strong>.</p>
<p>Please contact your manager or HR if you have questions.</p>
<p><a href="${URI_REF}">View request</a></p>
Message type options
| Option | Field | When |
|---|---|---|
| HTML | Message HTML | Default — rich email |
| Plain text | Message plain text (Advanced view) | Plain-mail clients |
| SMS | SMS message | Mobile — not used here |
Phase 7 — Submit and verify
- Click Submit (top-right or bottom).
- Repeat Phases 3–6 for all 3 notifications.
- Open list: sysevent_email_action.list → filter Application = HR Leave → expect 3 active rows.
Phase 8 — End-to-end test
8.1 Test submitted → approver email
| Step | Action | Verify |
|---|---|---|
| 1 | Login as employee1 | |
| 2 | New x_786686_hr_leave_req_v2 — fill dates, type | u_approver_user = manager |
| 3 | Set State = submitted → Save | |
| 4 | Check events | All > System Logs > Events filter leave_v2.submitted · Open direct |
| 5 | Check email | Approver inbox / sys_email list |
| 6 | Check notification log | sysevent_email_action.list → open record → Email Logs related list |
8.2 Test approved → requester email
| Step | Action |
|---|---|
| 1 | Login as manager1 |
| 2 | Approve via Flow / My Approvals |
| 3 | State → approved |
| 4 | Event leave_v2.approved in log |
| 5 | Email to employee1 |
8.3 Test rejected
Same as 8.2 but Reject → event leave_v2.rejected → email to requester.
8.4 Script to confirm events (Background Scripts)
var e = new GlideRecord('sysevent');
e.addQuery('name', 'x_786686_hr_leave.leave_v2.submitted');
e.orderByDesc('sys_created_on');
e.setLimit(5);
e.query();
while (e.next())
gs.info(e.name + ' parm1=' + e.parm1 + ' parm2=' + e.parm2 + ' created=' + e.sys_created_on);
Phase 9 — Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No Event name in dropdown | Event not in Registry | Phase 1.1 |
| Event in log, no email | SMTP / PDI email off | Phase 1.4 |
| Event never in log | BR2/BR4 inactive or wrong table | Phase 1.2 |
| Wrong recipient | Wrong field in Users/Groups in fields | Phase 5 |
| Empty approver email | u_approver_user blank | BR1 + employee u_manager |
| Notification on wrong table | Table = Employee | Table = Leave Request |
| Duplicate emails | Multiple notifications same event | Set Weight / dedup |
| Approved but no mail | BR4 missing | Add BR4_on_approve_reject_event.js |
| ${field} shows blank | Wrong table on notification | Fix Table field |
| Link broken in email | Use ${URI_REF} not hard-coded URL | Phase 6 |
Options & alternatives
| Topic | Option A (this guide) | Option B | Option C |
|---|---|---|---|
| Trigger | Event + BR2/BR4 | Record updated notification | Flow Send Email action |
| Recipients | Field on record | Fixed user/group | Script |
| Content | Subject + Message HTML | Email Template | Notification Script |
| Approval path | Flow → state → BR4 | BR only | Manual state change (lab) |
Flow alternative (skip BR4 for approved/rejected):
After Update Record in Flow, add Run Script:
gs.eventQueue('x_786686_hr_leave.leave_v2.approved', fd_data.trigger_record,
fd_data.trigger_record.u_requested_for_user, fd_data.trigger_record.u_number);
Checklist — copy before go-live
- [ ] Application = HR Leave (not Global)
- [ ] 3 events in Event Registry on table x_786686_hr_leave_req_v2
- [ ] BR2 active (submitted)
- [ ] BR4 active (approved / rejected)
- [ ] 3 notifications — Table = Leave Request (not Employee)
- [ ] When to send = Event is fired + correct event name each
- [ ] Who will receive = u_approver_user / u_requested_for_user
- [ ] Subject + Message HTML filled (or template)
- [ ] Requester + approver users have email
- [ ] Flow approval updates u_state to approved/rejected
- [ ] E2E test: submit → approve → reject
- [ ] Update Set captures notification records
Related files
| File | Purpose |
|---|---|
| ../events/events.md | Event registry + gs.eventQueue |
| ../business_rules/BR2_on_submit_event.js | Submitted event |
| ../business_rules/BR4_on_approve_reject_event.js | Approved / rejected events |
| ../../flow/approval_flow.md | Flow sets state after approval |
| ../../../06_NOTIFICATIONS_EVENTS_JOBS.md | Summary chapter |
| ../../../02_ADMINISTRATION.md § Users | Test users + email |