Email based approval as a part of Workflow step | Community
Skip to main content
Level 8
February 11, 2026
Solved

Email based approval as a part of Workflow step

  • February 11, 2026
  • 3 replies
  • 46 views

Hi all.

 

One of the steps in a workflow is an approval and that approval link was shared to the end user by email.

After he approves/disapproves in the email, how to get the result back into AEM, and specific to the work item in question?

Email based approval as a part of Workflow step.

 

Appreciate all your replies.

 

Thanks,

RK.

    Best answer by Vishal_Anand

    @nsvsrk You can perform below steps:
     

    1 - Add an approval step to the workflow

    • Use a Participant or Process step that pauses the workflow and triggers sending an email.
    • Persist the current work item id (or workflow instance id) and a short-lived secure token in JCR (/var/workflow-approvals/<token>) or in the workflow metadata so the link can be validated later.

    2 - Build email with secure links

    • Include two links (approve / reject) pointing to a Sling servlet endpoint, e.g.:
    • Do not include PII. Use IDs and tokens only.

    3 - Create a secure servlet to handle clicks

    • Implement a Sling servlet (GET or POST) at /bin/wf-approval.
    • Steps inside servlet:
      1. Validate token and ensure it maps to the expected workItemId and is not expired.
      2. Obtain a ResourceResolver with a service user (no end-user creds).
      3. Get a WorkflowSession from the ResourceResolver (via WorkflowService or adapt).
      4. Locate the WorkItem / WorkflowInstance by ID.
      5. Record the decision into workflow metadata or add a workflow comment (who, when, decision).
      6. Advance or complete the work item so the workflow continues down the correct transition (approve vs reject).
      7. Mark token used / remove it to prevent replay.
      8. Return a friendly confirmation page to the user.

    4 - Update workflow state reliably

    • Use the WorkflowSession API to modify workflow data or to complete the work item and select the correct outcome/transition so only the targeted work item moves forward.
    • Ensure the servlet handles idempotency (multiple clicks) and logs actions.

    5 - Security & best practices

    • Use strong tokens, HTTPS, short expiry, and store tokens server-side.
    • Perform authorization checks (ensure token matches workItem and intended user if applicable).
    • Avoid exposing internal IDs if possible—use mapped reference tokens.
    • Log actions and failures for audit.

    6 - Testing & QA

    • Test approve/reject flows, expired tokens, replay attempts, anonymous vs logged-in clicks, and error handling.
    • Validate that the exact workflow instance/work item gets updated and that downstream steps trigger correctly.

    3 replies

    Kamal_Kishor
    Community Advisor
    Community Advisor
    February 11, 2026

    @nsvsrk - If your workflow step approval/rejection is happeing outside of AEM, you can probably use “WorkflowExternalProcess”. Based on approval/rejection, your workflow can proceed further.

    https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/com/day/cq/workflow/exec/WorkflowExternalProcess.html#:~:text=public%20interface%20WorkflowExternalProcess,by%20execute()%20looks%20like.

    nsvsrkAuthor
    Level 8
    February 15, 2026

    Thanks ​@Kamal_Kishor.

     

    Kindly guide me through the step by step process of using “WorkflowExternalProcess”.

    Also lay stress on how the outside approval affects only the workflow instance in question.

    Appreciate your guidance.

     

    Thanks,

    RK.

    giuseppebaglio
    Level 10
    February 11, 2026

    hi ​@nsvsrk

    To get email approval results back into the specific AEM workflow work item, you can create a custom servlet that completes the work item via WorkflowSession.complete() when the user clicks the approval link.

    Here an example including the work item ID in the email URL: 
    https://author.example.com/etc/workflow/approve.html/content?wi=12345&action=approve
     

    Resource-based Servlet so you can leverage AEM permissions accordingly:

    @Component(service = Servlet.class, 
    property = {
    "sling.servlet.resourceTypes=workflow/approve",
    "sling.servlet.methods=GET"
    })
    public class ApprovalServlet extends SlingSafeMethodsServlet {

    @Reference
    private WorkflowService workflowService;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
    String wiId = request.getParameter("wi");
    String action = request.getParameter("action");

    ResourceResolver resolver = request.getResourceResolver();
    Session session = resolver.adaptTo(Session.class);
    WorkflowSession wfSession = workflowService.getSession(session);

    WorkItem workItem = wfSession.getWorkItem(Long.parseLong(wiId));
    List<WorkflowNode> routes = wfSession.getRoutes(workItem);

    // Route 0=Approve, 1=Reject
    WorkflowNode route = "approve".equals(action) ? routes.get(0) : routes.get(1);
    wfSession.complete(workItem, route);

    response.sendRedirect("/libs/cq/workflow/admin/console/content/instances.html");
    }
    }


    Before the participant step, add a Process Step that:

    1. Sends email with work item ID embedded in approval links
    2. Stores work item ID in workflow metadata for reference

    The servlet call advances the workflow as if approved via AEM Inbox, routing to the correct next step (Approve/Reject branch). https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/extending-aem/extending-workflows/workflows-program-interaction 

     

    nsvsrkAuthor
    Level 8
    February 15, 2026

    Thanks ​@giuseppebaglio .

     

    Kindly guide me through the step by step process of your approach.

    Also lay stress on how the outside approval affects only the workflow instance in question.

    Appreciate your guidance.

     

    Thanks,

    RK.

    Vishal_Anand
    Vishal_AnandAccepted solution
    Level 5
    February 16, 2026

    @nsvsrk You can perform below steps:
     

    1 - Add an approval step to the workflow

    • Use a Participant or Process step that pauses the workflow and triggers sending an email.
    • Persist the current work item id (or workflow instance id) and a short-lived secure token in JCR (/var/workflow-approvals/<token>) or in the workflow metadata so the link can be validated later.

    2 - Build email with secure links

    • Include two links (approve / reject) pointing to a Sling servlet endpoint, e.g.:
    • Do not include PII. Use IDs and tokens only.

    3 - Create a secure servlet to handle clicks

    • Implement a Sling servlet (GET or POST) at /bin/wf-approval.
    • Steps inside servlet:
      1. Validate token and ensure it maps to the expected workItemId and is not expired.
      2. Obtain a ResourceResolver with a service user (no end-user creds).
      3. Get a WorkflowSession from the ResourceResolver (via WorkflowService or adapt).
      4. Locate the WorkItem / WorkflowInstance by ID.
      5. Record the decision into workflow metadata or add a workflow comment (who, when, decision).
      6. Advance or complete the work item so the workflow continues down the correct transition (approve vs reject).
      7. Mark token used / remove it to prevent replay.
      8. Return a friendly confirmation page to the user.

    4 - Update workflow state reliably

    • Use the WorkflowSession API to modify workflow data or to complete the work item and select the correct outcome/transition so only the targeted work item moves forward.
    • Ensure the servlet handles idempotency (multiple clicks) and logs actions.

    5 - Security & best practices

    • Use strong tokens, HTTPS, short expiry, and store tokens server-side.
    • Perform authorization checks (ensure token matches workItem and intended user if applicable).
    • Avoid exposing internal IDs if possible—use mapped reference tokens.
    • Log actions and failures for audit.

    6 - Testing & QA

    • Test approve/reject flows, expired tokens, replay attempts, anonymous vs logged-in clicks, and error handling.
    • Validate that the exact workflow instance/work item gets updated and that downstream steps trigger correctly.