# Outlook

To use the **Outlook Node** in StackAI, simply add it to your workflow and configure the desired action. Connect it to other nodes to dynamically generate email content, recipients, or attachments. You can use this node to send emails, search your mailbox, or automate other Outlook-related tasks.

## Connecting to Outlook

There are two types of connections you can set up for Outlook:

### OAuth2 Connection

To set up an OAuth2 connection, log in to your Microsoft account through StackAI. Your connection will inherit your permissions and access.

### App Registration Connection

Follow the set up instructions [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) to create an app registration in Microsoft.

#### Phase 1: Azure Portal (Entra ID) Setup

If using an **App Registration** connection (not OAuth), your Azure AD application requires these **Application** permissions for Microsoft Graph:

* `Mail.Send` - Send emails as any user
* `Mail.Read` - Read you emails (for the Search Emails Action)
* `Mail.ReadBasic.All` (for On Email Received trigger)
* `Mail.ReadWrite` - Create drafts, add attachments, modify messages, reply/forward
* `MailboxSettings.Read` - Get list of email categories (for Set Email Category Action)
* `Calendars.ReadWrite` - Read your calendar and create calendar events (for Create Event and Get Events Actions)
* `User.Read.All` - Read users profiles (Optional)

Important: After adding these permissions in Azure Portal, click "Grant admin consent" for your tenant.

By default, the steps above will grant the app access to all mailboxes. To restrict access only to specific mailboxes, additionally do the following:

#### Phase 2: Microsoft 365 Admin Setup

*Goal: Create the mailbox and the security boundary.*

1. **Create the Shared Mailbox**:
   * Go to **Microsoft 365 Admin Center** > **Teams & groups** > **Shared mailboxes**.
   * Click **Add a shared mailbox** (e.g., `yourmailbox@yourdomain.com`).
   * *Note: Ensure it is a "Shared Mailbox" and not just a "Group".*
2. **Create a Mail-Enabled Security Group**:
   * Go to **Active teams & groups** > **Mail-enabled security**.
   * Click **Add a group**. Name it `StackAI-Authorized-Mailboxes`.
   * Give it an email address (e.g., `stackai-access@yourdomain.com`). This is a different email than your shared mailbox and corresponds just to the security group.
3. **Add the Mailbox to the Group**:
   * Open the new Security Group, go to **Members**, and add the Shared Mailbox email (`yourmailbox@...`) as a member.

#### Phase 3: Exchange Online (PowerShell) Setup

The following steps must be done in Microsoft Powershell by an administrator.

*Goal: Restrict the app so it can ONLY see the mailboxes in your group (Security Step).*

1. **Connect to Exchange**:

   ```powershell
   Connect-ExchangeOnline
   ```
