6

I have a custom object with 100 fields, out of those 100 I need to listen to updates for 40 fields (out of those 100 fields). Means if any record gets updated in salesforce for this custom object and field value updated is from these 40 fields then I want to call a webservice (or insert a record in Log object). This is for the purpose of integration with other system outside salesforce (3rd party systm is only interested in those 40 fields value changes).

Few things to note: 1. Third party system needs only record id and they do not need what value changed. 2. I am looking for any options other than trigger 3. Field history audit option is ruled out as we need to listen updates to 40 fields.

What will be the best way to implement this?

Thanks in advance.

2 Answers 2

7

Even though you want to avoid using a trigger, I don't think it's practical to avoid it here. To me, triggers are the most natural way to detect changes in a field.

I think that using a fieldset to dictate which fields you want to monitor is the easiest solution here. Using a fieldset makes the trigger a lot more compact, and is easily updated.

You could accomplish the same thing by declaring a List<String> that contains the API names of the fields you want to monitor, if using a fieldset isn't an option. The only real difference is that I find a fieldset easier to update/maintain.

The only other issue at hand is that to make the callout, you'll need a separate Apex class that has a method with the @isFuture(callout=true) annotation. I'll assume that you don't need help with that part.

A generic example of such a trigger would look like this:

Trigger <<name>> on <<sObject Name>> (after update){
    List<Id> updatedRecordIds = new List<Id>();

    // Gather all of the fields contained in the target fieldset
    List<Schema.FieldSetMember> fields = Schema.SObjectType.<<sObjectName>>.Fieldsets.<<fieldset api name>>.getFields();

    // Iterate over all of the records in `trigger.new`, and see if any of the fields in the fieldset have been changed
    for(<<sobject name>> rec :trigger.new){
        for(Schema.FieldSetMember fsm :fields){
            // The getFieldPath() method of Schema.FieldSetMember returns the API name of the field.
            if(rec.get(fsm.getFieldPath()) != trigger.oldMap.get(rec.Id).get(fsm.getFieldPath())){
                updatedRecordIds.add(rec.Id);

                // After the first change is detected, we don't care about the rest of the fields.
                // Break out of the inner loop to save cpu time (and to not add the same Id to the list multiple times)
                break;
            }
        }
    }

    // Call the future method, in another apex class, that allows callouts ( @isFuture(callout=true) )
    SomeClass.callout(updatedRecordIds);

}
4
  • 4
    Good usage of break statement in this context. Mar 30, 2016 at 17:12
  • if all triggers used a common SoC Domain layer or common trigger handler framework, then the detection/logging could be done by a method in a single Domain/trigger handler superclass.
    – cropredy
    Mar 30, 2016 at 17:13
  • I love fieldsets, I think using fieldsets for this is spot on! thanks for your answer. I am now thinking about writing workflow vs trigger. Mar 30, 2016 at 20:04
  • +1 for the suggestion of using a field set. That would've been my recommendation. Jul 9, 2016 at 4:56
5

There are two other options other than a trigger:

  • Workflow Rule w/ Outbound Message
  • Streaming API

The Workflow Rule w/ Outbound Message is the better of the two choices. You can use the ISCHANGED() formula 40 times in your workflow rule that is evaluated when a record is created, and every time it's edited. This'll send a SOAP message to the endpoint you specify in the outbound message that'll include at minimum the affected record's Id.

Outbound Messaging WSDL

Setting Up Outbound Messaging

You must log in to answer this question.

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