• Michelle Soto
  • NEWBIE
  • 20 Points
  • Member since 2022
  • Coordinador Software & Internal Solution
  • Métrica Móvil


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 5
    Questions
  • 3
    Replies
At de moment we are implement a Email Service in a custom object where we want to received and reply emails but, when we create a EmailMessage register in the Apex class, the register in the chatter component from custom object appear like a task. We want that the EmailMessage register appear like in the Case object.
 
EmailMessage register in Case object:
User-added imageEmailMessage register in the custom object:
User-added image

We want to in the custom object appear the EmailMessage register like in the Case object.
 
How can we solve it?
What are the best prectices?
We want to grant access to customer for query cases through API. We grant the licence Customer Community Plus, but i don´t know how grant the token because for autenthicate to API needed ClientId, ClientSecret, UserName, Password, Token.

We used a connected app. And that works for us ( Salesforce user ), but for the customer user not works.

When the customer try to "Authenticate", appear the next error: "Authentication failed: InvalidGrant : authentication failure"

We used the next code ( SalesforceSharp ).
var client = new SalesforceClient();
var authFlow = new UsernamePasswordAuthenticationFlow(clientId, clientSecret, username, password);

try 
{
	client.Authenticate(authFlow);
}
catch(SalesforceException ex)
{
	Console.WriteLine("Authentication failed: {0} : {1}", ex.Error, ex.Message);
}
How i can to get the token?
Can customer user can to conect through API?
What do you recommend as best practice?
Hi,

We have a problem with the community public version. 

When a user public try to view the knoledge base, appear the next error: "ERROR: You don't have access to the Apex class named 'DataCategoryController'."

I find information about that but is referent to profiles acces to Apex Class. The error appear to public user so i can´t give acces to Apex Class if are public user without licences.

The Apex Class is a controller for a aura component. When i see the component with my salesforce user no appeat the error.

Code:
public class DataCategoryController {
    @AuraEnabled
    public static Wrapper getDataCategories(){
        
        Wrapper wrap = new wrapper();
        wrap.items = new List<Node>();
        wrap.label = 'Ayuda y soporte tecnico';
        
        Map<String, Knowledge__DataCategorySelection> mapKDCS = new Map<String, Knowledge__DataCategorySelection >();
        List<Knowledge__DataCategorySelection> lstkdcs =  [SELECT DataCategoryGroupName,DataCategoryName,Id FROM Knowledge__DataCategorySelection];
        
        for(Knowledge__DataCategorySelection KDCS :lstkdcs ){
            mapKDCS.put( KDCS.DataCategoryName, KDCS );
        }
        
        for(Knowledge__DataCategorySelection KDCS :mapKDCS.values() ){
            Node DCNode = new  Node();
            DCNode.label = KDCS.DataCategoryName;
            DCNode.name = KDCS.DataCategoryName;
            DCNode.expanded = true;
            wrap.items.add( DCNode );
        }
        
        system.debug('wrap: '+ wrap);
        return wrap;
    }
    
    @AuraEnabled
    public static List<Knowledge__kav>  getArticleVersion(String topicName){
        
        Set<Id> setTopicEntyId = new Set<Id>();
        
        List<TopicAssignment> lstTA = [SELECT EntityId FROM TopicAssignment WHERE Topic.Name = :topicName LIMIT 900 ];
        system.debug('lstTA: '+lstTA);
        
        for(TopicAssignment ta :lstTA){
            setTopicEntyId.add(ta.EntityId);
        }
        
        system.debug('setTopicEntyId: '+setTopicEntyId);
        
        List<Knowledge__kav > lstKAV = [
            SELECT Id, Title, FirstPublishedDate, LastPublishedDate,UrlName 
            FROM Knowledge__kav
            WHERE PublishStatus = 'Online' AND Id in  :setTopicEntyId];
        system.debug('lstKAV: '+lstKAV);
        return lstKAV;
    }
    
        
    public class Wrapper{
        @AuraEnabled
        public String label{get;set;}
        @AuraEnabled
        public List<Node> items{get;set;}
    }
    
