Quickstart #5: Notification Ambient Agent

View as Markdown

What You’ll Build

You’ll create an Ambient Agent that receives a webhook (e.g., from HR system), finds the right user by email, generates a smart notification, and sends it directly in chat.

The plugin you will build solves a common, practical problem: notifying users about specific updates or action items.

Before starting to build, we always recommend that you first map out the desired end user experience and the overall building blocks of an Ambient Agent.

Here is an example of the end-user experience we hope to enable:

Learning Objectives

  1. Build a Listener to receive webhooks
  2. Create a Compound Action to process payload → message
  3. Wire everything in a Plugin
  4. Test your webhooks using our Purple Suite tool.

Architecture Overview

To get to this experience, the Ambient Agent will consist of one Compound Action and two input arguments: the user’s email and the payload of the webhook.

Let’s get started!

Plan Your Data Flow

Let’s map the data journey to understand how the data travels from the external systems to the user’s chat.

1. Expected sample payload from external system

1{ "email": "jane@company.com", "data": { "title": "PTO Expiring", ... } }

2. Listener -> parsed_body

When the Listener receives the request:

StepWhat HappensResult
1Listener validates the payload-
2The entire payload is automatically parsedvariable parsed_body (object)
3parsed_body becomes available inside the Plugin-
1// The plugin will have access to the following:
2{
3 "parsed_body": {
4 "email": "jane@company.com",
5 "data": { "title": "PTO Expiring", "val": "..." }
6 },
7 "raw_body": "...",
8 "headers": {},
9 "query_params": {},
10}

3. Plugin Input Mapping → Compound Action Arguments

In the Plugin editor you map fields from parsed_body to the input arguments of your Compound Action:

1user_email: parsed_body.email
2payload: parsed_body.data

4. Compound Action runs the logic

Your Compound Action receives:

data.user_email → string (e.g. "jane.doe@company.com")
data.payload → object (the whole `data` block)

It then:

  1. mw.get_user_by_email → resolves to a user ID
  2. mw.generate_text_action → turns payload into a polished message
  3. notify → sends the message to that user ID

Now you know exactly where every piece of data lives.

Phase 1: Create Your Compound Action

You will now create a compound action to handle the incoming webhook routed by the listener.

In this phase you will build a compound action with 1) user_email and payload input arguments, and 2) two actions to resolve the user by email and then notify them with the message. Here’s a reminder of the bird’s-eye view for our Compound Action

1

Create a new Compound Action

Navigate to a new “Compound Action” in the left nav and then click “Create”.

2

Set the title and description

Set the following title and description for your Compound Action (be sure to replace “first” and “last” with your corresponding information).

FieldValue
Titlequickstart_first_last_message_notification_ca
DescriptionSends a message to a user
3

Copy the Compound Action expression

Copy the following expression into the Compound Action Editor

1steps:
2 - action:
3 output_key: target_user
4 action_name: mw.get_user_by_email
5 input_args:
6 user_email: data.user_email
7 - action:
8 output_key: generate_text_action_result
9 action_name: mw.generate_text_action
10 progress_updates:
11 on_complete: ON_COMPLETE_MESSAGE
12 on_pending: ON_PENDING_MESSAGE
13 input_args:
14 system_prompt: '''Based on the provided user message, provide an actionable alert and formatted message for the user'''
15 user_input:
16 RENDER():
17 template: "{{webhook_data}}"
18 args:
19 webhook_data: $STRINGIFY_JSON(data.payload)
20 - notify:
21 output_key: notification_output
22 recipient_id: data.target_user.user.id
23 message: data.generate_text_action_result.generated_output

Understanding the Compound Action

