Skip to content

Instantly share code, notes, and snippets.

@the-dvlpr
Last active January 29, 2020 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save the-dvlpr/20ec966eb5a7d9bca10e95f97bf2164c to your computer and use it in GitHub Desktop.
Save the-dvlpr/20ec966eb5a7d9bca10e95f97bf2164c to your computer and use it in GitHub Desktop.
An email opt out option for Salesforce via a reply email.

Use this to allow a user to unsubscribe from a newsletter via a reply email

// This is the updated code to be used for the Salesforce plugin: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N300000016YDZEA2
// Install the plubin.
// Changout all of the Apex installed in the unsubscribe class with updated code below. 
// Add the custom field hasOptedOutOfEmail__c (without the __c, salesforce will add that) to your Lead and Contact object.
// Create an email in Setup > Custom Code > Email Services (and make it active)
// Then just append ?subject=Unsubscribe to the end of the email and insert that link into any mailings.
// This allows a user to unsubscribe via email.
// Use a process to automate any changes when the hasOptedOutofEmail__c checkbox is changed to true. ie check the standard salesforce EmailOptOut or unsubscribe them from a specific list
// Further documentation can be found here: https://appexchange.salesforce.com/servlet/servlet.FileDownload?file=00P3000000P3Vv2EAF
Global class unsubscribe 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();
 
		// Contact and Lead lists to hold all the updated records
		List<Contact> lc = new List <contact>();
		List<Lead> ll = new List <lead>();
 
		// Convert the subject line to lower case, so I can match on lower case
		String mySubject = email.subject.toLowerCase();
		// String I am searching for in the subject line
		String s = 'unsubscribe';
 
		// Check variable to see if the word "unsubscribe" was found in the subject line 
		Boolean unsubMe;
                                
		// Look for the unsubcribe word in the subject line, 
		// if it is found return true, otherwise false is returned
		unsubMe = mySubject.contains(s);
 
 		// If unsubscribe is found in the subject line enter the if statement
 		if (unsubMe == true) {
    		try {
    			// Lookup all contacts with a matching email address
     			for (Contact c : [Select Id, Name, Email, hasOptedOutOfEmail__c From Contact
                	        Where Email = :env.fromAddress And hasOptedOutOfEmail__c = false Limit 100]) {            
        			// Add all the contacts into the List   
            		c.hasOptedOutOfEmail__c = true;
            		lc.add(c);                                 
    			}    
        		// update all the Contact records
        		update lc;
        	} catch (System.QueryException e) {
        		System.debug('Contact Query Issue: ' + e);
        	}   

    		try { 
            	// Lookup all leads matching the email address
     			for (Lead l : [Select Id, Name, Email, hasOptedOutOfEmail__c From Lead Where Email = :env.fromAddress
                        	And isConverted = false And hasOptedOutOfEmail__c = false Limit 100]) {
        			// Add all the leads to the List        
        			l.hasOptedOutOfEmail__c = true;
        			ll.add(l);
                               
           			System.debug('Lead Object: ' + l);   
    			}    
        		// Update all Lead records in the query
        		update ll;
        	} catch (System.QueryException e) {
        		System.debug('Lead Query Issue: ' + e);
        	}   

    		System.debug('Found the unsubscribe word in the subject line.');
		} else {
    		System.debug('No Unsuscribe word found in the subject line.' );
 		}
		// Return true and exit
		// True will confirm it is complete and no bounced email 
		// should be the sender of the unsubscribe request. 
		result.success = true;
		return result;
    }
  

    // Test method to ensure you have enough code coverage
    // Have created two methods, one that does the testing
    // with a valid "unsubcribe" in the subject line
    // and one the does not contain "unsubscribe" in the
    // subject line
    static testMethod void testUnsubscribe() {
        // Create a new email and envelope object
        Messaging.InboundEmail email = new Messaging.InboundEmail() ;
        Messaging.InboundEnvelope env    = new Messaging.InboundEnvelope();
        
        // Create a new test Lead and insert it in the Test Method        
        Lead l = new lead(firstName='Seph', lastName='Cordovano',
                          Company='Southern Cloud', Email='seph@southerncloud.com', 
                          HasOptedOutOfEmail__c=false);
        insert l;
        
        // Create a new test Contact and insert it in the Test Method  
        Contact c = new Contact(firstName='Josh', lastName='Robinson', 
                                Email='Josh@southerncloud.com', HasOptedOutOfEmail__c=false);
        insert c;
        
        // Instantiate the class
        unsubscribe unsub = new unsubscribe(); 
        
        // Set email for testing Lead with subject that matches the unsubscribe statement
        email.subject = 'test unsubscribe test';
        env.fromAddress = 'seph@southerncloud.com';
        
        // Test the class method against the Lead 
        unsub.handleInboundEmail(email, env );
        
        // Set email for testing Contact with subject that matches the unsubscribe statement
        env.fromAddress = 'josh@southerncloud.com';
        
        // Test the class method against the Contact 
        unsub.handleInboundEmail(email, env );     
    }
    
    static testMethod void testNonUnsubscribe() {
        // Create a new email and envelope object
        Messaging.InboundEmail email = new Messaging.InboundEmail() ;
        Messaging.InboundEnvelope env    = new Messaging.InboundEnvelope();
        
        // Create a new test Lead and insert it in the Test Method        
        Lead l = new lead(firstName='Seph', lastName='Cordovano',
                          Company='Southern Cloud', Email='seph@southerncloud.com', 
                          HasOptedOutOfEmail__c=false);
        insert l;
        
        // Create a new test Contact and insert it in the Test Method  
        Contact c = new Contact(firstName='Josh', lastName='Robinson', 
                                Email='Josh@southerncloud.com', HasOptedOutOfEmail__c=false);
        insert c;
        
        // Instantiate the class
        unsubscribe unsub = new unsubscribe(); 
        
        // Set email for testing Lead with subject that matches the unsubscribe statement
        email.subject = 'test subject';
        env.fromAddress = 'seph@southerncloud.com';
        
        // Test the class method against the Lead 
        unsub.handleInboundEmail(email, env );
        
        // Set email for testing Contact with subject that matches the unsubscribe statement
        env.fromAddress = 'josh@southerncloud.com';
        
        // Test the class method against the Contact 
        unsub.handleInboundEmail(email, env );                       
    }
   
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment