+ Start a Discussion
CNMCNM 

Trigger on Attachment to create new FeedItems

 have been trying to get a trigger to fire when a new attachment is inserted (After insert), the ParentIdis Event for that attachment, and the Event is related to an Account.

So, if anyone inserts an attachment on an Event and that event is related to an Account the following needs to happen:

A Chatter FeedItem needs to be inserted for the Event Owner followers.
A Chatter FeedItem needs to be inserted for the related Account followers for that event.
List item

Note: On the code expose here I'm trying only the account followers.

I know this can be very tricky and I'm trying to at least get it fired, not so such luck so far. The Trigger is on an After Trigger context variable.

Here is the code:
trigger AttachmentTrigger on Attachment (after insert) {


List<FeedItem> feedList = new List<FeedItem>();

    Set<Id> accIds = new Set<Id>();
    Set<Id> ownIds = new Set<Id>();
    Set<Id> eveIds = new Set<Id>();

    for(Attachment a: trigger.new)
    {
      if(a.ParentId.getSObjectType() == Event.SObjectType)
    {
      eveIds.add(a.ParentId); 
    }
  }
      System.debug('Event size ' +eveIds.size());


    if(!eveIds.isEmpty()){
    Map<Id, Event> evenList = new Map<Id, Event>([SELECT OwnerId, Account.Id FROM Event WHERE Id IN :eveIds AND Account.Id != null]); 
    for(Event e: evenList.values()){


    accIds.add(e.Account.Id);
    ownIds.add(e.OwnerId); 
   }
  }

System.debug('Account from event size ' +accIds.size());
System.debug('Owner from event size ' +ownIds.size()); 

List<EntitySubscription> entityListAcct = [SELECT id, ParentId, SubscriberId FROM EntitySubscription WHERE ParentId IN :accIds];
List<EntitySubscription> entityListOwn = [SELECT id, ParentId, SubscriberId FROM EntitySubscription WHERE ParentId IN :ownIds];

System.debug('This is the entityListAcct size: ' + entityListAcct.size());
System.debug('This is the entityListOwn size: ' +entityListOwn.size());

   for(EntitySubscription entityAcct: entityListAcct)
{
   if(!entityListAcct.isEmpty() && entityListAcct.size()>0)
{
    FeedItem accountFeedItem= new FeedItem(
    ParentId = entityAcct.SubscriberId, 
    Body ='This is a message from hell!!'); 

    feedList.add(accountFeedItem); 
    }

  }

   System.debug('This is the feedList size: '+feedList.size()); 

   if(!feedList.isEmpty() && feedList.size()>0){
   insert feedList; 
  }

Any tips on how to get this trigger to fire or why is not firing?? Any help would be much appreciated. Thanks.
Andy BoettcherAndy Boettcher
The trigger is probably being fired - but there may be some logic in there that's not firing correctly.  My advice (outside of reviewing your code in depth) would be to pull up Developer Console and review logs as you are creating attachments - and putting System.Debug messages in your code to show you what's happening where and how.
surasura
As andy said trigger should  always fire for defiend critera  unless it is inactive .
CNMCNM

Hello. 

First, thanks for your feedback. 
I find out that it would better to use the Event object for what I want to do. 
This code is workng pretty good, I just need to work out a bit on the update triggert context variable to remove the check box "has_Attachment__c" if there is not attachment related to the Event. 

Trigger EventWithAttachment on Event (after insert, after update) 
{
	List<Event> eventList = new List<Event>();
    List<FeedItem> feedList = new List<FeedItem>();
    Set<Id> ownerIds = new Set<Id>();
    Set<Id> accountIds = new Set<Id>();
    Set<Id> eventAttachmentsIds = new Set<Id>();
    Id eventID;
    
    for(Event e : trigger.new)
    {
        
        if(e.WhatId.getSObjectType() == Account.SObjectType)
          {
            eventList.add(e); 
          }
    }
    
   Map<Id,Event> eventAttMap = new Map<Id, Event>([SELECT id, OwnerId, Account.Id, has_Attachment__c,
  (SELECT Id   FROM Attachments) FROM Event WHERE Id IN : eventList]); 
    
    for(Event currentEvent: eventAttMap.values())
    {
        for(Attachment a : currentEvent.Attachments)
        {
           if(currentEvent.Attachments != null && currentEvent.has_Attachment__c== false)
             {
            	currentEvent.has_Attachment__c = true; 
            	ownerIds.add(currentEvent.OwnerId);
                accountIds.add(currentEvent.Account.Id);
                eventId = currentEvent.id; 
                update currentEvent;
             }  
        }	
    }			 
    
    List<EntitySubscription> entityListAccount = [SELECT Id, ParentId, SubscriberId
                                                  FROM EntitySubscription
                                                  WHERE ParentId IN: accountIds]; 
    
    for(EntitySubscription entityAccount : entityListAccount)
    {
    
    if(!entityListAccount.isEmpty() && entityListAccount.size() >0){
            
            FeedItem accountFeedItem = new FeedItem(
            ParentId = entityAccount.SubscriberId,
            Body = 'This is the msg',
            LinkUrl = 'https://eu5.salesforce.com/'+ eventId);
            
            feedList.add(accountFeedItem);
    
        }
        
    }
    
    if(!feedList.isEmpty() && feedList.size() >0){
       try 
       {
       	insert feedList; 
       } 
       catch (DMLException ex)
       {
      }
  }
I have been trying to revert the action if without getting what I want: 
 
if(currentEvent.Attachments == null && currentEvent.has_Attachment__c== true)
             {
            	currentEvent.has_Attachment__c = false; 
            	//ownerIds.add(currentEvent.OwnerId); -------> This is not needed because we are not sending FeedItems for this action
                //accountIds.add(currentEvent.Account.Id); -------> This is not needed because we are not sending FeedItems for this action
                //eventId = currentEvent.id; -------> This is not needed because we are not sending FeedItems for this action
                update currentEvent;
             }

But the rest works find ... so, thanks for your responses. 
CNMCNM
On line 10 is better to change 
for(Event e : trigger.new)
    {
        if(e.WhatId.getSObjectType() == Account.SObjectType)
          {
            eventList.add(e);

          }
    }

// For this 

for(Event e : trigger.new)
    {
        if(e.WhatId !=null && e.WhatId.getSObjectType() == Account.SObjectType)
          {
            eventList.add(e);

          }
    }