This Compound Action executes three actions in sequence, with the output of one step feeding into the next:

  1. mw.get_user_by_email (Built-in Action)
    1. Purpose: To identify the notification recipient.
    2. Process: It takes a user’s email address (from the webhook) as its input and retrieves that user’s unique Moveworks profile ID.
  2. mw.generate_text_action (Built-in Action)
    1. Purpose: To create a polished message for the user.
    2. Process: This action uses an LLM to interpret the raw data in the webhook payload and generate a structured, readable message.
  3. notify (Compound Action Expression)
    1. Purpose: To send the final notification.
    2. Process: This action takes two inputs from the previous steps:
      1. Recipient ID: It uses the user ID that was retrieved by the mw.get_user_by_email action.
      2. Message: It uses the formatted text that was generated by the mw.generate_text_action action.
4

Define input arguments

Define two formal input arguments to represent the user_email and payload inputs that this Compound Action Requires

  1. Click on the “Input Args” button near the top right corner

  2. Click “Create New” in the “Input Arguments” pop up.

  3. Fill out the following details for your user_email argument:

    Field labelValue to enter/select
    Argument Nameuser_email
    Data TypeSelect “string”
    Example ValueLeave this field empty
    DescriptionThe email of the user that will be notified
    RequiredCheck the box
  4. Hit “Save”

  5. Click “Create New” again to the “Input Arguments” pop up.

  6. Fill out the following details for your payload argument:

    Field labelValue to enter/select
    Argument Namepayload
    Data TypeSelect “object”
    Example ValueLeave this field empty
    DescriptionThe payload of the webhook sent from an external system
    RequiredCheck the box

    Known Issue: The Example Value field is optional but currently if left empty, you may see a red validation message (“Must be a valid object”) and a warning icon next to the argument name after saving. This is a known issue (currently expected behavior) and will not block publishing — you can safely ignore it.

  7. Hit “Save” and hit the “X” icon to close this “Input Arguments” pop up.

5

Publish

Click “Publish”

All done with Actions!

You’re ready to move on — time to create your Listener to start listening to webhooks.

Phase 2: Set Up Your Webhook Listener

1

Create a new Listener

Navigate to a new Listener. Click “Create”.

2

Set the title and description

Set the following Title and Description for your listener (be sure to replace firstand lastn with your corresponding information).

FieldValue to enter (replace “first” & “last” with your info)
Titlequickstart_first_last_notification_listener
DescriptionListens for simple notifications
3

Copy the webhook URL

Click “Copy URL” and paste the webhook URL somewhere you can get back to it quick, we will need it in future steps.

4

Publish your listener

Click “Publish” to save your listener. When prompted with a confirmation message about security, click “Publish anyway” to proceed.

Note: Unsecured listeners are intended for testing only. For production environments, always enable signature verification to secure your webhook listener.

Phase 3: Configure and Launch Your Plugin

This section guides you through adding your Listener and Compound Action to a Plugin. A key step will be configuring the data flow, where you’ll specify exactly which fields from the webhook you want to forward to your action.

1

Create a new Plugin

Navigate to a new Plugin (navigate to the library and click “Create”).

2

Set the title and description

Set the following title and description for your Plugin (be sure to replace “first” and “last” with your corresponding information).

FieldValue to enter
Titlequickstart_first_last_message_notification
DescriptionSends a message to a user based on a webhook with an email and payload.
3

Configure the trigger and body

In the “Workflow Overview” section click “System” in the Trigger box.

  1. Configure your system trigger to connect your Listener in the slide-out pop up with:

    Field LabelValue to enter/select
    Select Trigger TypeWebhook
    Select Listenerquickstart_first_last_notification_listener (Select yours)
    Event FilterLeave this field empty
  2. Click on the “Body” in the “Workflow Overview

  3. Configure your system body to connect your compound action to the plugin

    Field label

    Value to enter/select

    Select Type

    System body

    Select an Action

    quickstart_first_last_message_notification_ca (Select yours)

    Input mapping

    user_email: parsed_body.email

    payload: parsed_body.data

    Understanding the Input Mapping

    When the listener receives a webhook, we expect a JSON payload structured like this:

    1{
    2 "createdAt": "2025-09-02T18:10:28Z",
    3 "data": {
    4 "actions": [
    5 {
    6 "text": "View PTO Policy",
    7 "url": "https://internal-hr.example.com/policies/pto-2025"
    8 }
    9 ],
    10 "alert_code": "PTO-EXP-WARN-90",
    11 "details": {
    12 "accrual_policy": "use-it-or-lose-it",
    13 "current_balance_hours": 112.5,
    14 "hours_at_risk": 72.5,
    15 "policy_id": "pol_hr_pto_standard_2025"
    16 },
    17 "last_date": "Tue Sep 09 2025",
    18 "message": "This is a friendly reminder that you have accrued paid time off that is set to expire. To ensure you don't lose these hours, please schedule and take your vacation time.",
    19 "object": "alert",
    20 "priority": "medium",
    21 "title": "Action Required: Use Your PTO Balance Before Year-End"
    22 },
    23 "email": "user@example.com",
    24 "eventId": "evt_alert_2b3c4d5e6f7G8h9I0jK",
    25 "eventType": "alert.pto_expiration_warning"
    26}

    The listener automatically parses this JSON payload into a parsed_body object. To access the data you need, you simply use dot notation to reference the keys:

    • parsed_body.email
    • parsed_body.data

    This method gives you the flexibility to extract only the specific data your compound action requires, even if the webhook sends a much larger payload.

    Note: While this mapping is currently a manual process, we are developing an “Auto Configure” feature to streamline this setup in the future.

4

Publish your Plugin

Click “Publish” to launch your Plugin.

And just like that — you've finished building your Plugin, and now it's ready to use!

Congrats! You are now ready to test your plugin. In the next section, you will provided with required tools to help you test it.

Phase 4: Testing

This section guides you through the Moveworks Purple API tool to help you test your plugin by sending webhooks to your listener.

1

Open the Purple API Tool

Go the Moveworks Purple API Tool

2

Create a new Session ID

Click “Create New Session ID”

3

Open the Webhooks tab

Click on the “Webhooks” Tab

4

Configure the webhook fields

Configure the field values with your listener information

FieldValue to enter
Webhook URLEnter the Webhook URL you created in Phase 2
API KeyLeave empty
5

Generate the webhook payload

Select the “Simple Notification” tab and click on “Generate Webhook Payload”

  1. A payload will be generated for your upcoming webhook

    1{
    2 "createdAt": "2025-09-02T18:10:28Z",
    3 "data": {
    4 "actions": [
    5 {
    6 "text": "View PTO Policy",
    7 "url": "https://internal-hr.example.com/policies/pto-2025"
    8 }
    9 ],
    10 "alert_code": "PTO-EXP-WARN-90",
    11 "details": {
    12 "accrual_policy": "use-it-or-lose-it",
    13 "current_balance_hours": 112.5,
    14 "hours_at_risk": 72.5,
    15 "policy_id": "pol_hr_pto_standard_2025"
    16 },
    17 "last_date": "Tue Sep 09 2025",
    18 "message": "This is a friendly reminder that you have accrued paid time off that is set to expire. To ensure you don't lose these hours, please schedule and take your vacation time.",
    19 "object": "alert",
    20 "priority": "medium",
    21 "title": "Action Required: Use Your PTO Balance Before Year-End"
    22 },
    23 "email": "user@example.com",
    24 "eventId": "evt_alert_2b3c4d5e6f7G8h9I0jK",
    25 "eventType": "alert.pto_expiration_warning",
    26 "sessionId": "C7KOA5KoumkgsTiXDHa4" // This sessionId will be based on your session
    27}
  2. Change the data and email fields to the corresponding values you would want.

6

Trigger the webhook

Click on Trigger Webhook

Success! Check Your Notifications

Excellent work! You have successfully tested your plugin. Check your chat, where you should now see a notification from the AI Assistant containing the message from your webhook payload.

Reflecting on this Plugin

The plugin you just created uses several key Agent Studio concepts, from Webhook Listeners to Compound Actions. You’ve successfully built a plugin that:

  • Listens for webhooks from other apps.
  • Grabs only the specific data it needs from the webhook payload.
  • Processes that data to find the right user and send them a direct message.

Awesome work sticking with it! Your plugin is now ready to notify users of important messages and updates.