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
Liz Gibbons 16Liz Gibbons 16 

Automate Customer Community user creation

We have partnered with a new organization and have the potential to have 20000 new customer community users request access over the next 2 months. We have been using self registration, but for this partnership, we don't want to have people duplicating efforts. We have set up a connection where the partner will send us users' data via SFTP and we will use Jitterbit to insert that into Salesforce as Contacts. My problem comes from creating Customer Community Users from those Contacts. You can't create users via workflow and this needs to go live on April 1.

Any thoughts? 
Best Answer chosen by Liz Gibbons 16
Shashikant SharmaShashikant Sharma
Hi Liz,


In your exeute method remove:
1. 
scope = [SELECT Id, Name, Email FROM Contact WHERE Account.Name = 'Philadelphia Youth Network'];
Reason:  scope is already coming from start method.

Send email outside the loop to bulkify it. Although I would still suggest to keep the batch size 1 initially.
global void execute(Database.BatchableContext BC, List<Contact> scope){
        String Passwd;
        
        Profile LPCommPf = [SELECT Id, Name FROM Profile WHERE Name = 'Learner Profile Community User' LIMIT 1];

        List<Messaging.SingleEmailMessage> setPWs = new List<Messaging.SingleEmailMessage>();

        for (Contact c : scope){
            User u = new User();
            	u.FirstName = c.FirstName;
                u.LastName = c.LastName;
                u.ContactId = c.Id;
                u.Email = c.Email;
                u.Username = c.Email;
                u.CommunityNickname = c.Email.Trim().toLowerCase();
                u.Alias = c.Name.Trim().toLowerCase();
                u.ProfileId = LPCommPf.id;
                u.LocaleSidKey = 'en_US';
                u.TimeZoneSidKey = 'EDT';
                u.LanguageLocaleKey = 'en_US';
                u.EmailEncodingKey = 'UTF-8';
                String pwd = Passwd;
                
                String userId = Site.createPortalUser(u, pwd);
            
        
            
            Messaging.SingleEmailMessage setPW = new Messaging.SingleEmailMessage();
        	List<String> sendTo = new List<String>();
        	sendTo.add(u.Email);
        	setPW.setToAddresses(sendTo);
        	setPW.setSenderDisplayName('info@digitalonramps.com');
        	setPW.setSenderDisplayName('Digital On-Ramps');
        	setPW.setTemplateId('005G0000003zJsm'); 
        	setPW.setTargetObjectId(u.Id);
        	setPW.setSaveAsActivity(false);
            
            setPWs.add(setPW);
            

        }
            Messaging.sendEmail(setPWs);

    }

 

You could try to run the Batch Class 

By either running it from Developer Console: https://help.salesforce.com/apex/HTViewSolution?id=000171199&language=en_US

Or by adding a scheduled job. Steps are: 

1. Create a Schedule Apex Class calling this Batch
 
global class scheduledMerge implements Schedulable {
   global void execute(SchedulableContext SC) {
      ConvertToCommUsers clsBatch  = new ConvertToCommUsers(); 
      
      // here 1 is the batch size
      Database.executeBatch( clsBatch, 1 );

   }
}

2. Schedule the JOB for this schedule apex class : https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_scheduling_3.htm


Thanks
Shashikant

 

All Answers

Shashikant SharmaShashikant Sharma
You could do is to develop a Apex Batch Class. So what you will be doing is just creating the Contact but a Apex Batch Class will pcik the contacts and create users from it. 

Let me know if you need help in developing Apex Batch Job.

Thanks
Shashikant
Liz Gibbons 16Liz Gibbons 16
Thanks Shashikant!

I'm a newbie developer, but I took a stab at it. Feedback would be greatly appreciated!
 
global class ConvertToCommUsers implements Database.Batchable<sObject> {
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        String query = 'SELECT	Id, Name, Email FROM Contact WHERE Account.Name = "Philadelphia Youth Network"'; 
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext BC, List<Contact> scope){
        String Passwd;
        scope = [SELECT Id, Name, Email FROM Contact WHERE Account.Name = 'Philadelphia Youth Network'];
        Profile LPCommPf = [SELECT Id, Name FROM Profile WHERE Name = 'Learner Profile Community User' LIMIT 1];
        
        for (Contact c : scope){
            User u = new User();
            	u.FirstName = c.FirstName;
                u.LastName = c.LastName;
                u.ContactId = c.Id;
                u.Email = c.Email;
                u.Username = c.Email;
                u.CommunityNickname = c.Email.Trim().toLowerCase();
                u.Alias = c.Name.Trim().toLowerCase();
                u.ProfileId = LPCommPf.id;
                u.LocaleSidKey = 'en_US';
                u.TimeZoneSidKey = 'EDT';
                u.LanguageLocaleKey = 'en_US';
                u.EmailEncodingKey = 'UTF-8';
                String pwd = Passwd;
                
                String userId = Site.createPortalUser(u, pwd);
            
        List<Messaging.SingleEmailMessage> setPWs = new List<Messaging.SingleEmailMessage>();
            
            Messaging.SingleEmailMessage setPW = new Messaging.SingleEmailMessage();
        	List<String> sendTo = new List<String>();
        	sendTo.add(u.Email);
        	setPW.setToAddresses(sendTo);
        	setPW.setSenderDisplayName('info@digitalonramps.com');
        	setPW.setSenderDisplayName('Digital On-Ramps');
        	setPW.setTemplateId('005G0000003zJsm'); 
        	setPW.setTargetObjectId(u.Id);
        	setPW.setSaveAsActivity(false);
            
            setPWs.add(setPW);
            
            Messaging.sendEmail(setPWs);
        }
    }
    
    global void finish(Database.BatchableContext BC){
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(new String[] {'meg372@drexel.edu'});
        	mail.setReplyTo('batch@digitalonramps.com');
        	mail.setSenderDisplayName('Batch Processing');
        	mail.setSubject('Batch Process Complete');
        	mail.setPlainTextBody('Batch Process has completed');
        
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
        
    }

}

 
Shashikant SharmaShashikant Sharma
Hi Liz,


