Button in Email Template

У цій статті хочу показати практичний кейс використання кнопки в Email та створення “хендлера”, який буде реагувати на дану кнопку.
Реальна задача може бути така: “Реалізувати можливість відправки Email з угодою в вигляді PDF файлу. В цьому листі повинна бути кнопка “Yes”, натиснувши на яку клієнт підтверджує свою згоду, і ця інформація повинна бути збережена в Salesforce. Процес відправки листа може бути запущений в Salesforce в будь-який спосіб (trigger, flow, LWC). Після підтвердження клієнт отримує лист подяки чи перенаправляється до веб-ресурсу.”

Головна проблема в цій задачі це те, як відстежити натискання кнопки “Yes” в листі та запустити якісь дії в Salesforce. Це можливо реалізувати за допомогою Public Visualforce чи Public REST API. Я не буду детально розбирати реалізацію відправки Email з Apex, – про це в інтернеті існує дуже багато детальної інформації, i кожен може реалізувати свою. Розберемо лише підхід до взаємодії з юзером через лист.

Public Visualforce.

Цей підхід полягає в тому, щоб створити Visualforce Page, яка буде доступна для не авторизованих в Salesforce юзерів, і в такому випадку кнопка “Yes” буде мати URL на цю сторінку. Саме в контролері сторінки буде виконуватися вся логіка після натискання кнопки.

Visualforce Page приклад:

<apex:page controller="AgreementPageController" action="{!saveConsent}">
</apex:page>

Apex controller приклад:

public without sharing class AgreementPageController {
    public AgreementPageController() {
    }

    public PageReference saveConsent() {
	// some logic
  }
}

Також нам потрібно створити HTML Classic Email Template з кнопкою:

<a href="{!Consent__c.Consent_URL__c}" style="text-decoration: none;">
<div style=" height: 45px; width: 100px; line-height: 38px; border-radius: 50px; background: #339DFF; border: none; text-align: center; color: #fff; font-size: 16px;">
Yes
</div>
</a>


Припустимо, що інформація буде збережена в записі об’єкта Consent__c. Тоді ми можемо створити на цьому об’єкті поле типу Formula Field. Саме це поле буде формувати URL на сторінку Visualforce, і ми можемо його використати в Email Template як Merge Fields. Оскільки на різних Salesforce orgs різні url домени, та може бути ввімкнений Custom Domain, щоб не виправляти url на Visualforce сторінку в Email Template вручну – і створено Formula Field.

SUBSTITUTE(
LEFT($Api.Partner_Server_URL_260,FIND("/services", $Api.Partner_Server_URL_530)),
'salesforce.com/',
'salesforce-sites.com/AgreementPage?consentId='+Id
)

Тепер, щоб все запрацювало, лишилось тільки зробити Visualforce сторінку публічною.
Для цього потрібно зайти в Setup, знайти Sites, перейти до Site Details, i потім в Public Access Settings в розділі Visualforce Page Access додати потрібну сторінку.

Public REST API.

Наступний підхід буде дуже схожий на попередній, за винятком того, що замість Visualforce сторінки буде використовуватись REST API контролер, який теж можна зробити публічним.
@RestResource(urlMapping='/agreement')
global without sharing class AgreementRestResource {
    @HttpPost
    global static void saveConsent() {
	// some logic
    }
}

Також кнопка в Email Template тепер буде робити POST запит до REST ресурсу і буде мати наступний вигляд:

<form action="{!Consent__c.Consent_URL__c}" method="POST">
<input type="hidden" id="consentId" name="consentId" type="text" value={!Consent__c.Id} />
<input type="submit" name="submit" value="Yes" style=" height: 45px; width: 100px; line-height: 38px; border-radius: 50px; background: #339DFF; border: none; text-align: center; color: #fff; font-size: 16px;"></input>
</form>

Formula Field з використанням REST API:

SUBSTITUTE(
LEFT($Api.Partner_Server_URL_260,FIND("/services", $Api.Partner_Server_URL_530)),
'salesforce.com/',
'salesforce-sites.com/agreement
)

Який спосіб краще, кожен може вирішити для себе сам, вони дуже схожі, але на мій погляд з використанням REST API в контролер можливо передати більший обсяг інформації який буде структурований в тілі POST запиту.

3 Вподобання

Дякую,

во времена засилья Low Code No Code tools оправлять Емейл с помощью Апекса будет немного старомодным.

плюс вроде еще чекбокс “Require CSRF protection on GET requests” на ВФ странице должен быть анчект, но не точно :slight_smile: