Sales teams thrive on clarity, follow-ups, and timely actions—and nothing supports that better than automation. When an Opportunity progresses through different sales stages, it often calls for a corresponding action: sending an email, making a call, or logging a follow-up. But relying on manual task creation isn’t scalable—and that’s where Apex automation comes in.
In this blog, we walk through an Apex trigger that automatically creates a Task record every time an Opportunity’s Stage is changed. The Task is linked to the Opportunity and assigned to the logged-in user, giving them an instant reminder to take the next step in the sales process.
This is one of those small automations that significantly boosts sales productivity, ensures consistent follow-up, and removes reliance on memory or manual steps.
🧠 Why This Trigger Is Useful
Changing the stage of an Opportunity is a key signal in the sales lifecycle. Whether the deal is moving from “Prospecting” to “Negotiation” or being marked as “Closed Won,” it often requires immediate next actions. With this trigger in place:
-
A Task is automatically created the moment the stage changes
-
The Task includes all necessary fields and is linked to the Opportunity
-
Users get real-time, automated follow-up prompts without needing to create Tasks manually
-
You reduce the risk of deals going cold due to missed follow-ups
-
It encourages proactive sales behavior and consistency in process
This automation supports sales alignment and speeds up deal cycles by ensuring that every stage movement is actioned appropriately.
🔍 What This Blog Covers
-
How to detect StageName changes using
Trigger.oldMap
-
How to use Apex to create a related Task in the after update context
-
Why the Task is assigned using
UserInfo.getUserId()
-
How to write scalable and bulk-safe logic for multi-record updates
-
Best practices for using a trigger handler class to keep logic clean
-
Where this type of automation fits in sales and CRM workflows
This solution ensures that your sales pipeline stays active, dynamic, and supported by automated task management.
🎯 Real-World Use Cases for This Trigger
-
Sales reps needing timely reminders to follow up on stage changes
-
Sales managers wanting to enforce process compliance at each stage
-
Customer success teams triggering onboarding tasks once a deal is won
-
B2B sales teams tracking multi-step engagement through the pipeline
-
Revenue operations who want consistent engagement logged throughout the sales cycle
This trigger can be easily adapted for different sales models, lead handoff structures, or pipeline designs.
👨💻 Developer & Admin Tips
The trigger runs in the after update context, which ensures that:
-
The new
StageName
has already been committed to the Opportunity -
You can safely reference fields like
WhatId
when creating the Task
Here’s how the logic works:
-
It compares the old and new
StageName
usingTrigger.oldMap
-
If a change is detected, it creates a Task record
-
The Task is assigned to the current user (
UserInfo.getUserId()
), but this can be modified to assign to the Opportunity Owner or a queue -
All Task records are collected in a list and inserted using a single DML operation for bulk safety
The Task includes default fields:
-
Subject: “Email”
-
Status: “Not Started”
-
Priority: “Normal”
-
Owner: Current user
You can easily enhance this by:
-
Customizing the subject based on the new stage
-
Adding due dates or descriptions
-
Assigning based on business rules using Role or Profile logic
🎥 Walkthrough Included – YouTube Playlist
For those who prefer visual learning, this trigger is covered in the Salesforce Makes Sense YouTube playlist. You’ll learn:
-
How to structure the logic
-
Where to use
UserInfo.getUserId()
-
How to test and deploy the trigger
-
Best practices for bulk testing with multiple Opportunities
This playlist is designed for real-world use cases—not theory—so you can apply what you learn right away.
Solution:
trigger OpportunityTrigger on Opportunity (after update) {
if(Trigger.isUpdate){ if(Trigger.isAfter){
OpportunityTriggerHandler.createTask(Trigger.New,
Trigger.oldMap);
}
}
}
public class OpportunityTriggerHandler { public static void createTask(List<Opportunity>
oppList,Map<Id,Opportunity>
oldMap){ List<Task> tList= new List<Task>(); for(Opportunity opp:oppList){
if(opp.StageName!=oldMap.get(opp.Id).StageName){ Task t =
new Task(); t.WhatId = opp.Id;
t.Subject = ‘Email’;
t.Priority = ‘Normal’; T.status = ‘Not
Started’;
t.OwnerId = UserInfo.getUserId(); tList.add(t);
}
}
If(tList.size( ) > 0){ insert tList;
}
}}