3

When a field is populated on an Opportunity record I want to alert a team of users of that. I don't want to spam them with emails so I thought to make a chatter group and then post chatter feed items with the details that they can review whenever.

I wrote this method and it seems to work posting the link to the Opportunity:

public static void competitionAlert(Map<Id, Opportunity> newMap, Map<Id, Opportunity> oldMap)
{
    // Find the Chatter group Id
    CollaborationGroup chatterGroup = [ SELECT Id, Name 
                                        FROM CollaborationGroup 
                                        WHERE Name = 'Competitive Intelligence'];

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

    // loop the Opportunities to see if the compeitition field changed.
    for (Opportunity  oppy : newMap.values())
    {
        if(
            oppy.Competition__c != oldMap.get(oppy.Id).Competition__c &&
            oppy.Competition__c != null
        )
        {
            // create a chatter feed post alerting the team
            FeedItem fpost = new FeedItem();
                fpost.ParentId = chatterGroup.Id;
                fpost.LinkURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' +oppy.Id;
                fpost.Title = oppy.Name;
                fpost.Body = 'An Opportunity was flagged as "Closed Lost" to ' + oppy.Competition__c + ' please review.';
            feedPost.add(fpost);
        }
    }
insert feedPost;
}   

The challenge is that the chatter group needs to be private, so when I lock the group down I get errors when a user who does not have access triggers the method and tries to create the post.

Is there a way to post into groups without having access to the group or a way to post as a user who does?

FINAL Solution:

Handler Class:

public static List<Opportunity> competitionAlertFilter(Map<Id, Opportunity> newMap, Map<Id, Opportunity> oldMap)
{
    List<Opportunity> oppy = new List<Opportunity>();

    // loop the Opportunities to see if the compeitition field changed.
    for (Opportunity  o : newMap.values())
    {
        if(
            o.Competition__c != oldMap.get(o.Id).Competition__c &&
            o.Competition__c != null
        )
            {
                oppy.add(o);
            }
    }
    return oppy;
}

public static void competitionAlert(List<Opportunity> chatFilter)
{
    ChatterPosts.createCompetitiveIntelligencePost(chatFilter);
}
}

Extender Class

public without sharing class ChatterPosts {

public static void createCompetitiveIntelligencePost(List<Opportunity> chatFilter)
{       
    // Find the Chatter group Id
    CollaborationGroup chatterGroup = [ SELECT Id, Name 
                                        FROM CollaborationGroup 
                                        WHERE Name = 'Competitive Intelligence'];

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

    // loop the Opportunities to see if the compeitition field changed.
    for (Opportunity  oppy : chatfilter)
    {
        // create a chatter feed post alerting the team
        FeedItem fpost = new FeedItem();
            fpost.ParentId = chatterGroup.Id;
            fpost.LinkURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' +oppy.Id;
            fpost.Title = oppy.Name;
            fpost.Body = 'An Opportunity was flagged as "Closed Lost" to ' + oppy.Competition__c + ' please review.';
        feedPost.add(fpost);
    }
insert feedPost;
}    

}

I'm excited about this methodology because for future use cases I can pass whatever data to the ChatterPosts class and not run into this issue again.

3 Answers 3

2

It's a very common problem. I have already faced the same issue.the solution is to move the same functionality in the trigger. As the trigger run on system mode,then there will be no issue regarding access.Then error what you get will be resolve. I have tried and it is working fine for me.

3
  • what if the specific code runs without sharing class? Apr 13, 2017 at 18:06
  • I think Dan is facing the issue because it was a sharing class..And without knowing functionality i can't suggest him to make it without sharing
    – Avijit Das
    Apr 13, 2017 at 18:08
  • the class is a trigger handler so I can't make the whole thing without sharing as I don't want to break the other things going on. I think I can break this out into a separate class and make that without sharing. I'll give that a try. Apr 13, 2017 at 18:50
1

Try using the process Builder, When a field is populated on an Opportunity record you can create a post on a specific chatter group based what you need.

I would recommend you check out the this Trailhead which seems to address your use case. Select object/field conditions enter image description here create configure your actions (post to a chatter group, something) enter image description here

You can also reference an apex class to execute upon your object/record update.

4
  • Process Builder does not work. I get "Error Occurred: You don't have permission to do this." when trying to post as a non member of the group. Apr 13, 2017 at 18:48
  • As a sys admin, I recently created a Process that basically Posts on a Chatter private group without being part of it. I think you can even flush your apex class and simply reference the Custom Object fields you want + the message to the chatter group (As a sys admin, even if it is set to private, and you are not a member of it)
    – glls
    Apr 13, 2017 at 19:16
  • Interesting, I must have been doing something wrong. I went with code as I can set a link to the record which didn't seem to be available in PB. Apr 13, 2017 at 19:24
  • @glls I am wondering how your process builder is configured, because we have the same problem as Dan: if the user is not in the private group, the process errors out when the user makes the change that fires the process. Mar 11, 2020 at 16:22
1

I have used flow to create a feeditem record directly, which runs properly in system mode, unlike the post to chatter action in flow / process builder which clearly does not.

At mentions are not possible with this approach, but topic insertion still works. You can post to groups or records that the user does not have access to, and which otherwise throw the 'you do not have permission to do this' error.

You must log in to answer this question.

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