Skip to content

Instantly share code, notes, and snippets.

@pchittum
Last active August 29, 2015 13:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pchittum/9681222 to your computer and use it in GitHub Desktop.
Save pchittum/9681222 to your computer and use it in GitHub Desktop.
Advanced ELEVATE Triggers
In this exercise, you will create a trigger that will address the problem of people creating
bad topics in your org. We will create logic to remove bad topics from chatter posts and replace them
with good topics.
The trigger executes on the TopicAssignment object on insert. It then attempts to delete the bad
TopicAssignment record and insert a new one. Because the trigger is on insert and also calls insert
we risk the problem of a recursive trigger, which must be addressed by using a variable to maintain the
execution state of the trigger.
1. Top prepopulate our "good" topics, run the following execute anonymous code:
List<Topic> topics = new List<Topic>();
Topics.add(new Topic(Name='ELEVATE'));
Topics.add(new Topic(Name='Developer'));
insert topics;
2. Copy the TopicHelper class code into your org. Find the "TODO" sections and work on them.
3. Copy the TopicAssignmentTrigger code into your org. Find the "TODO" sections and work on them.
4. See if you can add logic to also remove the bad Topic record.
5. For a real challenge, see if you can make a lead record feed, with the correct topic fire
the lead conversion process.
public with sharing class TopicHelper {
/*
*/
//TODO: add a public static boolean variable, set to true
public static Map<String,String> kBlacklist = new Map<String,String>();
// I need a map between the acceptable topics and an Id value.
public static final Map<String,Topic> whiteTopicsDB = new Map<String,Topic>();
static {
//normally something like this would be better in a custom setting
//TODO: create 3-4 more map entries. the key is the "bad" topic. The value
// is the acceptable topic we will use in its place
kBlacklist.put('Elevat','ELEVATE');
//dedupe "good" topics and get the keys of all good topics we might need for later.
Set<String> whiteTopicNames = new Set<String>(kBlacklist.values());
for (Topic t : [SELECT Id,Name,TalkingAbout from Topic where Name in : whiteTopicNames]){
whiteTopicsDB.put(t.Name,t);
}
System.debug('GRAYLIST----->' + kBlacklist);
System.debug('TOPICS in DB----->' + whiteTopicsDB);
}
//need all topics currently associated with this Entity record so that we don't duplicate
//the topic association record. No two topics should be assigned to the same feed post or
//other entity. what is an entity will transform as this feature evolves.
public static Map<Id,Set<Id>> getExistingEntityTopics(List<TopicAssignment> tas){
Map<Id,Set<Id>> existingEntityTopics = new Map<Id,Set<Id>>();
Set<Id> entityIds = new Set<Id>();
for (TopicAssignment ta : tas) {
entityIds.add(ta.EntityId);
}
//This query is necessary to ensure that all other topics associated with this entity record are checked.
//for instance, if the topic SalesforceTopics was already used, but is not in the scope of Trigger.new
//we need to make sure we don't attempt to assign it a second time.
for (TopicAssignment ta : [select EntityId,TopicId from TopicAssignment where EntityId in : entityIds]){
if (!existingEntityTopics.keySet().contains(ta.EntityId)){
existingEntityTopics.put(ta.EntityId,new Set<Id>{ta.TopicId});
} else {
existingEntityTopics.get(ta.EntityId).add(ta.TopicId);
}
}
return existingEntityTopics;
}
}
trigger TopicAssignmentTrigger on TopicAssignment (after insert) {
/*SOQL of note:
TOPIC All Fields
Select t.TalkingAbout, t.SystemModstamp, t.Name, t.Id, t.Description, t.CreatedDate, t.CreatedById From Topic t
TOPICASSIGNMENT All Fields:
FEEDITEM All Fields
*/
//Lists to build in trigger
List<TopicAssignment> correctTAInsert = new List<TopicAssignment>(); //new list of topic assignments we will add
List<TopicAssignment> graylistTADelete = new List<TopicAssignment>(); //list of topic assignments to wipe out
Set<Id> feedItemIdSet = new Set<Id>();
for (TopicAssignment ta : [SELECT Id,EntityId,TopicId,Topic.Name from TopicAssignment where Id in : Trigger.new]) {
//TODO: add an if block and test your static variableskip if trigger is recursive.
if (TopicHelper.kBlacklist.keySet().contains(ta.Topic.Name)){
TopicAssignment newTopic = new TopicAssignment();
newTopic.EntityId=ta.EntityId;
System.debug('The bad topic is: '+ta.Topic.Name);
newTopic.TopicId=TopicHelper.whiteTopicsDB.get(TopicHelper.kBlacklist.get(ta.Topic.Name)).Id;
correctTAInsert.add(newTopic);
graylistTADelete.add(new TopicAssignment(Id=ta.Id));
}
}
//TODO: set the static variable to false before
TopicHelper.firstRun = false;
System.debug('To INSERT----->' +correctTAInsert);
System.debug('To DELETE----->' +graylistTADelete);
delete graylistTADelete;
insert correctTAInsert;
}
trigger TopicAssignmentTrigger on TopicAssignment (after insert) {
/*SOQL of note:
TOPIC All Fields
Select t.TalkingAbout, t.SystemModstamp, t.Name, t.Id, t.Description, t.CreatedDate, t.CreatedById From Topic t
TOPICASSIGNMENT All Fields:
FEEDITEM All Fields
*/
//Lists to build in trigger
List<TopicAssignment> correctTAInsert = new List<TopicAssignment>(); //new list of topic assignments we will add
List<TopicAssignment> graylistTADelete = new List<TopicAssignment>(); //list of topic assignments to wipe out
Set<Id> feedItemIdSet = new Set<Id>();
for (TopicAssignment ta : [SELECT Id,EntityId,TopicId,Topic.Name from TopicAssignment where Id in : Trigger.new]) {
//skip if trigger is recursive.
if (TopicHelper.firstRun){
if (TopicHelper.kBlacklist.keySet().contains(ta.Topic.Name)){
TopicAssignment newTopic = new TopicAssignment();
newTopic.EntityId=ta.EntityId;
System.debug('The bad topic is: '+ta.Topic.Name);
newTopic.TopicId=TopicHelper.whiteTopicsDB.get(TopicHelper.kBlacklist.get(ta.Topic.Name)).Id;
correctTAInsert.add(newTopic);
graylistTADelete.add(new TopicAssignment(Id=ta.Id));
}
}
}
TopicHelper.firstRun = false;
System.debug('To INSERT----->' +correctTAInsert);
System.debug('To DELETE----->' +graylistTADelete);
delete graylistTADelete;
insert correctTAInsert;
//-->lead TopicHelper.convertLeads(leadsToConvert);
}
public with sharing class TopicHelper {
/*
*/
//we are calling insert for an object with an insert trigger
//to avoid invoking the code twice, we will control reentry with this variable
public static Boolean firstRun = true;
public static Map<String,String> kBlacklist = new Map<String,String>();
// I need a map between the acceptable topics and an Id value.
public static final Map<String,Topic> whiteTopicsDB = new Map<String,Topic>();
static {
//normally something like this would be better in a custom setting
kBlacklist.put('Smellevate','ELEVATE');
kBlacklist.put('Elevat','ELEVATE');
kBlacklist.put('Developpeur','Developer');
kBlacklist.put('Dev','Developer');
//dedupe "good" topics
Set<String> whiteTopicNames = new Set<String>(kBlacklist.values());
for (Topic t : [SELECT Id,Name,TalkingAbout from Topic where Name in : whiteTopicNames]){
whiteTopicsDB.put(t.Name,t);
}
System.debug('GRAYLIST----->' + kBlacklist);
System.debug('TOPICS in DB----->' + whiteTopicsDB);
}
//need all topics currently associated with this Entity record so that we don't duplicate
//the topic association record. No two topics should be assigned to the same feed post or
//other entity. what is an entity will transform as this feature evolves.
public static Map<Id,Set<Id>> getExistingEntityTopics(List<TopicAssignment> tas){
Map<Id,Set<Id>> existingEntityTopics = new Map<Id,Set<Id>>();
Set<Id> entityIds = new Set<Id>();
for (TopicAssignment ta : tas) {
entityIds.add(ta.EntityId);
}
//This query is necessary to ensure that all other topics associated with this entity record are checked.
//for instance, if the topic SalesforceTopics was already used, but is not in the scope of Trigger.new
//we need to make sure we don't attempt to assign it a second time.
for (TopicAssignment ta : [select EntityId,TopicId from TopicAssignment where EntityId in : entityIds]){
if (!existingEntityTopics.keySet().contains(ta.EntityId)){
existingEntityTopics.put(ta.EntityId,new Set<Id>{ta.TopicId});
} else {
existingEntityTopics.get(ta.EntityId).add(ta.TopicId);
}
}
return existingEntityTopics;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment