MS Outlook – Messages – Forward Message
MS Outlook – Messages – Forward Message
Forward an Outlook message. Uses the selected mailbox and returns the available result.
Forwards and sends immediately. Supply at least one valid recipient address in To Recipients CSV. Although the Apex input is marked optional and not validated locally, Microsoft requires recipients. The action sends comment and toRecipients when populated; it does not create a draft or return a sent-message ID.
Action details
| Property | Value |
|---|---|
| Action label | MS Outlook – Messages – Forward Message |
| Category | CloudTools |
| Apex class and method | ForwardMSOutlookMessage.forwardMessage |
| Input type | ForwardMSOutlookMessage.ForwardMSOutlookMessageInput |
| Output type | List<ForwardMSOutlookMessageOutput> |
| Authorization | OAuth Delegated (Authorization Code) or OAuth Application (Client Credentials). |
| Flow automation | Use an application connector configured as the Flow default. |
| Microsoft Graph operation | POST /v1.0/me/messages/{messageId}/forward for Authorization Code Flow; otherwise POST /v1.0/users/{userIdOrPrincipalName}/messages/{messageId}/forward. |
Prerequisites and permissions
Configure a CloudTools Connector with Connector Type set to Microsoft 365. Complete Microsoft sign-in for delegated access. For application access, grant application permissions and administrator consent, supply the target mailbox user ID or principal name, and ensure the app can access that mailbox.
Microsoft requires Mail.Send for delegated and application access. See the Microsoft operation and permissions reference.
Mailbox selection: Authorization Code Flow uses /me and ignores userIdOrPrincipalName. Supplying another user does not redirect that call. Other authorization types use /users/{userIdOrPrincipalName}; their authentication must be valid for Microsoft Graph. Use Graph resource IDs rather than Salesforce record IDs.
Inputs
The table lists action labels, Apex field names, and data types. Provide one non-null request per invocation. Required text must not be blank.
| Input | Apex field | Type | Required | Description |
|---|---|---|---|---|
| User Id or Principal Name | userIdOrPrincipalName | String | Unless Authorization Code Flow is enabled | User id or user principal name. Required for application authorization; ignored for Authorization Code Flow. |
| Message Id | messageId | String | Yes | Message identifier. |
| Comment | comment | String | No | Forward comment. |
| To Recipients CSV | toRecipientsCsv | String | No | Comma-separated recipient addresses. Separate plain email addresses with commas. CloudTools trims whitespace and skips empty entries; it does not parse display-name address syntax. |
The invocable input has no connectorId field. Apex and Flow use CloudTools connector selection; the LWC controller accepts an additional connectorId property to select a record. This action does not resolve replacement tokens in its inputs; resolve dynamic values first. See Using Token Replacements.
Outputs
Returns a list containing one ForwardMSOutlookMessage.ForwardMSOutlookMessageOutput after the call completes without an exception. The result is constructed by CloudTools, not a Microsoft resource.
| Output | Apex field | Type | Description |
|---|---|---|---|
| Success | success | Boolean | Whether operation succeeded. |
| Message | message | String | Operation message. |
Failures raise exceptions rather than returning success=false as a normal failure result. Microsoft accepts the send request asynchronously; success means the call completed, not confirmed mail delivery.
Use in Flow
Add MS Outlook – Messages – Forward Message in Flow Builder. Configure a Microsoft 365 application connector as the default for Flow automations, then populate the inputs above. Delegated connectors are not supported for CloudTools Flow automation. Add a fault path for callout errors. This implementation processes only the first input request; it is not a bulk action.
Use in custom Apex
This subscriber-org example uses the Apptigent namespace. Replace placeholders before use. Run in a context that permits callouts with a configured application connector. For an already-authorized delegated connector, omit the user value.
Apptigent.ForwardMSOutlookMessage.ForwardMSOutlookMessageInput request =
new Apptigent.ForwardMSOutlookMessage.ForwardMSOutlookMessageInput();
request.userIdOrPrincipalName = 'REPLACE_WITH_MICROSOFT_USER_ID_OR_UPN';
request.messageId = 'REPLACE_WITH_MESSAGE_ID';
request.comment = 'Thank you for the update.';
request.toRecipientsCsv = 'recipient@example.com';
List<Apptigent.ForwardMSOutlookMessage.ForwardMSOutlookMessageOutput> results =
Apptigent.ForwardMSOutlookMessage.forwardMessage(
new List<Apptigent.ForwardMSOutlookMessage.ForwardMSOutlookMessageInput>{ request }
);
Boolean succeeded = !results.isEmpty() && results[0].success;
System.debug(succeeded);
Submit one request per invocation. The example does not implement connector setup, delegated sign-in, or exception handling; those belong in the calling application.
Use in a Lightning Web Component
Use forwardMSOutlookMessage from msOutlookConnectorLib, through MSOutlookConnectorController. This example uses repository c/ imports for a component in the same namespace. Replace placeholders and complete connector authorization before invoking it.
outlookActionExample.js
import { LightningElement } from 'lwc';
import { forwardMSOutlookMessage, MSOutlookObjects } from 'c/msOutlookConnectorLib';
export default class OutlookActionExample extends LightningElement {
connectorId = 'REPLACE_WITH_CONNECTOR_RECORD_ID';
result = null;
errorMessage = '';
isRunning = false;
completed = false;
async handleRun() {
if (this.isRunning || this.completed) {
return;
}
this.isRunning = true;
this.errorMessage = '';
try {
const request = MSOutlookObjects.inputs.message();
request.connectorId = this.connectorId;
request.userIdOrPrincipalName = 'REPLACE_WITH_MICROSOFT_USER_ID_OR_UPN';
request.messageId = 'REPLACE_WITH_MESSAGE_ID';
request.comment = 'Thank you for the update.';
request.toRecipientsCsv = 'recipient@example.com';
const result = await forwardMSOutlookMessage(request);
if (!result?.success) {
throw new Error('No successful operation result was returned.');
}
this.result = result;
this.completed = true;
} catch (error) {
this.errorMessage = error.requiresInteractiveAuthorization
? 'Sign in to Microsoft for this connector, then try again.'
: error.message || 'The Outlook action failed.';
} finally {
this.isRunning = false;
}
}
}
outlookActionExample.html
<template>
<lightning-button label="Run action" onclick={handleRun}
disabled={isRunning}></lightning-button>
<p role="alert">{errorMessage}</p>
</template>
The library accepts one request object and resolves to one operation result; read result.success and result.message directly. The shared factory includes inputs for other actions; only the fields in this page and optional connectorId are used here.
The controller also exposes rawJson as a serialization of the mapped Apex result; it is not an original Microsoft response or an invocable Flow output.
This example reports authorization errors but does not implement sign-in. For delegated access, use getMSOutlookAuthorizationState, beginMSOutlookAuthorization, and createMSOutlookOAuthMessageHandler. Errors expose message and requiresInteractiveAuthorization.
The example prevents another invocation after success. Reset completed only when deliberately starting a new operation. If an error leaves the outcome uncertain, verify mailbox state before retrying; repeating the action can create duplicate mail, attachments, or folders, or act on an item that has already moved or been deleted.
Error handling and troubleshooting
| Symptom | What to check |
|---|---|
| Required fields error | Pass a nonempty list with a non-null first request. Populate required resource fields and User Id or Principal Name for application authorization. |
| Authorization is required | Complete or renew the current user’s delegated Microsoft authorization for the selected connector. |
| Access denied | Check the operation permission, consent, connector identity, and mailbox access. |
| Resource not found | Verify IDs belong to the selected mailbox and refer to the expected resource. Authorization Code Flow ignores the user input. |
| Operation rejected | Review the Microsoft error and confirm the resource supports this operation. |
| Unexpected result | Check for an empty Apex result, a null JavaScript response, omitted properties, or incomplete pagination. Handle exceptions in the caller. |