Столкнулись с ситуацией, когда существует сервис, который уже никак не может быть изменён, но и через REST или SOAP с ним взаимодействовать тоже не получится. Но нашёлся 1 способ.
Так как сервис может принимать и отправлять Email, то с его помощью и было решено наладить с ним связь.
Идея заключалась в том, что к нам в Salesforce приходит Email, и из него уже будет взят Attachment или текст из body имэйла.
Далее делаем парсинг пришедших данных, и, если надо, отправляем email в ответ.
EmailServiceHandler
global class UploadInvoicesEmailServiceHandler implements Messaging.InboundEmailHandler {
private static final String endOfLine = '\n';
global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,
Messaging.InboundEnvelope envelope) {
Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
try {
List<InvoiceDTO> invoiceDTOs = new List<InvoiceDTO>();
if (email.textAttachments != null && !email.textAttachments.isEmpty()) {
for (Messaging.InboundEmail.TextAttachment textAttachment : email.textAttachments) {
if (textAttachment.mimeTypeSubType == 'text/csv' ||
textAttachment.mimeTypeSubType == 'multipart/mixed') {
String content = textAttachment.body;
String fileName = textAttachment.fileName;
List<String> contentLines = content.split(endOfLine);
if (isValidAttachment(fileName, contentLines)) {
List<UserIdDTO> parsedInvoiceDTOs = getParsedInvoiceIds(contentLines);
invoiceDTOs.addAll(parsedInvoiceDTOs);
}
}
}
}
/* Use the next if you need to work with binary attachments
if (email.binaryAttachments != null && !email.binaryAttachments.isEmpty()) {
for (Messaging.InboundEmail.BinaryAttachment binAttachment : email.binaryAttachments) {
//Do some work
}
}
*/
if (!invoiceDTOs.isEmpty()) {
List<Invoice__c> invoicesToUpsert = getInvoicesToUpsert(invoiceDTOs);
upsert invoicesToUpsert;
result.success = true;
result.message = 'Upload was performed successfully.';
}
} catch (Exception ex) {
result.success = false;
result.message = 'Upload failed: ' + ex.getMessage();
}
return result;
}
private Boolean isValidAttachment(String fileName, List<String> contentLines) {
// Some content validation logic
}
private List<InvoiceDTO> getParsedInvoiceIds(List<String> contentLines) {
// Some parsing logic
return invoiceDTOs;
}
private List<Invoice__c> getInvoicesToUpsert(List<UserIdDTO> invoiceDTOs) {
// Some logic for converting DTOs to sObjects
return invoicesToUpsert;
}
private class InvoiceDTO {
public String invoiceName { get; set; }
public DateTime invoiceDate { get; set; }
public Decimal amount { get; set; }
/*
Add the new fields here for whatever you need
*/
public InvoiceDTO(String invoiceName,
String invoiceDate,
String amount) {
this.invoiceName = invoiceName;
this.invoiceDate = invoiceDate;
this.amount = amount;
}
}
}
Выше представлен итоговый результат. Давайте детальнее рассмотрим такой подход.
Все данные, полученные из email, будут храниться в обёртке над объектом Invoice__c.
private class InvoiceDTO {
public String invoiceName { get; set; }
public DateTime invoiceDate { get; set; }
public Decimal amount { get; set; }
/*
Add the new fields here for whatever you need
*/
public InvoiceDTO(String invoiceName,
String invoiceDate,
String amount) {
this.invoiceName = invoiceName;
this.invoiceDate = invoiceDate;
this.amount = amount;
}
}
Собственно сам парсинг заключается в получении определённых данных из пришедшего Email, с помощью Messaging.InboundEmail type.
global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
try {
List<InvoiceDTO> invoiceDTOs = new List<InvoiceDTO>();
if (email.textAttachments != null && !email.textAttachments.isEmpty()) {
for (Messaging.InboundEmail.TextAttachment textAttachment : email.textAttachments) {
if (textAttachment.mimeTypeSubType == 'text/csv' ||
textAttachment.mimeTypeSubType == 'multipart/mixed') {
String content = textAttachment.body;
String fileName = textAttachment.fileName;
List<String> contentLines = content.split(endOfLine);
if (isValidAttachment(fileName, contentLines)) {
List<UserIdDTO> parsedInvoiceDTOs = getParsedInvoiceIds(contentLines);
invoiceDTOs.addAll(parsedInvoiceDTOs);
}
}
}
}
/* Use the next if you need to work with binary attachments
if (email.binaryAttachments != null && !email.binaryAttachments.isEmpty()) {
for (Messaging.InboundEmail.BinaryAttachment binAttachment : email.binaryAttachments) {
//Do some work
}
}
*/
if (!invoiceDTOs.isEmpty()) {
List<Invoice__c> invoicesToUpsert = getInvoicesToUpsert(invoiceDTOs);
upsert invoicesToUpsert;
result.success = true;
result.message = 'Upload was performed successfully.';
}
} catch (Exception ex) {
result.success = false;
result.message = 'Upload failed: ' + ex.getMessage();
}
return result;
}
Весь доступный функционал для работы с Email в Apex вы можете найти по ссылкам: