init
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
public inherited sharing class CreateEmailToCase {
|
||||
public class Request {
|
||||
@InvocableVariable(required=true label='Routing Name')
|
||||
public String routingName;
|
||||
|
||||
@InvocableVariable(required=true label='Email Address')
|
||||
public String emailAddress;
|
||||
|
||||
@InvocableVariable(required=true label='Case Owner Queue Id')
|
||||
public Id caseOwnerId;
|
||||
|
||||
@InvocableVariable(required=true label='Case Origin')
|
||||
public String caseOrigin;
|
||||
}
|
||||
|
||||
public class Result {
|
||||
@InvocableVariable(label='Metadata Full Name')
|
||||
public String metadataFullName;
|
||||
|
||||
@InvocableVariable(label='Routing Name')
|
||||
public String routingName;
|
||||
|
||||
@InvocableVariable(label='Email Address')
|
||||
public String emailAddress;
|
||||
|
||||
@InvocableVariable(label='Email-to-Case Address')
|
||||
public String emailToCaseAddress;
|
||||
|
||||
@InvocableVariable(label='Email Routing Address Id')
|
||||
public Id emailRoutingAddressId;
|
||||
|
||||
@InvocableVariable(label='Created')
|
||||
public Boolean created;
|
||||
}
|
||||
|
||||
@InvocableMethod(
|
||||
label='Create Email-To-Case'
|
||||
description='Adds an on-demand Email-to-Case routing address to Case Settings.'
|
||||
category='Queue Configuration'
|
||||
callout=true
|
||||
)
|
||||
public static List<Result> createRoutingAddress(List<Request> requests) {
|
||||
MetadataXml.require(
|
||||
requests != null && requests.size() == 1,
|
||||
'Create Email-To-Case accepts exactly one request per invocation.'
|
||||
);
|
||||
Request input = requests[0];
|
||||
input.routingName = input.routingName == null
|
||||
? null
|
||||
: input.routingName.trim();
|
||||
input.emailAddress = input.emailAddress == null
|
||||
? null
|
||||
: input.emailAddress.trim();
|
||||
input.caseOrigin = input.caseOrigin == null
|
||||
? null
|
||||
: input.caseOrigin.trim();
|
||||
MetadataXml.require(
|
||||
!String.isBlank(input.routingName),
|
||||
'Routing Name is required.'
|
||||
);
|
||||
MetadataXml.require(
|
||||
!String.isBlank(input.emailAddress),
|
||||
'Email Address is required.'
|
||||
);
|
||||
MetadataXml.require(
|
||||
input.caseOwnerId != null,
|
||||
'Case Owner Queue Id is required.'
|
||||
);
|
||||
MetadataXml.require(
|
||||
!String.isBlank(input.caseOrigin),
|
||||
'Case Origin is required.'
|
||||
);
|
||||
|
||||
List<Group> queues = [
|
||||
SELECT Id, DeveloperName
|
||||
FROM Group
|
||||
WHERE Id = :input.caseOwnerId AND Type = 'Queue'
|
||||
WITH USER_MODE
|
||||
LIMIT 1
|
||||
];
|
||||
MetadataXml.require(
|
||||
!queues.isEmpty(),
|
||||
'Case Owner Id must identify a queue.'
|
||||
);
|
||||
|
||||
Dom.XmlNode caseSettings = MetadataApiClient.readMetadata(
|
||||
'CaseSettings',
|
||||
'Case'
|
||||
);
|
||||
MetadataXml.require(
|
||||
caseSettings != null,
|
||||
'Case Settings metadata was not found.'
|
||||
);
|
||||
Dom.XmlNode emailToCase = MetadataXml.child(caseSettings, 'emailToCase');
|
||||
MetadataXml.require(
|
||||
emailToCase != null,
|
||||
'Email-to-Case is not configured. Enable Email-to-Case in Setup before creating a routing address.'
|
||||
);
|
||||
|
||||
for (
|
||||
Dom.XmlNode route : MetadataXml.children(emailToCase, 'routingAddresses')
|
||||
) {
|
||||
String existingName = MetadataXml.text(route, 'routingName');
|
||||
String existingAddress = MetadataXml.text(route, 'emailAddress');
|
||||
Boolean sameName = input.routingName.equalsIgnoreCase(existingName);
|
||||
Boolean sameAddress = input.emailAddress.equalsIgnoreCase(
|
||||
existingAddress
|
||||
);
|
||||
if (sameName || sameAddress) {
|
||||
MetadataXml.require(
|
||||
sameName && sameAddress,
|
||||
'An Email-to-Case routing address already uses this routing name or email address with different values.'
|
||||
);
|
||||
return new List<Result>{ buildResult(input, false) };
|
||||
}
|
||||
}
|
||||
|
||||
String routeXml =
|
||||
'<routingAddresses>' +
|
||||
'<addressType>EmailToCase</addressType>' +
|
||||
'<caseOrigin>' +
|
||||
MetadataXml.escape(input.caseOrigin) +
|
||||
'</caseOrigin>' +
|
||||
'<caseOwner>' +
|
||||
MetadataXml.escape(queues[0].DeveloperName) +
|
||||
'</caseOwner>' +
|
||||
'<caseOwnerType>Queue</caseOwnerType>' +
|
||||
'<casePriority>Medium</casePriority>' +
|
||||
'<emailAddress>' +
|
||||
MetadataXml.escape(input.emailAddress) +
|
||||
'</emailAddress>' +
|
||||
'<routingName>' +
|
||||
MetadataXml.escape(input.routingName) +
|
||||
'</routingName>' +
|
||||
'<saveEmailHeaders>false</saveEmailHeaders>' +
|
||||
'</routingAddresses>';
|
||||
String emailToCaseXml = '<emailToCase>';
|
||||
Boolean inserted = false;
|
||||
for (Dom.XmlNode child : emailToCase.getChildElements()) {
|
||||
if (!inserted && child.getName().compareTo('routingAddresses') > 0) {
|
||||
emailToCaseXml += routeXml;
|
||||
inserted = true;
|
||||
}
|
||||
emailToCaseXml += MetadataXml.serialize(child);
|
||||
}
|
||||
if (!inserted) {
|
||||
emailToCaseXml += routeXml;
|
||||
}
|
||||
emailToCaseXml += '</emailToCase>';
|
||||
|
||||
MetadataApiClient.updateMetadata(
|
||||
'CaseSettings',
|
||||
MetadataXml.replaceOrInsertChild(
|
||||
caseSettings,
|
||||
'emailToCase',
|
||||
emailToCaseXml
|
||||
)
|
||||
);
|
||||
return new List<Result>{ buildResult(input, true) };
|
||||
}
|
||||
|
||||
private static Result buildResult(Request input, Boolean created) {
|
||||
Result result = new Result();
|
||||
result.metadataFullName = 'Case';
|
||||
result.routingName = input.routingName;
|
||||
result.emailAddress = input.emailAddress;
|
||||
result.created = created;
|
||||
|
||||
Schema.SObjectType routingType = Schema.getGlobalDescribe()
|
||||
.get('EmailRoutingAddress');
|
||||
if (routingType == null) {
|
||||
return result;
|
||||
}
|
||||
Map<String, Schema.SObjectField> fields = routingType.getDescribe()
|
||||
.fields.getMap();
|
||||
String addressField = fields.containsKey('EmailAddress')
|
||||
? 'EmailAddress'
|
||||
: (fields.containsKey('Address') ? 'Address' : null);
|
||||
if (addressField == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<String> selectFields = new List<String>{ 'Id', addressField };
|
||||
if (fields.containsKey('RoutingAddress')) {
|
||||
selectFields.add('RoutingAddress');
|
||||
}
|
||||
if (fields.containsKey('EmailServicesAddressId')) {
|
||||
selectFields.add('EmailServicesAddressId');
|
||||
}
|
||||
String query =
|
||||
'SELECT ' +
|
||||
String.join(selectFields, ',') +
|
||||
' FROM EmailRoutingAddress WHERE ' +
|
||||
addressField +
|
||||
' = :emailAddress LIMIT 1';
|
||||
List<SObject> matches = Database.queryWithBinds(
|
||||
query,
|
||||
new Map<String, Object>{ 'emailAddress' => input.emailAddress },
|
||||
AccessLevel.USER_MODE
|
||||
);
|
||||
if (matches.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.emailRoutingAddressId = (Id) matches[0].get('Id');
|
||||
if (fields.containsKey('RoutingAddress')) {
|
||||
result.emailToCaseAddress = (String) matches[0].get('RoutingAddress');
|
||||
} else if (fields.containsKey('EmailServicesAddressId')) {
|
||||
result.emailToCaseAddress = emailServicesAddress(
|
||||
(Id) matches[0].get('EmailServicesAddressId')
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String emailServicesAddress(Id serviceAddressId) {
|
||||
if (serviceAddressId == null) {
|
||||
return null;
|
||||
}
|
||||
Schema.SObjectType serviceType = Schema.getGlobalDescribe()
|
||||
.get('EmailServicesAddress');
|
||||
if (serviceType == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Schema.SObjectField> fields = serviceType.getDescribe()
|
||||
.fields.getMap();
|
||||
if (
|
||||
!fields.containsKey('LocalPart') || !fields.containsKey('EmailDomainName')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
List<SObject> rows = Database.queryWithBinds(
|
||||
'SELECT LocalPart, EmailDomainName FROM EmailServicesAddress WHERE Id = :serviceAddressId LIMIT 1',
|
||||
new Map<String, Object>{ 'serviceAddressId' => serviceAddressId },
|
||||
AccessLevel.USER_MODE
|
||||
);
|
||||
return rows.isEmpty()
|
||||
? null
|
||||
: String.valueOf(rows[0].get('LocalPart')) +
|
||||
'@' +
|
||||
String.valueOf(rows[0].get('EmailDomainName'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user