    public class Node{
        @AuraEnabled
        public String label{get;set;}
        @AuraEnabled
        public String name{get;set;}
        @AuraEnabled
        public Boolean expanded{get;set;}
        @AuraEnabled
        public List<node> items{get;set;}
    }
}

Do you know the solution for this error?
Do you know another method to solve the error?

Thanks!
 
I'm try to scheduler email send with a repor attached, but when i received the email, appear the next error in the file:

User-added image
global class Exporter implements System.Schedulable {
    global void execute(SchedulableContext sc) {
        DoExport();
    }

    @future(callout=true)
    public static void DoExport() {
        ApexPages.PageReference report = new ApexPages.PageReference('/00O6g000004Z0nNEAS?csv=1');
        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
        attachment.setFileName('report.csv');
        attachment.setBody(Blob.valueof(report.getContent().toString()));
        attachment.setContentType('text/csv');
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        message.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment } );
        message.setPlainTextBody('The report is attached.');
        message.setToAddresses( new String[] { 'user@example.com' } );
        Messaging.sendEmail( new Messaging.SingleEmailMessage[] { message } );
    }
}
Could you help me with this error please?
Could you tell me if there is another option to solve the need to send the attached file by mail?
 
I want to past the apex class test but when i validate the test class appear the next error:
 
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because there was an error in the process “Caso nuevo”. Provide these details to your administrator Salesforce. null null : [] Stack Trace: Class.ActualizacionResolucionGeneralGarantiasT.actualizar: line 31, column 1

The flow “Caso nuevo” send a email alert. I think that the problem is the email of the contact, but in the test class i put the email in the contact.
 
@isTest
public class ActualizacionResolucionGeneralGarantiasT {
    @isTest
    static void actualizar(){
        ActualizacionResolucionGeneralGarantias actualizacion = new ActualizacionResolucionGeneralGarantias();
        Account cuenta = new Account(
        	Name = 'Test Account'
        );
        insert cuenta;
        Contact contacto = new Contact(
        	FirstName = 'User',
            LastName = 'Test',
            AccountId = cuenta.Id,
            Email = 'test@gmail.com'
        );
        insert contacto;
        case numeroCaso = new case(
            Subject = 'Test NO MOVER',
            AccountId = cuenta.Id,
            Dispositivo_Accesorio__c = 'ABC',
            Status = 'New',
            Priority = 'Low',
            ContactId = contacto.Id,
            Lista_de_dispositivos__c = 'Test NO MOVER',
            Origin = 'Phone',
            Dispositivos__c = '',
            Responsable__c = '0056g000005ixDtAAI',
            Producto_reportado__c = 'GO',
            Incidente_reportado__c = 'Otro'
        );
        insert numeroCaso;
    }
}
Thanks!
 
We want to grant access to customer for query cases through API. We grant the licence Customer Community Plus, but i don´t know how grant the token because for autenthicate to API needed ClientId, ClientSecret, UserName, Password, Token.

We used a connected app. And that works for us ( Salesforce user ), but for the customer user not works.

When the customer try to "Authenticate", appear the next error: "Authentication failed: InvalidGrant : authentication failure"

We used the next code ( SalesforceSharp ).
var client = new SalesforceClient();
var authFlow = new UsernamePasswordAuthenticationFlow(clientId, clientSecret, username, password);

try 
{
	client.Authenticate(authFlow);
}
catch(SalesforceException ex)
{
	Console.WriteLine("Authentication failed: {0} : {1}", ex.Error, ex.Message);
}
How i can to get the token?
Can customer user can to conect through API?
What do you recommend as best practice?
I want to past the apex class test but when i validate the test class appear the next error:
 
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, We can't save this record because there was an error in the process “Caso nuevo”. Provide these details to your administrator Salesforce. null null : [] Stack Trace: Class.ActualizacionResolucionGeneralGarantiasT.actualizar: line 31, column 1

The flow “Caso nuevo” send a email alert. I think that the problem is the email of the contact, but in the test class i put the email in the contact.
 
@isTest
public class ActualizacionResolucionGeneralGarantiasT {
    @isTest
    static void actualizar(){
        ActualizacionResolucionGeneralGarantias actualizacion = new ActualizacionResolucionGeneralGarantias();
        Account cuenta = new Account(
        	Name = 'Test Account'
        );
        insert cuenta;
        Contact contacto = new Contact(
        	FirstName = 'User',
            LastName = 'Test',
            AccountId = cuenta.Id,
            Email = 'test@gmail.com'
        );
        insert contacto;
        case numeroCaso = new case(
            Subject = 'Test NO MOVER',
            AccountId = cuenta.Id,
            Dispositivo_Accesorio__c = 'ABC',
            Status = 'New',
            Priority = 'Low',
            ContactId = contacto.Id,
            Lista_de_dispositivos__c = 'Test NO MOVER',
            Origin = 'Phone',
            Dispositivos__c = '',
            Responsable__c = '0056g000005ixDtAAI',
            Producto_reportado__c = 'GO',
            Incidente_reportado__c = 'Otro'
        );
        insert numeroCaso;
    }
}
Thanks!
 
Hello! We have created custom email functionality on a custom object that acts almost exactly like email to case. The problem I am facing is that the email comes in and connects to the correct Delivery Exception record (custom object) but doesnt create a feed item like email to case does. The users would like to see the emails in the chatter feed of the record as well as the email message related list (email message related list is created) would the code look something like the following (I am still in the beginning stages of learning to code)?
{
FeedItem item = new Feeditem();
FeedItem post = new FeedItem();
post.ParentId = deliveryexceptionId;
post.Body = email.plainTextBody;
Insert Post;
}

Here is the class as it stands now:

global class DeliveryEmailHandler implements Messaging.InboundEmailHandler {
    
    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
        try{
            id deliveryexceptionId;
            string emailBody = email.plainTextBody;        
            string deliveryexceptionName ='';
            string emailSubject= email.subject;
            system.debug('email subject'+emailSubject);
            pattern regEx = Pattern.compile('(E[0-9]{8})');
            matcher deliveryexceptionMatcherSubject = regEx.matcher(emailSubject);
            //deliveryexceptionMatcherSubject.find();
            if(deliveryexceptionMatcherSubject.find() && deliveryexceptionMatcherSubject.group(1) != null){
                deliveryexceptionName = deliveryexceptionMatcherSubject.group(1);
                system.debug('Delivery Exception name found in subject');
            } else {
                // try body of email if not in subject
                matcher deliveryexceptionMatcherBody = regEx.matcher(emailBody);
                //deliveryexceptionMatcherBody.find();
                if(deliveryexceptionMatcherBody.find() && deliveryexceptionMatcherBody.group(1) != null){
                    deliveryexceptionName = deliveryexceptionMatcherBody.group(1);
                    system.debug('Delivery Exception name found in body');
                } 
            }
            // if matcher matches find delivery exception record
            If (deliveryexceptionName != ''){
                list<Delivery_Exception__c> deliveryexceptionList = [select id,name,account__c from Delivery_Exception__c where name = :deliveryexceptionName];
                if(!deliveryexceptionList.isEmpty() && deliveryexceptionList.size() == 1){
                    deliveryexceptionId = deliveryexceptionList[0].id;
                }
            }
            // attach to error delivery exception if no delivery exception record is found
            if(deliveryexceptionId == null){
                deliveryexceptionId = [select id from Delivery_Exception__c where external_id__c = 'ERROR' limit 1].Id;
            }
            EmailMessage cEmailMessage = new EmailMessage();
            cEmailMessage.ToAddress =  String.join(email.toAddresses, ',');
            cEmailMessage.FromAddress = email.FromAddress;
            cEmailMessage.FromName = email.FromName;
            cEmailMessage.Subject = email.subject;
            cEmailMessage.status = '0';
            cEmailMessage.HtmlBody = email.htmlBody;
            //System.debug('htmlBody:>>>> ' + email.htmlBody );
            cEmailMessage.Incoming= True;
            cEmailMessage.TextBody = email.plainTextBody;
            cEmailMessage.relatedToId = deliveryexceptionId;
            cEmailMessage.Delivery_Exception__c = deliveryexceptionId;
            //cEmailMessage.validatedFromAddress = 'deliverytest@Arhaus.com';
            //System.debug('TextBody:>>>>> ' + email.plainTextBody);
            insert cEmailMessage;
            System.debug('Reply Email: ' + cEmailMessage ); 
            //Add Email Message Relation the from address
            list<emailMessageRelation> emailMessageRelations = new list<emailMessageRelation>();
            emailMessageRelations.add(new EmailMessageRelation(
                EmailMessageId = cEmailMessage.id,
                RelationAddress = email.FromAddress,
                RelationType = 'FromAddress'));
            // as of 10-24-19 Salesforce required a relationship to be able to reply.
            // this code section can be removed when Salesforce support Org Wide Email Addresses to be used on custom objects
            // with the functionality supported on the case object.
            // 
            for(user u : [select id,email from user where Exception_Email_Functionality__c = true and isactive = true]){
                emailMessageRelations.add(new EmailMessageRelation(EmailMessageId = cEmailMessage.id, RelationId = u.id, RelationType = 'BccAddress'));    
            }
            insert emailMessageRelations;
            // if email attachments are not null create files
            if(email.binaryAttachments != null) createContentDocumentLinks(email.binaryAttachments, cEmailMessage.id, deliveryexceptionId);
        } catch(exception e){
            system.debug('exception processing delivery exception inbound email:'+e.getMessage());
        }
        result.success = true;
        return result;
    }
    public boolean createContentDocumentLinks(Messaging.InboundEmail.BinaryAttachment[] binAttachList, Id insertedEmailMessageId, Id deliveryexceptionId) {
        List<ContentVersion>cvList = new List<ContentVersion>();
        List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
        for (Messaging.InboundEmail.BinaryAttachment binAttach : binAttachList) {
            ContentVersion testContentInsert = new ContentVersion();
            testContentInsert.Title = binAttach.fileName;
            testContentInsert.VersionData = binAttach.body;
            testContentInsert.PathOnClient = '/' + binAttach.fileName ;
            cvList.add(testContentInsert);
            
        }
        insert cvList;
        cvList = [select id, ContentDocumentId from ContentVersion WHERE Id in :cvList];
        for (ContentVersion cv : cvList) {
            ContentDocumentLink cl = new ContentDocumentLink();
            cl.ContentDocumentId = cv.ContentDocumentId;
            cl.LinkedEntityId = insertedEmailMessageId;
            cl.ShareType = 'V';
            cl.Visibility = 'AllUsers';
            cdlList.add(cl);
            // add link to delivery exception also
            ContentDocumentLink clc = new ContentDocumentLink();
            clc.ContentDocumentId = cv.ContentDocumentId;
            clc.LinkedEntityId = deliveryexceptionId;
            clc.ShareType = 'V';
            clc.Visibility = 'AllUsers';
            cdlList.add(clc);
        }
        insert cdlList;
        return true;
    }
}


THANK YOU SO MUCH FOR ANY ASSISTANCE!!!!
Hello All,

I'm setting up Embedded Services Chat. Is there a way to override the
embedded.svc.settings

parameters so that instead of text being displayed, an icon is displayed instead? For example, instead of 
embedded.svc.settings.defaultMinimizedText

we would have 
embedded.svc.settings.defaultMinimizedImage

. I've looked in the documentation and don't see any parameters like this, so would we have to build a LWC to override the default 
.embeddedServiceHelpButton

?