My current Apex Trigger places the last activity subject into a custom field I created for both leads and opportunities. I am rather unfamiliar with triggers and I am still unsure exactly what I can do with them. I was wondering if I could add something like a does not contain function to prevent any activity subjects with a certain word from being placed into the field. I tried adding t.subject.doesnotcontain('word') to line 11 of my code, but that did not work. Does anyone have any suggestions?

Here is my code:

    trigger updateRelatedLeadOrOpportunity on Task (after insert,after update) {
        List<Id> OpportunityIds = new List<Id>();
        List<Opportunity> OpportunityList = new List<Opportunity>();
        List<Id> LeadIds = new List<Id>();
        List<Lead> LeadList = new List<Lead>();
        List<Task> taskToProcess = new List<Task>();

    for(Task t :trigger.new)
        //This will make sure that we only process the task who's subject is added/updated
        if(t.status == 'Completed' && ((trigger.isInsert | trigger.isUpdate) || trigger.newMap.get(t.id).subject != trigger.oldMap.get(t.id).subject)){
            //You'll have WhoId populated when the Task related to a Lead/Contact(only) 
            //and whatId will be populated if the task is realted to Account/Opportunity/Custom Objects...
            if(t.whatId !=null)
                Schema.SObjectType tType= t.whatid.getSObjectType();
                if(tType == Opportunity.Schema.SObjectType)


            if(t.whoId != null){

                Schema.SObjectType tType= t.whoId.getSObjectType();
                if(tType == Lead.Schema.SObjectType)


    //Querying the related Opportunity as well as Lead based on whatid on Task
    map<Id, Opportunity> oppsToUpdateMap = new map<Id, Opportunity>([select id,Last_Activity_Subject__C from Opportunity where id in:OpportunityIds]);
    Map<Id,Lead> LeadMap =  new Map<Id,Lead>([select id,Last_Activity_Subject__C from Lead where id in:LeadIds]);
    //Now we have all the tasks that we need to process in this loop
    for(Task t :taskToProcess){
            Schema.SObjectType tType= t.whatId.getSObjectType();
            if(tType == Opportunity.Schema.SObjectType){
                Opportunity opp = oppsToUpdateMap.get(t.whatId);
                opp.Last_Activity_Subject__C = t.subject;
                oppsToUpdateMap.put(opp.Id, opp);


            Schema.SObjectType tType= t.whoId.getSObjectType();
            if(tType == Lead.Schema.SObjectType){
                Lead lead = LeadMap.get(t.whoId);
                lead.Last_Activity_Subject__C = t.subject;

    // updating the Opportunity and lead
    update oppsToUpdateMap.values();
    if(!LeadList.isEmpty()) update LeadList;

  • if your field is of type text yes you can do !trigger.newMap.get(t.id).subject.contains('Whatever_keywords'); your current implementations checks when subject gets updated, do you want to check for specific keywords in the update?
    – Rao
    Commented Jun 23, 2014 at 16:15
  • It is a text field, andy es I want to make sure that the subject does not contain certain keywords. Where would place that and would it be !trigger.newMap.get(t.id).subject.doesnotcontains('Whatever_keywords'); then instead of contains? Or is there another way I would do that.
    – Alex
    Commented Jun 23, 2014 at 16:20
  • The methods you have available are documented here String Class and adding a ! in front negates e.g. !s.contains('abc') means "s does not contain 'abc'".
    – Keith C
    Commented Jun 23, 2014 at 16:25

2 Answers 2


'!' is not operator in apex. you can check both the conditions

1) trigger.newMap.get(t.id).subject != trigger.oldMap.get(t.id).subject) This checks if the subject has changed.

2) !trigger.newMap.get(t.id).subject.contains('Whatever_keywords');

This specifically checks if the subject DOES NOT (! at the front is a not operator) Whatever_keywords string

Together you can use it as

    if(t.status == 'Completed' && ((trigger.isInsert | trigger.isUpdate) || ((trigger.newMap.get(t.id).subject != trigger.oldMap.get(t.id).subject) && (!trigger.newMap.get(t.id).subject.contains('Whatever_keywords'))))){

To add to rao's answer, your "if" term is getting pretty unwieldy and often when adding code you need to do a but of cleanup work at the same time. Otherwise you code just gets harder and harder to follow.

For example, your inclusion of trigger.isInsert | trigger.isUpdate has no effect because your trigger is declared to only execute when one or other of those is true. (They say nothing about individual field changes.)

So with that removed and a bit of vertical white space introduced:

for (Task t : Trigger.new) {
    Task old = Trigger.oldMap.get(t.Id);
    if (t.status == 'Completed'
            && t.Subject != old.Subject
            && !t.Subject.contains('abc')
            ) {

You must log in to answer this question.

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