I've set up some automation so that when a CampaignMember receives a specific status (Evaluation Request), a Contact, Account, and a set of project records are created. An external system notifies SFDC once the evaluation has started, and an opportunity is automatically created.

So I already have a Contact and Account record. The Contact has a CampaignMember which has already responded, and is the only CampaignMember associated with the Contact (in my test cases, at least).

Here's the first attempt ('ep' and 'ei' are custom objects, but you get the idea):

Opportunity newOpp = new Opportunity(
    AccountId = ep.Account__c,
    Name = ep.Account__r.Name + '-Automated',
    CloseDate = System.today() + 90,
    OwnerId = ep.Account__r.OwnerId,
    StageName = oppStage,
    RecordTypeId = oppRecType);
insert newOpp;

OpportunityContactRole ocr = new OpportunityContactRole(
    OpportunityId = newOpp.Id,
    ContactId = ei.Contact__c,
    IsPrimary = TRUE);
insert ocr;

When I check the Opportunity that is created, the Contact and Campaign show up as expected in the Campaign Influence related list, but the Primary Campaign Source field is not filled in. If you explicitly set the Primary Campaign Source, a new Campaign Influence entry is created, which is not tied to a Contact record.

OK, fine.

I know this works already with another process which creates an Opportunity while running through a Database.LeadConvert() call.

So here's the kludge attempt two, which converts and merges a dummy lead:

Lead l = new Lead(
    LastName = 'Temp',
    Company = 'Temp',
    RecordTypeId = leadRecType);
insert l;

Database.LeadConvert lc = new Database.LeadConvert();
lc.setConvertedStatus('Converted to Opportunity');
lc.setOpportunityName(ep.Account__r.Name + '-Automated');

Opportunity newOpp = new Opportunity();
Database.LeadConvertResult lcr = Database.ConvertLead(lc, FALSE);
if(lcr.isSuccess()) {
    newOpp.Id = lcr.getOpportunityId();
    newOpp.CloseDate = System.today() + 90;
    newOpp.StageName = oppStage;
    newOpp.RecordTypeId = oppRecType;
update newOpp;

Same result.

I can't associate the dummy lead with the Campaign, because the automation is triggered off of the CampaignMember status.

For now, we've settled on asking the sales rep to select the primary OCR manually so that the fields are updated correctly, but this is a ridiculous step when I should be able to set these values directly.

Has anyone had any luck populating the Primary Campaign Source correctly within Apex? It's a black box as far as the SFDC implementation, and I'm considering rolling my own as a replacement. Our marketing team relies on this value heavily.

  • I don't understand what the issue is here? If you set CampaignId on the Opportunity then you get the Campaign Influence record for the Primary Campaign, if you then add the CampaignMember's Contact record as an OpportunityContactRole then you will get the Campaign Influence record for the Contact. Does doing both of those things not achieve what you need? Jul 14, 2014 at 8:34

1 Answer 1


You can assign a campaign to the Opportunity's primary campaign source by:

CampaignMember campaign_member = ...;
Opportunity newOpp = new Opportunity(
    CampaignId: campaign_member.CampaignId,

Check the sforce api for Opportunity here.

  • If you explicitly set the Primary Campaign Source, a new Campaign Influence entry is created, which is not tied to a Contact record. It needs to be tied to the Contact as well.
    – mphillips
    May 19, 2014 at 21:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .