function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

How to associate inbound email to existing Opportunity?

Hi All,

Hope you could assist me modifying a code or adding a new one. I currently have email services that creates an Opportunity.  I am not really a coder, I am just looking around how to get this done.

My goal is that when user send an email from that Opportunity record (generated from Email services) and customer replies back (with threadId generated initially), the response of the customer should be attached to existing Opportunity. How can I achieve that? Should I attach it to existing code that I have?

Here is my existing Code that generates Opportunity record:
global class OpportunityCreation implements Messaging.InboundEmailHandler {

  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,
    Messaging.InboundEnvelope envelope) {

     Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
     String fName = email.fromname.substring(0,email.fromname.indexOf(' '));
     String lName = email.fromname.substring(email.fromname.indexOf(' '));
     Contact vCon;
     for(Contact c: [Select Id, Name, Email, AccountId From Contact Where Email = :email.fromAddress Limit 1])
         vCon = c;
     if(vCon == null)
        vCon = new Contact(
        FirstName = fName,
        LastName =  lName,
        Email = email.fromAddress);
        insert vCon;
     Opportunity opportunity = new Opportunity();
     opportunity.Name = email.Subject;
     opportunity.StageName = 'Prospecting';
     opportunity.CloseDate =;
     opportunity.Email_Body__c = email.plainTextBody;
     opportunity.Contact_Name__c = vCon.Id;
     opportunity.AccountId = vCon.AccountId;
     insert opportunity;
       System.debug('====> Created opportunity '+opportunity.Id);
if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) {
      for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) {
        Attachment attachment = new Attachment();
        // attach to the newly created opportunity record
        attachment.ParentId = opportunity.Id;
        attachment.Name = email.binaryAttachments[i].filename;
        attachment.Body = email.binaryAttachments[i].body;
        insert attachment;
    return result;



Thank you in advance.

Deepak Kumar ShyoranDeepak Kumar Shyoran
The above code will create a new Opportunity and will add the Binary Attachment if any associated with email to the newly created Opportunity.

And if you also want to add Other Attachment like text to add as an attachment to new Opportunity then use below code also in-addition to your code.
//Fetching Text attachment from Email and adding them to attachmentToInsert list
if (email.textAttachments != null && email.textAttachments.size() > 0) {
for (Integer i = 0 ; i < email.textAttachments.size() ; i++) {
Attachment attachment = new Attachment();
attachment.ParentId = opportunity.Id;
attachment.Name = email.textAttachments[i].filename;
attachment.Body = Blob.valueOf(email.textAttachments[i].body);
attachmentToInsert.add(attachment) ;

Ekin Van WinkleEkin Van Winkle
Did you ever find a way to associate an email to an Existing Opportunity?
Mark Neill 13Mark Neill 13
Here is my class for parsing the inbound email
Note that I had already sent the OPPORTUNITY RECORD ID to the sender

They must reply to my emaiil service address making sure to incude the OPP ID in the SUBJECT (ie [OPPID 15 characters]  )in brackets.

I then parse the subject for the OPP ID to create a follow-up task, load the email activity, and save the attachments in the OPP Record

I hope this helps.

global class Email_CreateOppTask_Attach_ChicagoTitle implements Messaging.InboundEmailHandler {
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, 
                                                       Messaging.InboundEnvelope env){
    // Create an InboundEmailResult object for returning the result of the 
    // Apex Email Service
    Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
    String myPlainText= '';

    // Add the email plain text into the local variable 
    myPlainText = email.plainTextBody;
    //Get RefID which is the OPP ID from the email subject
    String RefID = email.subject.substring(email.subject.indexOf('['));
    Integer Refidloc = email.subject.indexOf('[');
    System.debug('RefiD: ' + refID ); 
    System.debug('RefiDIndex: ' + RefIDloc ); 
    String OPPID = email.subject.substring(refIDLoc + 1,refIDLoc + 16);
    System.debug('OPPID is: ' + OPPID );

 if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) {
      for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) {
        Attachment attachment = new Attachment();
        //attach to the newly created opportunity record
        attachment.ParentId = oppID;
        //attachment.ParentId = '0065C0000030oCH';
        attachment.Name = email.binaryAttachments[i].filename;
        attachment.Body = email.binaryAttachments[i].body;
        insert attachment;
   if(email.textAttachments != null)
            // Save attachments, if any
            for (Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments) {
              Attachment attachment = new Attachment();
              attachment.Name = tAttachment.fileName;
              attachment.Body = Blob.valueOf(tAttachment.body);
              attachment.ParentId = oppID;
              //attachment.ParentId = '0065C0000030oCH';
              insert attachment;
    // New Task object to be created
    Task[] newTask = new Task[0];
    // Try to look up any contacts based on the email from address
    // If there is more than one contact with the same email address,
    // an exception will be thrown and the catch statement will be called.
    try {
      Contact vCon = [SELECT Id, Name, Email
        FROM Contact
        WHERE Email = :email.fromAddress
        LIMIT 1];
      // Add a new Task to the contact record we just found above.
      newTask.add(new Task(Description =  myPlainText,
           Priority = 'Normal',
           Status = 'Inbound Email',
           Subject = email.subject,
           Type = 'Email',
           IsReminderSet = true,
           ReminderDateTime =,
           //WHatId = '0065C0000030oCH',
           WhatId = oppID,
           WhoId =  vCon.Id));
     // Insert the new Task 
     insert newTask;    

     System.debug('New Task Object: ' + newTask );   
    // If an exception occurs when the query accesses 
    // the contact record, a QueryException is called.
    // The exception is written to the Apex debug log.
   catch (QueryException e) {
       System.debug('Query Issue: ' + e);
   // Set the result to true. No need to send an email back to the user 
   // with an error message
   result.success = true;
   // Return the result for the Apex Email Service
   return result;