2. **Create the Access Policy**: *Replace the AppId with your Azure Client ID and the PolicyScopeGroupId with your **Security Group** email. Ensure you use the security group email and **not** the email of your shared mailbox.*

   ```powershell
   New-ApplicationAccessPolicy -AppId "YOUR_CLIENT_ID" `
       -PolicyScopeGroupId "stackai-access@yourdomain.com" `
       -AccessRight RestrictAccess `
       -Description "Allow Stack AI to access authorized mailboxes only."
   ```
3. **Verify the Policy**: *Wait 15 minutes, then test if the shared mailbox is "visible" to the app.*

   ```powershell
   Test-ApplicationAccessPolicy -Identity "yourmailbox@yourdomain.com" -AppId "YOUR_CLIENT_ID"
   ```

   *It must return `AccessCheckResult: Granted`.*

#### Phase 3: Stack AI Connection

*Goal: Link the credentials to your workflow.*

1. **Create Connection**:
   * In Stack AI, create a new **Outlook (App Registration)** connection.
   * Enter your `Client ID`, `Client Secret`, and `Tenant ID`.
   * **User Principal Name**: Enter the exact email of the Shared Mailbox (`yourmailbox@...`).
2. **Create the Trigger**:
   * Add the **On Email Received** trigger to your workflow.
   * Select the connection you just created.
   * **Folder**: Type `Inbox` (case-sensitive) or select it from the dropdown.

***

#### ⚠️ Troubleshooting Tips for the Manual:

* **The 403 "Forbidden" Error**: This usually means the PowerShell policy hasn't synced yet. It can take **30-60 minutes** for Exchange to tell the Graph API about the new policy.
* **The 404 "Not Found" Error**: This means the `User Principal Name` in Stack AI doesn't match the `userPrincipalName` in Azure AD. Use the PowerShell command `Get-User -Identity "email"` to find the exact UPN.

***

### **Available Actions**

Below are the most commonly used Outlook actions in StackAI:

### 1. Send Email

#### Description

Send an email, reply to an existing message, or forward a message using your Outlook account. Supports drafts, attachments, and recipient filtering.

### Inputs

#### **recipient** (Optional)

* **Type:** String (comma-separated email addresses)
* **Description:** Recipient email address(es). If replying to a message (`message_id` provided), leave blank to reply to the original sender. If forwarding, specify new recipient(s).
* **Examples:**
  * `"recipient": "team@example.com"`
  * `"recipient": "user1@example.com, user2@example.com"`

#### **subject** (Optional)

* **Type:** String
* **Description:** Subject line of the email. If replying to a message (`message_id` provided), leave blank to use the original subject.
* **Example:** `"subject": "Weekly Report"`

#### **body** (Required)

* **Type:** String
* **Description:** Content/body of the email. Supports plain text or HTML.
* **Example:** `"body": "Please find the attached weekly report."`

#### **attachment\_urls** (Optional)

* **Type:** String (comma-separated URLs)
* **Description:** URLs of files to attach to the email. Files will be downloaded and attached.
* **Example:** `"attachment_urls": "https://example.com/file1.pdf, https://example.com/file2.xlsx"`

#### **message\_id** (Optional)

* **Type:** String
* **Description:** Microsoft Graph message ID to reply to or forward. When provided:
  * Without `recipient`: Creates a reply to the original sender
  * With `recipient`: Forwards the message to new recipient(s)
* **Example:** `"message_id": "AQMkAGY1MTc5Y2Y5LTNlMWMtNGU4NS05NzljLTRmM2IwOGNlYjI3MgBGAAAD..."`

#### **draft** (Optional)

* **Type:** Boolean
* **Description:** If `true`, saves the email as a draft instead of sending it immediately.
* **Default:** `false`
* **Example:** `"draft": true`

#### **allowed\_emails** (Optional)

* **Type:** String (comma-separated email addresses)
* **Description:** Whitelist of allowed recipient email addresses. If specified, emails will only be sent to addresses in this list. Leave blank to allow all recipients.
* **Example:** `"allowed_emails": "approved1@example.com, approved2@example.com"`

### Outputs

#### **result\_msg** (Always returned)

* **Type:** String
* **Description:** Summary of the email operation, including recipients, subject, body, and any errors or warnings.
* **Example:**

  ```json
  {
    "result_msg": "Recipient: team@example.com\nSubject: Weekly Report\nBody: Please find the attached report."
  }
  ```

***

#### Notes

* **New Emails:** `recipient` and `subject` are required when not replying/forwarding
* **Replies:** When `message_id` is provided without `recipient`, the action replies to the original sender
* **Forwards:** When `message_id` is provided with `recipient`, the action forwards to new recipients
* **Attachments:** Files are downloaded from provided URLs and attached to the message
* **Drafts:** When `draft=true`, the message is saved but not sent
* **Allowed Emails:** Use to restrict recipients to a whitelist; blocked recipients are reported in the result message

***

### 2. Search Emails

#### **Description:**

Search your Outlook mailbox for emails matching specific criteria.

#### **Inputs:**

* **query** (Required): The search query string (e.g., keywords, sender, date).
  * Example: `"query": "from:boss@example.com subject:invoice"`
* **folder** (Optional): Specify the folder to search in (e.g., Inbox, Sent).
  * Example: `"folder": "Inbox"`
* **max\_results** (Optional): Limit the number of results.
  * Example: `"max_results": 10`

**Configurations:**

* **connection\_id** (Required if you have multiple Outlook accounts): Specify the Outlook connection to use.

#### **Outputs:**

* **emails** (Always returned): List of matching emails with details such as subject, sender, date, and body.
  * Example:

    ```json
    {
      "emails": [
        {
          "subject": "Invoice Due",
          "from": "boss@example.com",
          "date": "2025-07-01",
          "body": "Please see the attached invoice."
        }
      ]
    }
    ```

***

#### **Best Practices**

* Always ensure required fields are filled to avoid errors.
* For attachments, connect a Files node or other relevant node to provide file paths.

***

Automate your Outlook email workflows in StackAI to save time, reduce manual effort, and ensure consistent communication.
