How do I use the Tooling API to create a new Apex Trigger (rather than update an existing one)?
According to the documentation I need to specify the ContentEntityId as an existing Trigger Id. But in my case I don't have an Id because I've trying to create a new sObject.
If I omit the ContentEntityId I get an error back in the SaveResult:
Status Code: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY
Message: "insufficient access rights on cross-reference id"
The following is more or less a test case in C# that attempts to use the SOAP tooling API to create the new trigger.
SforceService toolingService = //... Get instance of the Tooling API
MetadataContainer container = new MetadataContainer();
container.Name = "Test" + DateTime.Now.Ticks;
SaveResult[] saveResult = toolingService.create(new sObject[] { container });
string metaDataContainerId = saveResult[0].id;
ApexTriggerMember apexTriggerMember = new ApexTriggerMember();
apexTriggerMember.MetadataContainerId = metaDataContainerId;
apexTriggerMember.Body = "trigger TestOpportunityBeforeUpdate on Opportunity (before update) {\n//Horray\n}";
// Adding this will successfuly update the existing trigger
//apexTriggerMember.ContentEntityId = "01q70000000GuzP";
SaveResult[] triggerSaveResults = toolingService.create(new sObject[] { apexTriggerMember });
Assert.AreEqual(1, triggerSaveResults.Length);
SaveResult triggerSaveResult = triggerSaveResults[0];
if (!triggerSaveResult.success)
{
Assert.Fail(triggerSaveResult.errors[0].message);
}
Assert.IsTrue(triggerSaveResult.success);
ContainerAsyncRequest containerRequest = new ContainerAsyncRequest();
containerRequest.MetadataContainerId = metaDataContainerId;
containerRequest.IsCheckOnly = false;
SaveResult[] containerResults = toolingService.create(new sObject[] { containerRequest });