-1

I'm trying to create cases through incoming email by using Apex Inbound Emailhandler. It worked very well for a sample class which pulls the contact id based on incoming email address and creates case. However, when I try to create case based on our requirement, it wouldn't create. Please have a look at the below code. We receive emails in a particular template, we have to parse the emailbody to assign certain information to certain fields. We don't want the email body to be dumped in description field. Parsing is working fine, as I tested for the sample class. However, I'm unable to pull the location id (object of a managed package) for the incoming email. Can any one help me? There seems to be an issue with the query I think.

Every incoming email has a location name, we have to use it to pull the location id and create a case. SVMXC__Site__c is the API name for the custom object Location from which I have to pull the location id and create case.

    global Class EtoCase implements Messaging.InboundEmailHandler {

    // Instantiate variables that we will need for handling this email
    public String location;
    public String notes;
    public Integer locationIdx;
    public Integer notesIdx;
    public String locationFinal;
    public String notesFinal;

    global Messaging.InboundEmailResult 
    handleInboundEmail(Messaging.InboundEmail email, 
    Messaging.InboundEnvelope env){  
    Messaging.InboundEmailResult result = new 
    Messaging.InboundEmailResult();

    if (email.fromaddress =='example@test.com') {

    location = 'Location: ';   
    notes = 'Notes ';      


    locationIdx = email.plainTextBody.indexOf(location);
    notesIdx = email.plainTextBody.indexOf(notes);

    locationFinal = email.plainTextBody.substring(
                          locationIdx + location.length(), 
    email.plainTextBody.indexOf('\n', locationIdx + location.length()));
      String[] locNme = locationFinal.split(' ', 3);
    notesFinal = email.plainTextBody.substring(
                          notesIdx + notes.length(), 
    email.plainTextBody.indexOf('\n', notesIdx + notes.length()));


    try{      

    case c= new case();
    c.subject= 'PRODUCT SERVICE REQUEST';
    c.Case_Type__c= 'Service Request';
    c.Priority='High';
    c.Origin='Email';
    c.Status='new';
    string location = locationFinal;   
    SVMXC__Site__c[] locArray = [SELECT Id, Name, NTT_Location_Name__c, 
    SVMXC__Account__r.Id FROM SVMXC__Site__c where Name = 'locationFinal'  
    limit 1];
    c.SVMXC__Site__r.Id = locArray[0].Id;           
    c.AccountId = locArray[0].SVMXC__Account__r.Id;
    c.recordtypeId = '012E0000000oRWX';         
    c.Description= notesFinal;
     insert c;
    } catch (System.Dmlexception e)
                 {System.debug('Error: Not able to create new Case: ' + e);

      }
     }
     return result;

     } 
          }
  • 1
    What have you tried to verify this statement -- [There seems to be an issue with the query I think.]? Have you put debug logs to view what's being returned? – Jayant Das Oct 8 '18 at 15:50
1

Your query is using Apex binding incorrectly.

SVMXC__Site__c[] locArray = [SELECT Id, Name, NTT_Location_Name__c, 
SVMXC__Account__r.Id FROM SVMXC__Site__c where Name = 'locationFinal'  
limit 1];

This query looks for SVMXC__Site__c records whose Name is the literal string 'locationFinal'. To utilize your variable here, you need to use Apex binding syntax:

SVMXC__Site__c[] locArray = [SELECT Id, Name, NTT_Location_Name__c, 
SVMXC__Account__r.Id FROM SVMXC__Site__c where Name = :locationFinal  
limit 1];

This is particularly critical here because the use of Apex binding helps guard you against SOQL injection attacks, and the data you're using is sourced from outside your org.

There are some other issues with this code that you may wish to address:

  • You don't handle failure cases where you do not have a matching Location, which will result in a ListException rather than a DmlException.
  • Depending on the underlying data model, there may also be some NullPointerException possibilities.
  • You do not declare a sharing model (with sharing or without sharing) based on the security needs of this code.
  • This line will throw a NullPointerException: c.SVMXC__Site__r.Id = locArray[0].Id; You probably mean to directly assign to SVMXC__Site__c.
  • You hard-code a Record Type Id; it would be better to use the Describe API to source this value.
  • Hello David, I've tried with the new binding syntax, it still wouldn't create a case. – Shashank N Oct 8 '18 at 17:29
  • Hi Shashank, please understand that I cannot run your code in my org, so you need to be specific about identifying the problem. What error you do see, on which line, or what behavior. If you simply get no result, use System.debug() statements or review the debug logs to determine where execution stops. – David Reed Oct 8 '18 at 17:30
  • Hello David, I was able to resolve the issues of not creating cases. For few emails, the cases were not created because of the mismatch of data. When I check the debug log, it says "FATAL_ERROR System.NullPointerException: Attempt to de-reference a null object". For few cases, I get an error of "List out of bounds". What does that mean and how do I avoid it? It may be basic but I'm still in early phases of coding and would appreciate any valuable response. – Shashank N Oct 15 '18 at 18:44
  • Hi Shashank, it sounds like this is a separate issue, although please do note my comment about one line that will certainly throw a NullPointerException and which you can easily fix. Feel free to open a new question for these follow-up issues, but also know that NullPointerExceptions are usually things you can easily fix by tracing where a ` null` value could exist in your code. Search NullPointerException on SFSE for lots of good examples! – David Reed Oct 15 '18 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.