In your exeute method remove:
1. 
scope = [SELECT Id, Name, Email FROM Contact WHERE Account.Name = 'Philadelphia Youth Network'];
Reason:  scope is already coming from start method.

Send email outside the loop to bulkify it. Although I would still suggest to keep the batch size 1 initially.
global void execute(Database.BatchableContext BC, List<Contact> scope){
        String Passwd;
        
        Profile LPCommPf = [SELECT Id, Name FROM Profile WHERE Name = 'Learner Profile Community User' LIMIT 1];

        List<Messaging.SingleEmailMessage> setPWs = new List<Messaging.SingleEmailMessage>();

        for (Contact c : scope){
            User u = new User();
            	u.FirstName = c.FirstName;
                u.LastName = c.LastName;
                u.ContactId = c.Id;
                u.Email = c.Email;
                u.Username = c.Email;
                u.CommunityNickname = c.Email.Trim().toLowerCase();
                u.Alias = c.Name.Trim().toLowerCase();
                u.ProfileId = LPCommPf.id;
                u.LocaleSidKey = 'en_US';
                u.TimeZoneSidKey = 'EDT';
                u.LanguageLocaleKey = 'en_US';
                u.EmailEncodingKey = 'UTF-8';
                String pwd = Passwd;
                
                String userId = Site.createPortalUser(u, pwd);
            
        
            
            Messaging.SingleEmailMessage setPW = new Messaging.SingleEmailMessage();
        	List<String> sendTo = new List<String>();
        	sendTo.add(u.Email);
        	setPW.setToAddresses(sendTo);
        	setPW.setSenderDisplayName('info@digitalonramps.com');
        	setPW.setSenderDisplayName('Digital On-Ramps');
        	setPW.setTemplateId('005G0000003zJsm'); 
        	setPW.setTargetObjectId(u.Id);
        	setPW.setSaveAsActivity(false);
            
            setPWs.add(setPW);
            

        }
            Messaging.sendEmail(setPWs);

    }

 

You could try to run the Batch Class 

By either running it from Developer Console: https://help.salesforce.com/apex/HTViewSolution?id=000171199&language=en_US

Or by adding a scheduled job. Steps are: 

1. Create a Schedule Apex Class calling this Batch
 
global class scheduledMerge implements Schedulable {
   global void execute(SchedulableContext SC) {
      ConvertToCommUsers clsBatch  = new ConvertToCommUsers(); 
      
      // here 1 is the batch size
      Database.executeBatch( clsBatch, 1 );

   }
}

2. Schedule the JOB for this schedule apex class : https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_scheduling_3.htm


Thanks
Shashikant

 
This was selected as the best answer
Liz Gibbons 16Liz Gibbons 16
That makes sense. I'm getting an error now: System.QueryException: line 1:57 no viable alternative at character '"'

Thoughts on what might be causing that?

Thanks,
Liz
Shashikant SharmaShashikant Sharma
Change the "Philadelphia Youth Network" to \'Philadelphia Youth Network\' in the Query

So the query will be 

 
String query = 'SELECT  Id, Name, Email FROM Contact WHERE Account.Name = \'Philadelphia Youth Network\'';

Thanks
Shashikant
Liz Gibbons 16Liz Gibbons 16
Ok, that work! The class is running. I think I've only got one last issue before it works without error. 

Lline 29: String userId= Site.createPortalUser(u, pwd);
I get a 'Method not yet implemented: createPortalUser(User, String)' error.
I have changed createPortalUser to createExternalUser(sObject, String) and get the error: '[That operation is only allowed from within an active site]'

Thoughts?

Thanks,
Liz
Liz Gibbons 16Liz Gibbons 16
I got it. It should be just a DML insert. createPortalUser and createExternalUser create Contact and User. 

Thanks so much for all your help, Shashikant!
Shashikant SharmaShashikant Sharma
Happy that it helped you :).

Thanks
Shashikant