Apex ํธ๋ฆฌ๊ฑฐ ์์ํ๊ธฐ
ํ์ต ๋ชฉํ
์ด ์ ๋์ ์๋ฃํ๋ฉด ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
- Salesforce ๊ฐ์ฒด์ ๋ํ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
- ํธ๋ฆฌ๊ฑฐ ์ปจํ
์คํธ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ํธ๋ฆฌ๊ฑฐ์์ ํด๋์ค ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
- ํธ๋ฆฌ๊ฑฐ์ sObject
addError()๋งค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฅ ์์ ์ ์ ํํ ์ ์์ต๋๋ค.
์์ํ๊ธฐ ์ ์
Apex ํธ๋ฆฌ๊ฑฐ๋ ์ ์ฉํ๊ณ ์ฌ๋ฏธ์์ผ๋ฉฐ ํ๋ฅญํฉ๋๋ค. ์ด ๋ชจ๋์ ํตํด ์ด๋ฌํ ๊ธฐ๋ฅ์ ์์ํ ์๋ ์์ผ๋ฉฐ ๋ค๋ฅธ Salesforce ๊ธฐ๋ฅ๋ ์ ์ ์๊ธฐ ๋๋ฌธ์ Apex ํธ๋ฆฌ๊ฑฐ์ ์ฑ๋ฅ์ ํ์ธํ ์๋ ์์ต๋๋ค. ์ด ๋ชจ๋์ ์ต๋ํ ํ์ฉํ๋ ค๋ฉด ๋จผ์ ๋ค์ ๋ชจ๋์ ํ์ธํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
-
๋น ๋ฅธ ์์: Apex
-
Apex ๊ธฐ๋ณธ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค
-
๊ด๋ฆฌ์๋ฅผ ์ํ SOQL
-
Developer Console ๊ธฐ์ด
Apex ํธ๋ฆฌ๊ฑฐ ์์ฑํ๊ธฐ
Apex ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ์ , ์ ๋ฐ์ดํธ ๋๋ ์ญ์ ์ ๊ฐ์ Salesforce์ ๋ ์ฝ๋์ ๋ํ ์ด๋ฒคํธ ์ ํ์ ๋ง์ถคํ ์์ ์ ์ํํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ง์ํ๋ ๊ฒ๊ณผ ๊ฐ์ด Apex๋ ๋ ์ฝ๋ ๊ด๋ฆฌ๋ฅผ ์ํ ํธ๋ฆฌ๊ฑฐ ์ง์์ ์ ๊ณตํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ์์ ์ ์ํํ๊ฑฐ๋ ๊ด๋ จ ๋ ์ฝ๋๋ฅผ ์์ ํ๊ฑฐ๋ ํน์ ์์ ์ด ๋ฐ์ํ์ง ์๋๋ก ์ ํํฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํ์ฌ SOQL ๋ฐ DML ์คํ ๋๋ ๋ง์ถคํ Apex ๋ฉ์๋ ํธ์ถ์ ํฌํจํ์ฌ Apex์์ ํ ์ ์๋ ๋ชจ๋ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํ์ฌ Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ํฌ์ธํธ ์ค ํด๋ฆญ ๋๊ตฌ๋ก ์ํ ๋ถ๊ฐ๋ฅํ ์์ ์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํ๋ ๊ฐ์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๊ฑฐ๋ ๋ ์ฝ๋์ ํ๋๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ฒฝ์ฐ ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น๊ณผ ํ๋ก๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฑ๋ฅ๊ณผ ํ์ฅ์ด ์ค์ํ๊ฑฐ๋, ํฌ์ธํธ ์ค ํด๋ฆญ ๋๊ตฌ์ฉ์ผ๋ก๋ ๋ ผ๋ฆฌ๊ฐ ๋๋ฌด ๋ณต์กํ๊ฑฐ๋, CPU์ ๋ถ๋ด์ ์ฃผ๋ ์์ ์ ์คํํ ๋๋ Apex ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๊ณ์ ๋๋ ์ฐ๋ฝ์ฒ์ ๊ฐ์ ์ต์์ ํ์ค ๊ฐ์ฒด, ๋ง์ถคํ ๊ฐ์ฒด ๋ฐ ์ผ๋ถ ํ์ค ํ์ ๊ฐ์ฒด์ ๋ํด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ ์์ฑ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋ฉ๋๋ค. Salesforce๋ ์ง์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์๋์ผ๋ก ํ์ฑ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์คํํฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ ๊ตฌ๋ฌธ
ํธ๋ฆฌ๊ฑฐ ์ ์์ ๊ตฌ๋ฌธ์ ํด๋์ค ์ ์์ ๊ตฌ๋ฌธ๊ณผ ๋ค๋ฆ
๋๋ค. ํธ๋ฆฌ๊ฑฐ ์ ์๋ trigger ํค์๋๋ก ์์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํธ๋ฆฌ๊ฑฐ ์ด๋ฆ, ํธ๋ฆฌ๊ฑฐ๊ฐ ์ฐ๊ฒฐ๋ Salesforce ๊ฐ์ฒด ๋ฐ ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋๋ ์กฐ๊ฑด์ด ๋ฐ๋ฆ
๋๋ค. ํธ๋ฆฌ๊ฑฐ์ ๊ตฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
trigger TriggerName on ObjectName (trigger_events) {
code_block
}์ฝ์ , ์ ๋ฐ์ดํธ, ์ญ์ ๋ฐ ์ญ์ ์ทจ์ ์์ ์ ํ์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์คํํ๋ ค๋ฉด ์ผํ๋ก ๊ตฌ๋ถ๋ ๋ชฉ๋ก์ ์ฌ๋ฌ ํธ๋ฆฌ๊ฑฐ ์ด๋ฒคํธ๋ฅผ ์ง์ ํฉ๋๋ค. ์ง์ ํ ์ ์๋ ์ด๋ฒคํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
-
before insert(์ฝ์ ์ ) -
before update(์ ๋ฐ์ดํธ ์ ) -
before delete(์ญ์ ํ) -
after insert(์ฝ์ ํ) -
after update(์ ๋ฐ์ดํธ ํ) -
after delete(์ญ์ ํ) -
after undelete(์ญ์ ์ทจ์ ํ)
ํธ๋ฆฌ๊ฑฐ ์์
์ด ๊ฐ๋จํ ํธ๋ฆฌ๊ฑฐ๋ ๊ณ์ ์ ์ฝ์ ํ๊ณ ๋๋ฒ๊ทธ ๋ก๊ทธ์ ๋ฉ์์ง๋ฅผ ์ฐ๊ธฐ ์ ์ ์คํ๋ฉ๋๋ค.
- Developer Console์์ File(ํ์ผ) | New(์๋ก ๋ง๋ค๊ธฐ) | Apex Trigger(Apex ํธ๋ฆฌ๊ฑฐ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ํธ๋ฆฌ๊ฑฐ ์ด๋ฆ์
HelloWorldTrigger๋ฅผ ์ ๋ ฅํ ๋ค์ sObject์ ๋ํ Account(๊ณ์ )๋ฅผ ์ ํํฉ๋๋ค. Submit(์ ์ถ)์ ํด๋ฆญํฉ๋๋ค.
- ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ๋ค์์ผ๋ก ๋ฐ๊ฟ๋๋ค.
trigger HelloWorldTrigger on Account (before insert) {
System.debug('Hello World!');
}- ์ ์ฅํ๋ ค๋ฉด Ctrl+S๋ฅผ ๋๋ฆ
๋๋ค.
- ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ
์คํธํ๋ ค๋ฉด ๊ณ์ ์ ๋ง๋ญ๋๋ค.
-
Debug(๋๋ฒ๊ทธ) | Open Execute Anonymous Window(์ต๋ช
์คํ ์ฐฝ ์ด๊ธฐ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ์ ์ฐฝ์์ ๋ค์์ ์ถ๊ฐํ ๋ค์ Execute(์คํ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
Account a = new Account(Name='Test Trigger'); insert a;
- ๋๋ฒ๊ทธ ๋ก๊ทธ์์
Hello World!๊ตฌ๋ฌธ์ ์ฐพ์ต๋๋ค. ๋ํ ๋ก๊ทธ๋ ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋์์์ ๋ณด์ฌ์ค๋๋ค.
ํธ๋ฆฌ๊ฑฐ ์ ํ
ํธ๋ฆฌ๊ฑฐ์๋ ๋ ๊ฐ์ง ์ ํ์ด ์์ต๋๋ค.
-
Before triggers - ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ธฐ ์ ์ ๋ ์ฝ๋ ๊ฐ์ ์
๋ฐ์ดํธํ๊ฑฐ๋ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
-
After triggers - ์์คํ
์์ ์ค์ ํ ํ๋ ๊ฐ(์: ๋ ์ฝ๋์
Id๋๋LastModifiedDateํ๋)์ ์ก์ธ์ค ๋ฐ ๋ค๋ฅธ ๋ ์ฝ๋์ ๋ณ๊ฒฝ ์ฌํญ์ ์ํฅ์ ๋ฏธ์น๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. after trigger๊ฐ ๋ฐ์ํ ๋ ์ฝ๋๋ ์ฝ๊ธฐ ์ ์ฉ์ ๋๋ค.
์ปจํ ์คํธ ๋ณ์ ์ฌ์ฉ
ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ฐ์ํ ๋ ์ฝ๋์ ์ก์ธ์คํ๋ ค๋ฉด ์ปจํ
์คํธ ๋ณ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด Trigger.new์๋ ํธ๋ฆฌ๊ฑฐ ์ฝ์
๋๋ ์
๋ฐ์ดํธ์ ์ฝ์
๋ ๋ชจ๋ ๋ ์ฝ๋๊ฐ ํฌํจ๋ฉ๋๋ค. Trigger.old์์ ํธ๋ฆฌ๊ฑฐ ์
๋ฐ์ดํธ์ ์
๋ฐ์ดํธ๋๊ธฐ ์ ์ sObject ์ด์ ๋ฒ์ ๋๋ ํธ๋ฆฌ๊ฑฐ ์ญ์ ์์ ์ญ์ ๋ sObject ๋ชฉ๋ก์ ์ ๊ณตํฉ๋๋ค. ํ๋์ ๋ ์ฝ๋๊ฐ ์ฝ์
๋๊ฑฐ๋ API ๋๋ Apex๋ฅผ ํตํด ๋ง์ ๋ ์ฝ๋๊ฐ ๋๋์ผ๋ก ์ฝ์
๋ ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ Trigger.new์ ๊ฐ์ ์ปจํ
์คํธ ๋ณ์์ ํ๋์ ๋ ์ฝ๋๋ง ๋๋ ์ฌ๋ฌ ๋ ์ฝ๋๋ฅผ ํฌํจํ ์ ์์ต๋๋ค. Trigger.new๋ฅผ ๋ฐ๋ณตํ์ฌ ๊ฐ ๊ฐ๋ณ sObject๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ด ์์ ๋ HelloWorldTrigger ์์ ํธ๋ฆฌ๊ฑฐ์ ์์ ๋ ๋ฒ์ ์
๋๋ค. for ๋ฃจํ์์ ๊ฐ ๊ณ์ ์ ๋ฐ๋ณตํ๊ณ ๊ฐ๊ฐ์ ๋ํ Description(์ค๋ช
) ํ๋๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
trigger HelloWorldTrigger on Account (before insert) {
for(Account a : Trigger.new) {
a.Description = 'New description';
}
}์ผ๋ถ ๋ค๋ฅธ ์ปจํ ์คํธ ๋ณ์๋ ์ ๋ฐ์ดํธ ๋๋ ๊ธฐํ ์ด๋ฒคํธ๋ก ์ธํด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ์ธ ๊ฐ์ ๋ฐํํฉ๋๋ค. ์ด๋ฌํ ๋ณ์๋ ํธ๋ฆฌ๊ฑฐ๊ฐ ์ฌ๋ฌ ์ด๋ฒคํธ๋ฅผ ๊ฒฐํฉํ ๋ ์ ์ฉํฉ๋๋ค. ๋ค์์ ์๋ฅผ ํ์ธํด ๋ณด์ธ์.
trigger ContextExampleTrigger on Account (before insert, after insert, after delete) {
if (Trigger.isInsert) {
if (Trigger.isBefore) {
// Process before insert
} else if (Trigger.isAfter) {
// Process after insert
}
}
else if (Trigger.isDelete) {
// Process after delete
}
}
๋ค์ ํ๋ ํธ๋ฆฌ๊ฑฐ์ ์ฌ์ฉํ ์ ์๋ ๋ชจ๋ ์ปจํ ์คํธ ๋ณ์์ ํฌ๊ด์ ์ธ ๋ชฉ๋ก์ ๋๋ค.
๋ณ์ |
์ฌ์ฉ |
|---|---|
isExecuting |
Apex ์ฝ๋์ ํ์ฌ ์ปจํ
์คํธ๊ฐ Visualforce ํ์ด์ง, ์น ์๋น์ค ๋๋ |
isInsert |
Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค, Apex ๋๋ API์์ ์ฝ์
์์
์ผ๋ก ์ธํด ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
isUpdate |
Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค, Apex ๋๋ API์์ ์
๋ฐ์ดํธ ์์
์ผ๋ก ์ธํด ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
isDelete |
Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค, Apex ๋๋ API์์ ์ญ์ ์์
์ผ๋ก ์ธํด ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
isBefore |
๋ ์ฝ๋๊ฐ ์ ์ฅ๋๊ธฐ ์ ์ ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
isAfter |
๋ชจ๋ ๋ ์ฝ๋๊ฐ ์ ์ฅ๋ ํ์ ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
isUndelete |
Recycle Bin(ํด์งํต)์์ ๋ ์ฝ๋๋ฅผ ๋ณต๊ตฌํ ํ ์ด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ |
new |
sObject ๋ ์ฝ๋์ ์ ๋ฒ์ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ์ด sObject ๋ชฉ๋ก์ |
newMap |
sObject ๋ ์ฝ๋์ ์ ๋ฒ์ ์ ๋ํ ID ์ง๋์ ๋๋ค. ์ด ์ง๋๋ |
old |
sObject ๋ ์ฝ๋์ ์ด์ ๋ฒ์ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ์ด sObject ๋ชฉ๋ก์ |
oldMap |
sObject ๋ ์ฝ๋์ ์ด์ ๋ฒ์ ์ ๋ํ ID ์ง๋์ ๋๋ค. ์ด ์ง๋๋ |
operationType |
ํ์ฌ ์์ ์ ํด๋นํ๋ System.TriggerOperation ์ ํ์ ์ด๊ฑฐํ์ ๋ฐํํฉ๋๋ค.
|
size |
ํธ๋ฆฌ๊ฑฐ ํธ์ถ์์ ์ฒ๋ฆฌ๋๋ ๋ ์ฝ๋ ๊ฐ์์
๋๋ค. 200๊ฐ ์ด๊ณผ์ ๋ ์ฝ๋๋ฅผ ํฌํจํ๋ DML ์์
์ ๋ฐฐ์น ๋จ์๋ก ์ฒ๋ฆฌ๋๋ฉฐ, ํธ๋ฆฌ๊ฑฐ๋ ๊ฐ ๋ฐฐ์น์ ๋ํด ํธ์ถ๋ฉ๋๋ค. |
ํธ๋ฆฌ๊ฑฐ์์ ํด๋์ค ๋ฉ์๋ ํธ์ถํ๊ธฐ
ํธ๋ฆฌ๊ฑฐ์์ ๊ณต์ฉ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ฝ๋ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ ํธ๋ฆฌ๊ฑฐ ํฌ๊ธฐ๊ฐ ์ค์ด๋ค๋ฉฐ Apex ์ฝ๋์ ์ ์ง ๊ด๋ฆฌ๊ฐ ํฅ์๋ฉ๋๋ค. ๋ํ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์ ์์ ํธ๋ฆฌ๊ฑฐ๋ ํธ๋ฆฌ๊ฑฐ์์ ์ ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ฝ์
์ด๋ฒคํธ๋ก ์ธํด ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ฒฝ์ฐ ์์ ์์ CustomContactNotification ํด๋์ค์ ๋ํ ์ ์ notifyUsers() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. ์ด ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ ํธ๋ฆฌ๊ฑฐ์ ์ ์๋ Salesforce ์ฌ์ฉ์์๊ฒ ์ฌ์ฉ์ ์ ์ ์๋ฆผ์ ์ ์กํฉ๋๋ค. ์๋ฆผ์๋ ์ฝ์
๋ ์ฐ๋ฝ์ฒ ๋ ์ฝ๋์ ์๊ฐ ํฌํจ๋ฉ๋๋ค.
- ๋ฐ์คํฌํฑ ์ฌ์ฉ์ ์ ์ ์๋ฆผ ์์ฑํ๊ธฐ.
- Setup(์ค์ )์์ Quick Find(๋น ๋ฅธ ์ฐพ๊ธฐ) ์์์
Notification Builder(์๋ฆผ ๋น๋)๋ฅผ ์ ๋ ฅํ ํ Custom Notifications(์ฌ์ฉ์ ์ ์ ์๋ฆผ)๋ฅผ ์ ํํฉ๋๋ค.
-
New(์๋ก ๋ง๋ค๊ธฐ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ์ฌ์ฉ์ ์ ์ ์๋ฆผ ์ด๋ฆ์
New Contact Notification(์ ์ฐ๋ฝ์ฒ ์๋ฆผ)์ ์ ๋ ฅํฉ๋๋ค.
- API Name(API ์ด๋ฆ)์
New_Contact_Notification์ ์ ๋ ฅํฉ๋๋ค.
- ์ง์๋๋ ์ฑ๋์์ Desktop(๋ฐ์คํฌํฑ)์ ์ ํํฉ๋๋ค.
-
Save(์ ์ฅ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- Setup(์ค์ )์์ Quick Find(๋น ๋ฅธ ์ฐพ๊ธฐ) ์์์
- Developer Console์์ File(ํ์ผ) | New(์๋ก ๋ง๋ค๊ธฐ) | Apex Class(Apex ํด๋์ค)๋ฅผ ํด๋ฆญํฉ๋๋ค.
-
CustomContactNotification์ ์ ๋ ฅํ๊ณ OK(ํ์ธ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ๊ธฐ๋ณธ ํด๋์ค ๋ณธ๋ฌธ์ ์๋์ ์ ์๋
CustomContactNotificationํด๋์ค ์์๋ก ๋ณ๊ฒฝํฉ๋๋ค.
public with sharing class CustomContactNotification {
// Public method
public static void notifyUsers(Set<String> recipientsIds, Integer recordCount) {
// Get the ID for the custom notification type created in Setup
CustomNotificationType notificationType =
[SELECT Id, DeveloperName
FROM CustomNotificationType
WHERE DeveloperName='New_Contact_Notification'];
// Create a new custom notification
Messaging.CustomNotification notification = new Messaging.CustomNotification();
// Set the contents for the notification
notification.setTitle('Trailhead Trigger Tutorial');
notification.setBody(recordCount + ' contact(s) were inserted.');
// Set the notification type and target
notification.setNotificationTypeId(notificationType.Id);
// '000000000000000AAA' is a dummy targetId value
notification.setTargetId('000000000000000AAA');
// Send the notification
try {
notification.send(recipientsIds);
System.debug('Custom notification sent successfully.');
}
catch (Exception e) {
System.debug('Problem sending notification: ' + e.getMessage());
}
}
}- Developer Console์์ File(ํ์ผ) | New(์๋ก ๋ง๋ค๊ธฐ) | Apex Trigger(Apex ํธ๋ฆฌ๊ฑฐ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ํธ๋ฆฌ๊ฑฐ ์ด๋ฆ์
ContactNotificationTrigger๋ฅผ ์ ๋ ฅํ ๋ค์ sObject์ ๋ํ Contact(์ฐ๋ฝ์ฒ)๋ฅผ ์ ํํฉ๋๋ค. Submit(์ ์ถ)์ ํด๋ฆญํฉ๋๋ค.
- ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ๋ค์์ผ๋ก ๋ฐ๊ฟ๋๋ค.
trigger ContactNotificationTrigger on Contact (after insert, after delete) {
if (Trigger.isInsert) {
Integer recordCount = Trigger.new.size();
// Set the recipientIDs to the current user
Set<String> recipientIDs = new Set<String>{UserInfo.getUserId()};
// Call a utility method from another class
CustomContactNotification.notifyUsers(recipientIDs, recordCount);
}
else if (Trigger.isDelete) {
// Process after delete
}
}- ์ ์ฅํ๋ ค๋ฉด Ctrl+S๋ฅผ ๋๋ฆ
๋๋ค.
- ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ
์คํธํ๋ ค๋ฉด ์ฐ๋ฝ์ฒ๋ฅผ ๋ง๋ญ๋๋ค.
-
Debug(๋๋ฒ๊ทธ) | Open Execute Anonymous Window(์ต๋ช
์คํ ์ฐฝ ์ด๊ธฐ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ์ ์ฐฝ์์ ๋ค์์ ์ถ๊ฐํ ๋ค์ Execute(์คํ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
Contact c = new Contact(LastName='Test Contact'); insert c;
- ๋๋ฒ๊ทธ ๋ก๊ทธ์์ ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋์๋์ง ํ์ธํฉ๋๋ค. ๋ก๊ทธ ๋๋ถ๋ถ์์ ์ ํธ๋ฆฌํฐ ๋ฉ์๋(
DEBUG|Custom notification sent successfully.)๋ก ์์ฑ๋ ๋๋ฒ๊ทธ ๋ฉ์์ง๋ฅผ ์ฐพ์ต๋๋ค. - ์ด์ ์๋ฆผ์ด ์์ ๋์๋์ง ํ์ธํฉ๋๋ค. ์๋ฆผ ํจ๋์ ์ด๋ ค๋ฉด
๋ฅผ ํด๋ฆญํ์ธ์. ์ ๋ชฉ์ด 'Trailhead Trigger Tutorial'์ด๊ณ ๋ณธ๋ฌธ์ด '1 contact(s) were inserted(1๊ฐ์ ์ฐ๋ฝ์ฒ๊ฐ ์ฝ์
๋์์ต๋๋ค)'์ธ ์๋ฆผ์ด ํ์๋์ด์ผ ํฉ๋๋ค.
์ ํธ๋ฆฌ๊ฑฐ๊ฐ ์์ผ๋ฉด ์ฐ๋ฝ์ฒ๋ฅผ ํ๋ ์ด์ ์ถ๊ฐํ ๋๋ง๋ค ์ฌ์ฉ์ ์ ์ ๋ฐ์คํฌํฑ ์๋ฆผ์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
๊ด๋ จ ๋ ์ฝ๋ ์ถ๊ฐํ๊ธฐ
ํธ๋ฆฌ๊ฑฐ๋ ์ข ์ข ํธ๋ฆฌ๊ฑฐ ์ปจํ ์คํธ์ ๋ ์ฝ๋(์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ฐ์์ํจ ๋ ์ฝ๋)์ ๊ด๋ จ๋ ๋ ์ฝ๋์ ์ก์ธ์คํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์ด ํธ๋ฆฌ๊ฑฐ๋ ๊ธฐํ๊ฐ ์ด๋ฏธ ๊ณ์ ๊ณผ ์ฐ๊ฒฐ๋์ด ์์ง ์์ ๊ฒฝ์ฐ ์ ๊ณ์ ๋๋ ์
๋ฐ์ดํธ๋ ๊ฐ ๊ณ์ ์ ๋ํ ๊ด๋ จ ๊ธฐํ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ ๋จผ์ SOQL ์ฟผ๋ฆฌ๋ฅผ ์ํํ์ฌ ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋ ๊ณ์ ์ ๋ํ ๋ชจ๋ ํ์ ๊ธฐํ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๋ค์์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋ Trigger.new์ sObject ๋ชฉ๋ก์ ๋ฐ๋ณตํ์ฌ ๊ฐ ๊ณ์ sObject๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๊ณ์ ์ ๊ด๋ จ๋ ๊ธฐํ sObject๊ฐ ์๋ ๊ฒฝ์ฐ for ๋ฃจํ๋ ๊ธฐํ๋ฅผ ๋ง๋ญ๋๋ค. ํธ๋ฆฌ๊ฑฐ๊ฐ ์๋ก์ด ๊ธฐํ๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ์ต์ข
๋ช
๋ น๋ฌธ์ด ์ด๋ฅผ ์ฝ์
ํฉ๋๋ค.
- Developer Console์ ์ฌ์ฉํ์ฌ ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค(
HelloWorldTrigger์์ ์ ๋จ๊ณ๋ฅผ ๋ฐ๋ฅด์ง๋ง ํธ๋ฆฌ๊ฑฐ ์ด๋ฆ์ ๋ํดAddRelatedRecord๋ฅผ ์ฌ์ฉํฉ๋๋ค).
trigger AddRelatedRecord on Account(after insert, after update) {
List<Opportunity> oppList = new List<Opportunity>();
// Get the related opportunities for the accounts in this trigger
Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
[SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.new]);
// Add an opportunity for each account if it doesn't already have one.
// Iterate through each account.
for(Account a : Trigger.new) {
System.debug('acctsWithOpps.get(a.Id).Opportunities.size()=' + acctsWithOpps.get(a.Id).Opportunities.size());
// Check if the account already has a related opportunity.
if (acctsWithOpps.get(a.Id).Opportunities.size() == 0) {
// If it doesn't, add a default opportunity
oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
StageName='Prospecting',
CloseDate=System.today().addMonths(1),
AccountId=a.Id));
}
}
if (oppList.size() > 0) {
insert oppList;
}
}- ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ
์คํธํ๋ ค๋ฉด Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ๊ณ์ ์ ๋ง๋ค๊ณ
Apples & Oranges(์ฌ๊ณผ ๋ฐ ์ค๋ ์ง)๋ก ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
- ๊ณ์ ํ์ด์ง์ ๊ธฐํ ๊ด๋ จ ๋ชฉ๋ก์์ ์ ๊ธฐํ๋ฅผ ์ฐพ์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ๊ฐ ์ด ๊ธฐํ๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํ์ต๋๋ค.
ํธ๋ฆฌ๊ฑฐ ์์ธ ์ฌ์ฉํ๊ธฐ
ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ๋ ์ฝ๋๊ฐ ์ ์ฅ๋์ง ์๋๋ก ํ๋ ๊ฒ๊ณผ ๊ฐ์ด ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์
์ ๋ํ ์ ํ์ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ์ ๋ ์ฝ๋๊ฐ ์ ์ฅ๋์ง ์๋๋ก ํ๋ ค๋ฉด ๋ฌธ์ ๊ฐ ๋๋ sObject์ ๋ํ addError() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. addError() ๋ฉ์๋๋ ํธ๋ฆฌ๊ฑฐ ๋ด๋ถ์์ ์น๋ช
์ ์ธ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ์ค๋ฅ ๋ฉ์์ง๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ํ์๋๊ณ ๊ธฐ๋ก๋ฉ๋๋ค.
๋ค์ ํธ๋ฆฌ๊ฑฐ๋ ๊ด๋ จ ๊ธฐํ๊ฐ ์๋ ๊ฒฝ์ฐ ๊ณ์ ์ด ์ญ์ ๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณ์ ์ ์ญ์ ํ๋ฉด ๋ชจ๋ ๊ด๋ จ ๋ ์ฝ๋๊ฐ ๊ณ๋จ์์ผ๋ก ์ญ์ ๋ฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ ๊ธฐํ์ ๊ณ๋จ์ ์ญ์ ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ง์ ์ฌ์ฉํด ๋ณด์ธ์. ์ด์ ์์ ๋ฅผ ์คํํ ๊ฒฝ์ฐ ์กฐ์ง์ ๊ด๋ จ ๊ธฐํ๊ฐ ์๋ Apples & Oranges๋ผ๋ ๊ณ์ ์ด ์์ต๋๋ค. ์ด ์์ ์์ ํด๋น ์ํ ๊ณ์ ์ ์ฌ์ฉํฉ๋๋ค.
- Developer Console์ ์ฌ์ฉํ์ฌ ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
trigger AccountDeletion on Account (before delete) {
// Prevent the deletion of accounts if they have related opportunities.
for (Account a : [SELECT Id FROM Account
WHERE Id IN (SELECT AccountId FROM Opportunity) AND
Id IN :Trigger.old]) {
Trigger.oldMap.get(a.Id).addError(
'Cannot delete account with related opportunities.');
}
}- Salesforce ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์
Apples & Oranges๊ณ์ ํ์ด์ง๋ก ์ด๋ํ์ฌ Delete(์ญ์ )๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ํ์ธ ํ์
์์ Delete(์ญ์ )๋ฅผ ํด๋ฆญํฉ๋๋ค.
Cannot delete account with related opportunities(๊ด๋ จ ๊ธฐํ๊ฐ ์๋ ๊ณ์ ์ ์ญ์ ํ ์ ์์ต๋๋ค) ์ฌ์ฉ์ ์ ์ ์ค๋ฅ ๋ฉ์์ง๋ก ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ๋ฅผ ์ฐพ์ต๋๋ค.
-
AccountDeletionํธ๋ฆฌ๊ฑฐ๋ฅผ ๋นํ์ฑํํฉ๋๋ค. ์ด ํธ๋ฆฌ๊ฑฐ๋ฅผ ํ์ฑ ์ํ๋ก ๋๋ฉด ๊ณผ์ ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- Setup(์ค์ )์์
Apex Triggers๋ฅผ ๊ฒ์ํฉ๋๋ค.
- Apex Triggers(Apex ํธ๋ฆฌ๊ฑฐ) ํ์ด์ง์์
AccountDeletionํธ๋ฆฌ๊ฑฐ ์์ ์๋ Edit(ํธ์ง)์ ํด๋ฆญํฉ๋๋ค.
-
Is Active(ํ์ฑ)๋ฅผ ์ ํ ํด์ ํฉ๋๋ค.
-
Save(์ ์ฅ)๋ฅผ ํด๋ฆญํฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ ๋ฐ ์ฝ์์
Apex๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ๋ถ ์น ์๋น์ค๋ฅผ ํธ์ถํ๊ณ Apex ์ฝ๋๋ฅผ ์ธ๋ถ ์น ์๋น์ค์ ํตํฉํ ์ ์์ต๋๋ค. ์ธ๋ถ ์น ์๋น์ค์ ๋ํ Apex ํธ์ถ์ ์ฝ์์์ด๋ผ๊ณ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ฃผ์ ์์ธ ์๋น์ค์ ์ฝ์์์ ๋ง๋ค์ด ์ต์ ์์ธ๋ฅผ ์ป์ ์ ์์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ์์ ํธ์ถํ ๊ฒฝ์ฐ ํธ์ถ์ ํธ๋ฆฌ๊ฑฐ ํ๋ก์ธ์ค๊ฐ ์ธ๋ถ ์๋น์ค์ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์์ ์ ์ฐจ๋จํ์ง ์๋๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ํ๋์ด์ผ ํฉ๋๋ค. ๋น๋๊ธฐ ํธ์ถ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค์์ ์ํ๋๋ฉฐ ์ธ๋ถ ์๋น์ค๋ฅผ ๋ฐํํ ๊ฒฝ์ฐ ์๋ต์ด ์์ ๋ฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ์์ ์ฝ์์์ ๋ง๋ค๋ ค๋ฉด ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ ํด๋์ค ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ฅผ future ๋ฉ์๋๋ผ๊ณ ํ๋ฉฐ @future(callout=true) ์ฃผ์์ ์ถ๊ฐํฉ๋๋ค. ์ด ์์ ํด๋์ค์๋ ์ฝ์์์ ๋ง๋๋ future ๋ฉ์๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
public class CalloutClass {
@future(callout=true)
public static void makeCallout() {
HttpRequest request = new HttpRequest();
// Set the endpoint URL.
String endpoint = 'http://yourHost/yourService';
request.setEndPoint(endpoint);
// Set the HTTP verb to GET.
request.setMethod('GET');
// Send the HTTP request and get the response.
HttpResponse response = new HTTP().send(request);
}
}์ด ์์ ๋ ์ฝ์์์ ๋น๋๊ธฐ์ ์ผ๋ก ๋ง๋ค๊ธฐ ์ํด ํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
trigger CalloutTrigger on Account (before insert, before update) {
CalloutClass.makeCallout();
}์ด ์น์ ์์๋ ์ฝ์์์ ๊ฐ์๋ง ์ ๊ณตํ๋ฉฐ ์ฝ์์์ ์์ธํ ๋ค๋ฃจ์ง๋ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ Apex ๊ฐ๋ฐ์ ๊ฐ์ด๋์ Apex๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ์์ ํธ์ถ์ ์ฐธ์กฐํ์ธ์.
๋ฆฌ์์ค
- Apex ๊ฐ๋ฐ์ ๊ฐ์ด๋: ํธ๋ฆฌ๊ฑฐ
- Apex ๊ฐ๋ฐ์ ๊ฐ์ด๋: Apex๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ์์ ํธ์ถ
- Apex ์ฐธ์กฐ ๊ฐ์ด๋: CustomNotification ํด๋์ค
- Trailhead: Apex ํตํฉ ์๋น์ค
