diff --git a/LICENSE b/LICENSE index 6af04d8..48fc581 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2017-2022 Splunk Inc. + Copyright (c) 2017-2023 Splunk Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/NOTICE b/NOTICE index 52bcf7f..b2f2217 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Splunk SOAR MS Graph for Office 365 -Copyright (c) 2017-2022 Splunk Inc. +Copyright (c) 2017-2023 Splunk Inc. Third-party Software Attributions: diff --git a/README.md b/README.md index 03dcd10..b2cb52f 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ # MS Graph for Office 365 Publisher: Splunk -Connector Version: 2\.7\.1 +Connector Version: 2.8.0 Product Vendor: Microsoft -Product Name: Office 365 \(MS Graph\) -Product Version Supported (regex): "\.\*" -Minimum Product Version: 5\.3\.0 +Product Name: Office 365 (MS Graph) +Product Version Supported (regex): ".\*" +Minimum Product Version: 6.0.0 This app connects to Office 365 using the MS Graph API to support investigate and generic actions related to the email messages and calendar events [comment]: # " File: README.md" -[comment]: # " Copyright (c) 2017-2022 Splunk Inc." +[comment]: # " Copyright (c) 2017-2023 Splunk Inc." [comment]: # "" [comment]: # "Licensed under the Apache License, Version 2.0 (the 'License');" [comment]: # "you may not use this file except in compliance with the License." @@ -27,7 +27,7 @@ This app connects to Office 365 using the MS Graph API to support investigate an ## Playbook Backward Compatibility - The 'id' field of email artifact has been renamed to 'messageId'. Hence, it is requested to the - end-user to please update their existing playbooks by re-inserting \| modifying \| deleting the + end-user to please update their existing playbooks by re-inserting | modifying | deleting the corresponding action blocks to ensure the correct functioning of the playbooks created on the earlier versions of the app. @@ -68,6 +68,9 @@ Once the app is created, follow the below-mentioned steps: - For non-admin access, use User.Read (Delegated permission) instead (https://graph.microsoft.com/User.Read) + - Mail.Send (https://graph.microsoft.com/Mail.Send) - It is required only if you want to run + the **send email** action. + - Group.Read.All (https://graph.microsoft.com/Group.Read.All) - It is required only if you want to run the **list events** action for the group's calendar and for the **list groups** and the **list group members** action. @@ -79,7 +82,7 @@ Once the app is created, follow the below-mentioned steps: if you want to run the **delete event** action from the user's calendar. - MailboxSettings.Read (https://graph.microsoft.com/MailboxSettings.Read) - It is required - only if you want to run the **oof status** action. + only if you want to run the **oof status** , **list rules** and **get rule** actions. After making these changes, click **Add permissions** , then select **Grant admin consent for \** at the bottom of the screen. @@ -195,6 +198,8 @@ The app should now be ready to be used. This will only ingest the first level 'item attachment' as an EML file. The nested item attachments will not be ingested into the vault. If the extract_attachments flag is set to false, then the application will also skip the EML file ingestion regardless of this flag value. +- extract_eml - When polling is on and extract_eml is enabled, it will add the eml files of the + root email in the vault. If extract_attachments is set to true, only fileAttachment will be ingested. If both ingest_eml and extract_attachments are set to true, then both fileAttachment and itemAttachment will be ingested. @@ -223,8 +228,7 @@ Please check the permissions for the state file as mentioned below. #### State file path -- For Non-NRI instance: /opt/phantom/local_data/app_states/\/\\_state.json -- For NRI instance: +- For unprivileged instance: /\/local_data/app_states/\/\\_state.json #### State file permissions @@ -265,6 +269,17 @@ Please check the permissions for the state file as mentioned below. +## Increase the maximum limit for ingestion + +The steps are as follows: + +1. Open the **/opt/phantom/usr/nginx/conf/conf.d/phantom-nginx-server.conf** file on the SOAR + instance. +2. Change that value of the **client_max_body_size** variable as per your needs. +3. Save the configuration file. +4. Reload nginx service using **service nginx reload** or try restarting the nginx server from SOAR + platform: Go to **Administrator->System Health-> System Health** then restart the nginx server. + ## Port Details The app uses HTTP/ HTTPS protocol for communicating with the Office365 server. Below are the default @@ -277,38 +292,41 @@ ports used by the Splunk SOAR Connector. ### Configuration Variables -The below configuration variables are required for this Connector to operate. These variables are specified when configuring a Office 365 \(MS Graph\) asset in SOAR. +The below configuration variables are required for this Connector to operate. These variables are specified when configuring a Office 365 (MS Graph) asset in SOAR. VARIABLE | REQUIRED | TYPE | DESCRIPTION -------- | -------- | ---- | ----------- -**tenant** | required | string | Tenant ID \(e\.g\. 1e309abf\-db6c\-XXXX\-a1d2\-XXXXXXXXXXXX\) -**client\_id** | required | string | Application ID -**client\_secret** | required | password | Application Secret -**admin\_access** | optional | boolean | Admin Access Required -**admin\_consent** | optional | boolean | Admin Consent Already Provided -**scope** | optional | string | Access Scope \(for use with non\-admin access; space\-separated\) -**ph\_2** | optional | ph | -**email\_address** | optional | string | Email Address of the User \(On Poll\) -**folder** | optional | string | Mailbox folder name/folder path or the internal office365 folder ID to ingest \(On Poll\) -**get\_folder\_id** | optional | boolean | Retrieve the folder ID for the provided folder name/folder path automatically and replace the folder parameter value \(On Poll\) -**ph\_3** | optional | ph | -**first\_run\_max\_emails** | optional | numeric | Maximum Containers for scheduled polling first time -**max\_containers** | optional | numeric | Maximum Containers for scheduled polling -**extract\_attachments** | optional | boolean | Extract Attachments -**extract\_urls** | optional | boolean | Extract URLs -**extract\_ips** | optional | boolean | Extract IPs -**extract\_domains** | optional | boolean | Extract Domain Names -**extract\_hashes** | optional | boolean | Extract Hashes -**ingest\_eml** | optional | boolean | Ingest EML file for the itemAttachment -**ingest\_manner** | optional | string | How to Ingest \(during ingestion, should the app get the latest emails or the oldest\) -**retry\_count** | optional | numeric | Maximum attempts to retry the API call \(Default\: 3\) -**retry\_wait\_time** | optional | numeric | Delay in seconds between retries \(Default\: 60\) +**tenant** | required | string | Tenant ID (e.g. 1e309abf-db6c-XXXX-a1d2-XXXXXXXXXXXX) +**client_id** | required | string | Application ID +**client_secret** | required | password | Application Secret +**admin_access** | optional | boolean | Admin Access Required +**admin_consent** | optional | boolean | Admin Consent Already Provided +**scope** | optional | string | Access Scope (for use with non-admin access; space-separated) +**ph_2** | optional | ph | +**email_address** | optional | string | Email Address of the User (On Poll) +**folder** | optional | string | Mailbox folder name/folder path or the internal office365 folder ID to ingest (On Poll) +**get_folder_id** | optional | boolean | Retrieve the folder ID for the provided folder name/folder path automatically and replace the folder parameter value (On Poll) +**ph_3** | optional | ph | +**first_run_max_emails** | optional | numeric | Maximum Containers for scheduled polling first time +**max_containers** | optional | numeric | Maximum Containers for scheduled polling +**extract_attachments** | optional | boolean | Extract Attachments +**extract_urls** | optional | boolean | Extract URLs +**extract_ips** | optional | boolean | Extract IPs +**extract_domains** | optional | boolean | Extract Domain Names +**extract_hashes** | optional | boolean | Extract Hashes +**ingest_eml** | optional | boolean | Ingest EML file for the itemAttachment +**ingest_manner** | optional | string | How to Ingest (during ingestion, should the app get the latest emails or the oldest) +**retry_count** | optional | numeric | Maximum attempts to retry the API call (Default: 3) +**retry_wait_time** | optional | numeric | Delay in seconds between retries (Default: 60) +**extract_eml** | optional | boolean | Extract root (primary) email as Vault ### Supported Actions [test connectivity](#action-test-connectivity) - Use supplied credentials to generate a token with MS Graph [generate token](#action-generate-token) - Generate a token [oof check](#action-oof-check) - Get user's out of office status [list events](#action-list-events) - List events from user or group calendar +[get rule](#action-get-rule) - Get the properties and relationships of a messageRule object +[list rules](#action-list-rules) - Get all the messageRule objects defined for the user's inbox [list users](#action-list-users) - Retrieve a list of users [list groups](#action-list-groups) - List all the groups in an organization, including but not limited to Office 365 groups [list group members](#action-list-group-members) - List all the members in group @@ -318,10 +336,11 @@ VARIABLE | REQUIRED | TYPE | DESCRIPTION [delete email](#action-delete-email) - Delete an email [delete event](#action-delete-event) - Delete an event from user calendar [get email](#action-get-email) - Get an email from the server -[get email properties](#action-get-email-properties) - Get non\-standard email properties from the server +[get email properties](#action-get-email-properties) - Get non-standard email properties from the server [run query](#action-run-query) - Search emails [create folder](#action-create-folder) - Create a new folder [get folder id](#action-get-folder-id) - Get the API ID of the folder +[send email](#action-send-email) - Sends an email with optional text rendering. Attachments are allowed a Content-ID tag for reference within the html [on poll](#action-on-poll) - Ingest emails from Office 365 using Graph API ## action: 'test connectivity' @@ -346,14 +365,14 @@ Read only: **False** No parameters are required for this action #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.data | string | -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.data | string | | +action_result.summary | string | | +action_result.message | string | | Token generated +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'oof check' Get user's out of office status @@ -364,27 +383,27 @@ Read only: **True** #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**user\_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` +**user_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.user\_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.externalAudience | string | -action\_result\.data\.\*\.externalReplyMessage | string | -action\_result\.data\.\*\.internalReplyMessage | string | -action\_result\.data\.\*\.scheduledEndDateTime\.dateTime | string | -action\_result\.data\.\*\.scheduledEndDateTime\.timeZone | string | -action\_result\.data\.\*\.scheduledStartDateTime\.dateTime | string | -action\_result\.data\.\*\.scheduledStartDateTime\.timeZone | string | -action\_result\.data\.\*\.status | string | -action\_result\.summary\.events\_matched | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.user_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` | eeb3645f-df19-58a1-0e9c-ghi234cb5f6f +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#users('eeb3645f-df19-47a1-8e8c-fcd234cb5f6f')/mailboxSettings/automaticRepliesSetting +action_result.data.\*.@odata.etag | string | | +action_result.data.\*.externalAudience | string | | all +action_result.data.\*.externalReplyMessage | string | | +action_result.data.\*.internalReplyMessage | string | | +action_result.data.\*.scheduledEndDateTime.dateTime | string | | 2022-03-15T12:00:00.0000000 +action_result.data.\*.scheduledEndDateTime.timeZone | string | | UTC +action_result.data.\*.scheduledStartDateTime.dateTime | string | | 2022-03-14T12:00:00.0000000 +action_result.data.\*.scheduledStartDateTime.timeZone | string | | UTC +action_result.data.\*.status | string | | alwaysEnabled +action_result.summary.events_matched | numeric | | 1 +action_result.message | string | | Successfully retrieved out of office status +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'list events' List events from user or group calendar @@ -395,100 +414,169 @@ Read only: **True** #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**user\_id** | optional | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` -**group\_id** | optional | Group ID | string | `msgoffice365 group id` +**user_id** | optional | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` +**group_id** | optional | Group ID | string | `msgoffice365 group id` **filter** | optional | OData query to filter/search for specific results | string | **limit** | optional | Maximum number of events to return | numeric | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.filter | string | -action\_result\.parameter\.group\_id | string | `msgoffice365 group id` -action\_result\.parameter\.limit | numeric | -action\_result\.parameter\.user\_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.allowNewTimeProposals | boolean | -action\_result\.data\.\*\.attendee\_list | string | -action\_result\.data\.\*\.attendees\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.attendees\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.attendees\.\*\.status\.response | string | -action\_result\.data\.\*\.attendees\.\*\.status\.time | string | -action\_result\.data\.\*\.attendees\.\*\.type | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.bodyPreview | string | -action\_result\.data\.\*\.calendar\@odata\.associationLink | string | `url` -action\_result\.data\.\*\.calendar\@odata\.navigationLink | string | `url` -action\_result\.data\.\*\.categories\.\*\.name | string | -action\_result\.data\.\*\.changeKey | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.end\.dateTime | string | -action\_result\.data\.\*\.end\.timeZone | string | -action\_result\.data\.\*\.hasAttachments | boolean | -action\_result\.data\.\*\.hideAttendees | boolean | -action\_result\.data\.\*\.iCalUId | string | -action\_result\.data\.\*\.id | string | `msgoffice365 event id` -action\_result\.data\.\*\.importance | string | -action\_result\.data\.\*\.isAllDay | boolean | -action\_result\.data\.\*\.isCancelled | boolean | -action\_result\.data\.\*\.isDraft | boolean | -action\_result\.data\.\*\.isOnlineMeeting | boolean | -action\_result\.data\.\*\.isOrganizer | boolean | -action\_result\.data\.\*\.isReminderOn | boolean | -action\_result\.data\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.location\.address\.city | string | -action\_result\.data\.\*\.location\.address\.countryOrRegion | string | -action\_result\.data\.\*\.location\.address\.postalCode | string | -action\_result\.data\.\*\.location\.address\.state | string | -action\_result\.data\.\*\.location\.address\.street | string | -action\_result\.data\.\*\.location\.coordinates\.latitude | numeric | -action\_result\.data\.\*\.location\.coordinates\.longitude | numeric | -action\_result\.data\.\*\.location\.displayName | string | -action\_result\.data\.\*\.location\.locationType | string | -action\_result\.data\.\*\.location\.locationUri | string | `url` -action\_result\.data\.\*\.location\.uniqueId | string | -action\_result\.data\.\*\.location\.uniqueIdType | string | -action\_result\.data\.\*\.locations\.\*\.address\.city | string | -action\_result\.data\.\*\.locations\.\*\.address\.countryOrRegion | string | -action\_result\.data\.\*\.locations\.\*\.address\.postalCode | string | -action\_result\.data\.\*\.locations\.\*\.address\.state | string | -action\_result\.data\.\*\.locations\.\*\.address\.street | string | -action\_result\.data\.\*\.locations\.\*\.coordinates\.latitude | numeric | -action\_result\.data\.\*\.locations\.\*\.coordinates\.longitude | numeric | -action\_result\.data\.\*\.locations\.\*\.displayName | string | -action\_result\.data\.\*\.locations\.\*\.locationType | string | -action\_result\.data\.\*\.locations\.\*\.locationUri | string | `url` -action\_result\.data\.\*\.locations\.\*\.uniqueId | string | -action\_result\.data\.\*\.locations\.\*\.uniqueIdType | string | -action\_result\.data\.\*\.occurrenceId | string | -action\_result\.data\.\*\.onlineMeeting | string | -action\_result\.data\.\*\.onlineMeetingProvider | string | -action\_result\.data\.\*\.onlineMeetingUrl | string | `url` -action\_result\.data\.\*\.organizer\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.organizer\.emailAddress\.name | string | -action\_result\.data\.\*\.originalEndTimeZone | string | -action\_result\.data\.\*\.originalStartTimeZone | string | -action\_result\.data\.\*\.recurrence | string | -action\_result\.data\.\*\.reminderMinutesBeforeStart | numeric | -action\_result\.data\.\*\.responseRequested | boolean | -action\_result\.data\.\*\.responseStatus\.response | string | -action\_result\.data\.\*\.responseStatus\.time | string | -action\_result\.data\.\*\.sensitivity | string | -action\_result\.data\.\*\.seriesMasterId | string | -action\_result\.data\.\*\.showAs | string | -action\_result\.data\.\*\.start\.dateTime | string | -action\_result\.data\.\*\.start\.timeZone | string | -action\_result\.data\.\*\.subject | string | -action\_result\.data\.\*\.transactionId | string | -action\_result\.data\.\*\.type | string | -action\_result\.data\.\*\.webLink | string | `url` -action\_result\.data\.locations\.\*\.displayName | string | -action\_result\.summary\.events\_matched | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.filter | string | | $filter=subject eq 'Test2' +action_result.parameter.group_id | string | `msgoffice365 group id` | 3d9c58f8-9f38-4016-93ac-b61095f31c48 +action_result.parameter.limit | numeric | | 20 +action_result.parameter.user_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.data.\*.@odata.etag | string | | W/"b1MzKFCcdkuJ24Mc2VsdjwABAdhQhg==" +action_result.data.\*.allowNewTimeProposals | boolean | | True False +action_result.data.\*.attendee_list | string | | H-test, o365group +action_result.data.\*.attendees.\*.emailAddress.address | string | `email` | H-test@testdomain.abc.com +action_result.data.\*.attendees.\*.emailAddress.name | string | | H-test +action_result.data.\*.attendees.\*.status.response | string | | none +action_result.data.\*.attendees.\*.status.time | string | | 0001-01-01T00:00:00Z +action_result.data.\*.attendees.\*.type | string | | required +action_result.data.\*.body.content | string | | `\\r\\n\\r\\n\\r\\n\\r\\n
 
\\r\\n\\r\\n\\r\\n` +action_result.data.\*.body.contentType | string | | html +action_result.data.\*.bodyPreview | string | | +action_result.data.\*.calendar@odata.associationLink | string | `url` | https://test.abc.com/v1.0/users('ggfe645f-df19-47a1-8e8c-fcd234cb5f6f')/calendars('AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQBGAAADeDDJKaEf4EihMWU6SZgKbAcA07XhOkNngkCkqoNfY_k-jQAAAgEGAAAA07XhOkNngkCkqoNfY_k-jQAAAhTzBBAA')/$ref +action_result.data.\*.calendar@odata.navigationLink | string | `url` | https://test.abc.com/v1.0/users('ffb3645f-df20-47a1-8e9c-fcd234cb5f6f')/calendars('AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQBGAAADeDDJKaEf4EihMWU6SZgKbAcA07XhOkNngkCkqoNfY_k-jQAAAgEGAAAA07XhOkNngkCkqoNfY_k-jQAAAhTzABBB') +action_result.data.\*.categories.\*.name | string | | +action_result.data.\*.changeKey | string | | b1MzKFCcdkuJ24Mc2VsdjwABAdhQhg== +action_result.data.\*.createdDateTime | string | | 2019-10-03T09:03:42.4958512Z +action_result.data.\*.end.dateTime | string | | 2019-10-04T15:30:00.0000000 +action_result.data.\*.end.timeZone | string | | UTC +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.hideAttendees | boolean | | True False +action_result.data.\*.iCalUId | string | | 040000008200E00074C5B7101A82E00800000000347B5D74C979D5010000000000000000100000003F2152B556F23543B1B9C751CCD711A3 +action_result.data.\*.id | string | `msgoffice365 event id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwBGAAAAAADRlY7ewL4xToKRDciQog5UBwBvUzMoUJx2S4nbgxzZWx2PAAAAAAENAABvUzMoUJx2S4nbgxzZWx2PAAEB90vfAAA= +action_result.data.\*.importance | string | | normal +action_result.data.\*.isAllDay | boolean | | True False +action_result.data.\*.isCancelled | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isOnlineMeeting | boolean | | True False +action_result.data.\*.isOrganizer | boolean | | True False +action_result.data.\*.isReminderOn | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2019-10-04T15:24:43.0639836Z +action_result.data.\*.location.address.city | string | | City +action_result.data.\*.location.address.countryOrRegion | string | | Country +action_result.data.\*.location.address.postalCode | string | | 245004 +action_result.data.\*.location.address.state | string | | State +action_result.data.\*.location.address.street | string | | Location Address +action_result.data.\*.location.coordinates.latitude | numeric | | 23.0011 +action_result.data.\*.location.coordinates.longitude | numeric | | 72.4994 +action_result.data.\*.location.displayName | string | | Test +action_result.data.\*.location.locationType | string | | default +action_result.data.\*.location.locationUri | string | `url` | https://www.bingapis.com/api/v6/localbusinesses/YN4070x2912827763012539383?setLang=en +action_result.data.\*.location.uniqueId | string | | f30c3e81-78b7-4f47-8890-f60c3f57e199 +action_result.data.\*.location.uniqueIdType | string | | unknown +action_result.data.\*.locations.\*.address.city | string | | City +action_result.data.\*.locations.\*.address.countryOrRegion | string | | Country +action_result.data.\*.locations.\*.address.postalCode | string | | 245004 +action_result.data.\*.locations.\*.address.state | string | | State +action_result.data.\*.locations.\*.address.street | string | | Location Address +action_result.data.\*.locations.\*.coordinates.latitude | numeric | | 23.0011 +action_result.data.\*.locations.\*.coordinates.longitude | numeric | | 72.4994 +action_result.data.\*.locations.\*.displayName | string | | Test Building Address Bus Stop +action_result.data.\*.locations.\*.locationType | string | | localBusiness +action_result.data.\*.locations.\*.locationUri | string | `url` | https://www.bingapis.com/api/v6/localbusinesses/YN4070x2912827763012539383?setLang=en +action_result.data.\*.locations.\*.uniqueId | string | | f30c3e81-78b7-4f47-8890-f60c3f57e199 +action_result.data.\*.locations.\*.uniqueIdType | string | | locationStore +action_result.data.\*.occurrenceId | string | | +action_result.data.\*.onlineMeeting | string | | +action_result.data.\*.onlineMeetingProvider | string | | unknown +action_result.data.\*.onlineMeetingUrl | string | `url` | +action_result.data.\*.organizer.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.organizer.emailAddress.name | string | | Test Name +action_result.data.\*.originalEndTimeZone | string | | Pacific Standard Time +action_result.data.\*.originalStartTimeZone | string | | Pacific Standard Time +action_result.data.\*.recurrence | string | | +action_result.data.\*.reminderMinutesBeforeStart | numeric | | 15 +action_result.data.\*.responseRequested | boolean | | False True +action_result.data.\*.responseStatus.response | string | | organizer +action_result.data.\*.responseStatus.time | string | | 0001-01-01T00:00:00Z +action_result.data.\*.sensitivity | string | | normal +action_result.data.\*.seriesMasterId | string | | +action_result.data.\*.showAs | string | | busy +action_result.data.\*.start.dateTime | string | | 2019-10-04T15:00:00.0000000 +action_result.data.\*.start.timeZone | string | | UTC +action_result.data.\*.subject | string | | New event - 1 +action_result.data.\*.transactionId | string | | b2e47e5d-8f87-9845-c507-7be56490c432 +action_result.data.\*.type | string | | singleInstance +action_result.data.\*.webLink | string | `url` | https://outlook.office365.com/owa/?itemid=AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwBGAAAAAADRlY7ewL4xToKRDciQog5UBwBvUzMoUJx2S4nbgxzZWx2PAAAAAAENAABvUzMoUJx2S4nbgxzZWx2PAAEB90vfAAA%3D&exvsurl=1&path=/calendar/item +action_result.data.locations.\*.displayName | string | | +action_result.summary.events_matched | numeric | | 8 +action_result.message | string | | Successfully retrieved 8 events +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 + +## action: 'get rule' +Get the properties and relationships of a messageRule object + +Type: **investigate** +Read only: **True** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**user_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` +**rule_id** | required | Inbox rule ID | string | `msgoffice365 rule id` + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.rule_id | string | `msgoffice365 rule id` | AQAABgFGMAc= +action_result.parameter.user_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.data.\*.@odata.context | string | | https://graph.microsoft.com/v1.0/$metadata#users('eeb3645f-df19-47a1-8e8c-fcd234cb5f6f')/mailFolders('inbox')/messageRules/$entity +action_result.data.\*.actions_copyToFolder | string | | AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTswAAAA== +action_result.data.\*.actions_stopProcessingRules | boolean | | True False +action_result.data.\*.conditions_fromAddresses_0_emailAddress_address | string | `email` | cisco@phantomengineering2.onmicrosoft.com +action_result.data.\*.conditions_fromAddresses_0_emailAddress_name | string | | Ryan Edwards +action_result.data.\*.displayName | string | | Move all messages from Casey Edwards to test-msgoffice365-test +action_result.data.\*.hasError | boolean | | True False +action_result.data.\*.id | string | | AQAABgFGL8A= +action_result.data.\*.isEnabled | boolean | | True False +action_result.data.\*.isReadOnly | boolean | | True False +action_result.data.\*.sequence | numeric | | 2 +action_result.summary | string | | +action_result.message | string | | Successfully retrieved specified inbox rule +action_result.message | string | | Successfully retrieved specified inbox rule +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 + +## action: 'list rules' +Get all the messageRule objects defined for the user's inbox + +Type: **investigate** +Read only: **True** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**user_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.user_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.data.\*.actions.copyToFolder | string | `msgoffice365 folder id` | AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTswAAAA== +action_result.data.\*.actions.delete | boolean | | True False +action_result.data.\*.actions.markAsRead | boolean | | True False +action_result.data.\*.actions.moveToFolder | string | `msgoffice365 folder id` | AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTtAAAAA== +action_result.data.\*.actions.stopProcessingRules | boolean | | True False +action_result.data.\*.conditions.fromAddresses.\*.emailAddress.address | string | `email` | cisco@phantomengineering2.onmicrosoft.com +action_result.data.\*.conditions.fromAddresses.\*.emailAddress.name | string | | Ryan Edwards +action_result.data.\*.displayName | string | | Emails to Trash +action_result.data.\*.hasError | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 rule id` | AQAABiQdmB8= +action_result.data.\*.isEnabled | boolean | | True False +action_result.data.\*.isReadOnly | boolean | | True False +action_result.data.\*.sequence | numeric | | 1 +action_result.summary.total_rules_returned | numeric | | 14 +action_result.message | string | | Successfully retrieved 7 rules +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'list users' Retrieve a list of users @@ -503,26 +591,26 @@ PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS **limit** | optional | Maximum number of users to return | numeric | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.filter | string | -action\_result\.parameter\.limit | numeric | -action\_result\.data\.\*\.businessPhones | string | -action\_result\.data\.\*\.displayName | string | -action\_result\.data\.\*\.givenName | string | -action\_result\.data\.\*\.id | string | `msgoffice365 user id` -action\_result\.data\.\*\.jobTitle | string | -action\_result\.data\.\*\.mail | string | `email` -action\_result\.data\.\*\.mobilePhone | string | -action\_result\.data\.\*\.officeLocation | string | -action\_result\.data\.\*\.preferredLanguage | string | -action\_result\.data\.\*\.surname | string | -action\_result\.data\.\*\.userPrincipalName | string | `msgoffice365 user principal name` `email` -action\_result\.summary\.total\_users\_returned | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.filter | string | | displayName eq 'User Name' +action_result.parameter.limit | numeric | | 20 +action_result.data.\*.businessPhones | string | | 2056120271 +action_result.data.\*.displayName | string | | Test Admin +action_result.data.\*.givenName | string | | Test +action_result.data.\*.id | string | `msgoffice365 user id` | 6132ca31-7a09-434f-a269-abe836d0c01e +action_result.data.\*.jobTitle | string | | +action_result.data.\*.mail | string | `email` | test@testdomain.abc.com +action_result.data.\*.mobilePhone | string | | +action_result.data.\*.officeLocation | string | | +action_result.data.\*.preferredLanguage | string | | +action_result.data.\*.surname | string | | Globaltest +action_result.data.\*.userPrincipalName | string | `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.summary.total_users_returned | numeric | | 11 +action_result.message | string | | Successfully retrieved 11 users +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'list groups' List all the groups in an organization, including but not limited to Office 365 groups @@ -537,46 +625,46 @@ PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS **limit** | optional | Maximum number of groups to return | numeric | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.filter | string | -action\_result\.parameter\.limit | numeric | -action\_result\.data\.\*\.classification | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.creationOptions | string | -action\_result\.data\.\*\.deletedDateTime | string | -action\_result\.data\.\*\.description | string | -action\_result\.data\.\*\.displayName | string | -action\_result\.data\.\*\.expirationDateTime | string | -action\_result\.data\.\*\.groupTypes | string | -action\_result\.data\.\*\.id | string | `msgoffice365 group id` -action\_result\.data\.\*\.isAssignableToRole | string | -action\_result\.data\.\*\.mail | string | `email` -action\_result\.data\.\*\.mailEnabled | boolean | -action\_result\.data\.\*\.mailNickname | string | -action\_result\.data\.\*\.membershipRule | string | -action\_result\.data\.\*\.membershipRuleProcessingState | string | -action\_result\.data\.\*\.onPremisesDomainName | string | -action\_result\.data\.\*\.onPremisesLastSyncDateTime | string | -action\_result\.data\.\*\.onPremisesNetBiosName | string | -action\_result\.data\.\*\.onPremisesSamAccountName | string | -action\_result\.data\.\*\.onPremisesSecurityIdentifier | string | -action\_result\.data\.\*\.onPremisesSyncEnabled | string | -action\_result\.data\.\*\.preferredDataLocation | string | -action\_result\.data\.\*\.preferredLanguage | string | -action\_result\.data\.\*\.proxyAddresses | string | -action\_result\.data\.\*\.renewedDateTime | string | -action\_result\.data\.\*\.resourceBehaviorOptions | string | -action\_result\.data\.\*\.resourceProvisioningOptions | string | -action\_result\.data\.\*\.securityEnabled | boolean | -action\_result\.data\.\*\.securityIdentifier | string | -action\_result\.data\.\*\.theme | string | -action\_result\.data\.\*\.visibility | string | -action\_result\.summary\.total\_groups\_returned | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.filter | string | | displayName eq 'Group Name' +action_result.parameter.limit | numeric | | 20 +action_result.data.\*.classification | string | | +action_result.data.\*.createdDateTime | string | | 2018-09-11T09:51:07Z +action_result.data.\*.creationOptions | string | | ExchangeProvisioningFlags:3552 +action_result.data.\*.deletedDateTime | string | | +action_result.data.\*.description | string | | This is for testing purpose +action_result.data.\*.displayName | string | | Test-test-site +action_result.data.\*.expirationDateTime | string | | +action_result.data.\*.groupTypes | string | | Unified +action_result.data.\*.id | string | `msgoffice365 group id` | 2a201c95-101b-42d9-a7af-9a2fdf8193f1 +action_result.data.\*.isAssignableToRole | string | | +action_result.data.\*.mail | string | `email` | Test-test-site@testdomain.abc.com +action_result.data.\*.mailEnabled | boolean | | True False +action_result.data.\*.mailNickname | string | | Test-test-site +action_result.data.\*.membershipRule | string | | +action_result.data.\*.membershipRuleProcessingState | string | | +action_result.data.\*.onPremisesDomainName | string | | +action_result.data.\*.onPremisesLastSyncDateTime | string | | +action_result.data.\*.onPremisesNetBiosName | string | | +action_result.data.\*.onPremisesSamAccountName | string | | +action_result.data.\*.onPremisesSecurityIdentifier | string | | +action_result.data.\*.onPremisesSyncEnabled | string | | +action_result.data.\*.preferredDataLocation | string | | +action_result.data.\*.preferredLanguage | string | | +action_result.data.\*.proxyAddresses | string | | SMTP:test-h@testdomain.abc.com +action_result.data.\*.renewedDateTime | string | | 2018-09-11T09:51:07Z +action_result.data.\*.resourceBehaviorOptions | string | | WelcomeEmailDisabled +action_result.data.\*.resourceProvisioningOptions | string | | Team +action_result.data.\*.securityEnabled | boolean | | True False +action_result.data.\*.securityIdentifier | string | | S-1-12-1-294681889-1319597617-672379543-28952022 +action_result.data.\*.theme | string | | +action_result.data.\*.visibility | string | | Private +action_result.summary.total_groups_returned | numeric | | 9 +action_result.message | string | | Successfully retrieved 9 groups +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'list group members' List all the members in group @@ -587,35 +675,35 @@ Read only: **True** #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**group\_id** | required | Group ID | string | `msgoffice365 group id` -**get\_transitive\_members** | optional | Get a list of the group's members\. A group can have users, devices, organizational contacts, and other groups as members\. This operation is transitive and returns a flat list of all nested members | boolean | +**group_id** | required | Group ID | string | `msgoffice365 group id` +**get_transitive_members** | optional | Get a list of the group's members. A group can have users, devices, organizational contacts, and other groups as members. This operation is transitive and returns a flat list of all nested members | boolean | **filter** | optional | Search for specific results | string | **limit** | optional | Maximum number of members to return | numeric | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.filter | string | -action\_result\.parameter\.get\_transitive\_members | boolean | -action\_result\.parameter\.group\_id | string | `msgoffice365 group id` -action\_result\.parameter\.limit | numeric | -action\_result\.data\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.businessPhones | string | -action\_result\.data\.\*\.displayName | string | -action\_result\.data\.\*\.givenName | string | -action\_result\.data\.\*\.id | string | `msgoffice365 user id` -action\_result\.data\.\*\.jobTitle | string | -action\_result\.data\.\*\.mail | string | `email` -action\_result\.data\.\*\.mobilePhone | string | -action\_result\.data\.\*\.officeLocation | string | -action\_result\.data\.\*\.preferredLanguage | string | -action\_result\.data\.\*\.surname | string | -action\_result\.data\.\*\.userPrincipalName | string | `msgoffice365 user principal name` `email` -action\_result\.summary\.total\_members\_returned | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.filter | string | | displayName eq 'Group Name' +action_result.parameter.get_transitive_members | boolean | | True False +action_result.parameter.group_id | string | `msgoffice365 group id` | 11907d21-7631-4ea7-97b2-1328d1c5b901 +action_result.parameter.limit | numeric | | 20 +action_result.data.\*.@odata.type | string | | #test.abc.user +action_result.data.\*.businessPhones | string | | 2056120271 +action_result.data.\*.displayName | string | | Test Admin +action_result.data.\*.givenName | string | | Test +action_result.data.\*.id | string | `msgoffice365 user id` | 6132ca31-7a09-434f-a269-abe836d0c01e +action_result.data.\*.jobTitle | string | | +action_result.data.\*.mail | string | `email` | test@testdomain.abc.com +action_result.data.\*.mobilePhone | string | | +action_result.data.\*.officeLocation | string | | +action_result.data.\*.preferredLanguage | string | | +action_result.data.\*.surname | string | | Globaltest +action_result.data.\*.userPrincipalName | string | `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.summary.total_members_returned | numeric | | 9 +action_result.message | string | | Successfully retrieved 9 groups +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'list folders' Retrieve a list of mail folders @@ -623,32 +711,32 @@ Retrieve a list of mail folders Type: **investigate** Read only: **True** -If you want to list all the child folders \(includes all the sub\-levels\) of the specific parent folder, then, you have to provide the parent folder\_id parameter\. If you don't provide folder\_id it will list all the folders on Office 365 account \(includes all the sub\-level folders\)\. +If you want to list all the child folders (includes all the sub-levels) of the specific parent folder, then, you have to provide the parent folder_id parameter. If you don't provide folder_id it will list all the folders on Office 365 account (includes all the sub-level folders). #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**user\_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` -**folder\_id** | optional | Parent mail folder ID | string | `msgoffice365 folder id` +**user_id** | required | User ID/Principal name | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` +**folder_id** | optional | Parent mail folder ID | string | `msgoffice365 folder id` #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.folder\_id | string | `msgoffice365 folder id` -action\_result\.parameter\.user\_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` -action\_result\.data\.\*\.childFolderCount | numeric | -action\_result\.data\.\*\.displayName | string | -action\_result\.data\.\*\.id | string | `msgoffice365 folder id` -action\_result\.data\.\*\.isHidden | boolean | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.sizeInBytes | numeric | -action\_result\.data\.\*\.totalItemCount | numeric | -action\_result\.data\.\*\.unreadItemCount | numeric | -action\_result\.summary\.total\_folders\_returned | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.folder_id | string | `msgoffice365 folder id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA= +action_result.parameter.user_id | string | `msgoffice365 user id` `msgoffice365 user principal name` `email` | test@testdomain.abc.com +action_result.data.\*.childFolderCount | numeric | | 1 +action_result.data.\*.displayName | string | | test +action_result.data.\*.id | string | `msgoffice365 folder id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA= +action_result.data.\*.isHidden | boolean | | True False +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAAAAAEIAAA= +action_result.data.\*.sizeInBytes | numeric | | 7920 +action_result.data.\*.totalItemCount | numeric | | 0 +action_result.data.\*.unreadItemCount | numeric | | 0 +action_result.summary.total_folders_returned | numeric | | 14 +action_result.message | string | | Successfully retrieved 14 mail folders +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'copy email' Copy an email to a folder @@ -656,66 +744,66 @@ Copy an email to a folder Type: **generic** Read only: **False** -The get\_folder\_id parameter should be enabled only when you have specified folder name/folder path in the folder parameter\. If you provide folder ID in the folder parameter and set get\_folder\_id parameter to true, it will throw an error of folder ID not found for given folder name \(because the action considers folder parameter value as folder name/folder path\)\. The folder parameter must be either a \(case sensitive\) well\-known name \[list here; https\://docs\.microsoft\.com/en\-us/graph/api/resources/mailfolder?view=graph\-rest\-1\.0\] or the internal o365 folder ID\. The action supports copying to a folder that is nested within another\. To copy in such a folder, specify the complete folder path using the '/' \(forward slash\) as the separator\.
e\.g\. to search in a folder named phishing which is nested within \(is a child of\) Inbox, set the value as Inbox/phishing\. If a folder name has a literal forward slash\('/'\) in the name escape it with a backslash\('\\'\) to differentiate\. +The get_folder_id parameter should be enabled only when you have specified folder name/folder path in the folder parameter. If you provide folder ID in the folder parameter and set get_folder_id parameter to true, it will throw an error of folder ID not found for given folder name (because the action considers folder parameter value as folder name/folder path). The folder parameter must be either a (case sensitive) well-known name [list here; https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0] or the internal o365 folder ID. The action supports copying to a folder that is nested within another. To copy in such a folder, specify the complete folder path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Message ID to copy | string | `msgoffice365 message id` -**email\_address** | required | Source mailbox \(email\) | string | `email` -**folder** | required | Destination folder; this must be either a \(case\-sensitive\) well\-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -**get\_folder\_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/' ; i\.e\. Inbox/dir1/dir2/dir3\. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | +**email_address** | required | Source mailbox (email) | string | `email` +**folder** | required | Destination folder; this must be either a (case-sensitive) well-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` +**get_folder_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/' ; i.e. Inbox/dir1/dir2/dir3. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -action\_result\.parameter\.get\_folder\_id | boolean | -action\_result\.parameter\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.bccRecipients\.email | string | `email` -action\_result\.data\.\*\.bccRecipients\.name | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.bodyPreview | string | -action\_result\.data\.\*\.categories | string | -action\_result\.data\.\*\.ccRecipients\.email | string | `email` -action\_result\.data\.\*\.ccRecipients\.name | string | -action\_result\.data\.\*\.changeKey | string | -action\_result\.data\.\*\.conversationId | string | -action\_result\.data\.\*\.conversationIndex | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.flag\.flagStatus | string | -action\_result\.data\.\*\.from\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.from\.emailAddress\.name | string | -action\_result\.data\.\*\.hasAttachments | boolean | -action\_result\.data\.\*\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.importance | string | -action\_result\.data\.\*\.inferenceClassification | string | -action\_result\.data\.\*\.internetMessageId | string | `msgoffice365 internet message id` -action\_result\.data\.\*\.isDeliveryReceiptRequested | boolean | -action\_result\.data\.\*\.isDraft | boolean | -action\_result\.data\.\*\.isRead | boolean | -action\_result\.data\.\*\.isReadReceiptRequested | boolean | -action\_result\.data\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.receivedDateTime | string | -action\_result\.data\.\*\.replyTo | string | -action\_result\.data\.\*\.sender\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.sender\.emailAddress\.name | string | -action\_result\.data\.\*\.sentDateTime | string | -action\_result\.data\.\*\.subject | string | `msgoffice365 subject` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.webLink | string | `url` -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAA +action_result.parameter.get_folder_id | boolean | | True False +action_result.parameter.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwABS2DpdwAAAA== +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#message +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFQwHj9" +action_result.data.\*.@odata.type | string | | #test.abc.message +action_result.data.\*.bccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.bccRecipients.name | string | | Test Name +action_result.data.\*.body.content | string | | `plain text?\\r\\n` +action_result.data.\*.body.contentType | string | | text +action_result.data.\*.bodyPreview | string | | plain text? +action_result.data.\*.categories | string | | +action_result.data.\*.ccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.ccRecipients.name | string | | Test Name +action_result.data.\*.changeKey | string | | CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFQwHj9 +action_result.data.\*.conversationId | string | | AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQANDpL7xEHORGgd1idbVXqcg= +action_result.data.\*.conversationIndex | string | | AQHW+IHb9hH4JnJtjUmniPjyy9YF2Y== +action_result.data.\*.createdDateTime | string | | 2017-10-25T22:29:01Z +action_result.data.\*.flag.flagStatus | string | | notFlagged +action_result.data.\*.from.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.from.emailAddress.name | string | | Test Name +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAAQSl1b8BFiEmbqZql_JiUtwABUH-stgAAAA== +action_result.data.\*.importance | string | | normal +action_result.data.\*.inferenceClassification | string | | focused +action_result.data.\*.internetMessageId | string | `msgoffice365 internet message id` | +action_result.data.\*.isDeliveryReceiptRequested | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isRead | boolean | | True False +action_result.data.\*.isReadReceiptRequested | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2017-11-02T23:58:59Z +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAA +action_result.data.\*.receivedDateTime | string | | 2017-10-25T22:29:01Z +action_result.data.\*.replyTo | string | | +action_result.data.\*.sender.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.sender.emailAddress.name | string | | Test Name +action_result.data.\*.sentDateTime | string | | 2017-10-25T22:28:57Z +action_result.data.\*.subject | string | `msgoffice365 subject` | more body formats? +action_result.data.\*.toRecipients.\*.emailAddress.address | string | `email` | Test@testdomain.abc.com +action_result.data.\*.toRecipients.\*.emailAddress.name | string | | Test Name +action_result.data.\*.webLink | string | `url` | https://outlook.office365.com/owa/?ItemID=AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0%2BMMHKonvdoWQcAQSl1b8BFiEmbqZql%2BJiUtwAAAgEbAAAAQSl1b8BFiEmbqZql%2BJiUtwABUH%2FstgAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem +action_result.summary | string | | +action_result.message | string | | Successfully copied email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'move email' Move an email to a folder @@ -723,66 +811,66 @@ Move an email to a folder Type: **generic** Read only: **False** -The get\_folder\_id parameter should be enabled only when you have specified folder name/folder path in the folder parameter\. If you provide folder ID in the folder parameter and set get\_folder\_id parameter to true, it will throw an error of folder ID not found for given folder name \(because the action considers folder parameter value as folder name/folder path\)\. The folder parameter must be either a \(case sensitive\) well\-known name \[list here; https\://docs\.microsoft\.com/en\-us/graph/api/resources/mailfolder?view=graph\-rest\-1\.0\] or the internal o365 folder ID\. The action supports moving to a folder that is nested within another\. To copy in such a folder, specify the complete folder path using the '/' \(forward slash\) as the separator\.
e\.g\. to search in a folder named phishing which is nested within \(is a child of\) Inbox, set the value as Inbox/phishing\. If a folder name has a literal forward slash\('/'\) in the name escape it with a backslash\('\\'\) to differentiate\. +The get_folder_id parameter should be enabled only when you have specified folder name/folder path in the folder parameter. If you provide folder ID in the folder parameter and set get_folder_id parameter to true, it will throw an error of folder ID not found for given folder name (because the action considers folder parameter value as folder name/folder path). The folder parameter must be either a (case sensitive) well-known name [list here; https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0] or the internal o365 folder ID. The action supports moving to a folder that is nested within another. To copy in such a folder, specify the complete folder path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Message ID to move | string | `msgoffice365 message id` -**email\_address** | required | Source mailbox \(email\) | string | `email` -**folder** | required | Destination folder; this must be either a \(case\-sensitive\) well\-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -**get\_folder\_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/'\(forward slash\) ; i\.e\. Inbox/dir1/dir2/dir3\. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | +**email_address** | required | Source mailbox (email) | string | `email` +**folder** | required | Destination folder; this must be either a (case-sensitive) well-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` +**get_folder_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/'(forward slash) ; i.e. Inbox/dir1/dir2/dir3. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -action\_result\.parameter\.get\_folder\_id | boolean | -action\_result\.parameter\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.bccRecipients\.email | string | `email` -action\_result\.data\.\*\.bccRecipients\.name | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.bodyPreview | string | -action\_result\.data\.\*\.categories | string | -action\_result\.data\.\*\.ccRecipients\.email | string | `email` -action\_result\.data\.\*\.ccRecipients\.name | string | -action\_result\.data\.\*\.changeKey | string | -action\_result\.data\.\*\.conversationId | string | -action\_result\.data\.\*\.conversationIndex | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.flag\.flagStatus | string | -action\_result\.data\.\*\.from\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.from\.emailAddress\.name | string | -action\_result\.data\.\*\.hasAttachments | boolean | -action\_result\.data\.\*\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.importance | string | -action\_result\.data\.\*\.inferenceClassification | string | -action\_result\.data\.\*\.internetMessageId | string | `msgoffice365 internet message id` -action\_result\.data\.\*\.isDeliveryReceiptRequested | boolean | -action\_result\.data\.\*\.isDraft | boolean | -action\_result\.data\.\*\.isRead | boolean | -action\_result\.data\.\*\.isReadReceiptRequested | boolean | -action\_result\.data\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.receivedDateTime | string | -action\_result\.data\.\*\.replyTo | string | -action\_result\.data\.\*\.sender\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.sender\.emailAddress\.name | string | -action\_result\.data\.\*\.sentDateTime | string | -action\_result\.data\.\*\.subject | string | `msgoffice365 subject` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.webLink | string | `url` -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAA +action_result.parameter.get_folder_id | boolean | | True False +action_result.parameter.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwABS2DpdwAAAA== +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#message +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFQwHj9" +action_result.data.\*.@odata.type | string | | #test.abc.message +action_result.data.\*.bccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.bccRecipients.name | string | | Test User +action_result.data.\*.body.content | string | | `plain text?\\r\\n` +action_result.data.\*.body.contentType | string | | text +action_result.data.\*.bodyPreview | string | | plain text? +action_result.data.\*.categories | string | | +action_result.data.\*.ccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.ccRecipients.name | string | | Test Name +action_result.data.\*.changeKey | string | | CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFQwHj9 +action_result.data.\*.conversationId | string | | AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQANDpL7xEHORGgd1idbVXqcg= +action_result.data.\*.conversationIndex | string | | AQHW+IHb9hH4JnJtjUmniPjyy9YF1Y== +action_result.data.\*.createdDateTime | string | | 2017-10-25T22:29:01Z +action_result.data.\*.flag.flagStatus | string | | notFlagged +action_result.data.\*.from.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.from.emailAddress.name | string | | Test Name +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAAQSl1b8BFiEmbqZql_JiUtwABUH-stgAAAA== +action_result.data.\*.importance | string | | normal +action_result.data.\*.inferenceClassification | string | | focused +action_result.data.\*.internetMessageId | string | `msgoffice365 internet message id` | +action_result.data.\*.isDeliveryReceiptRequested | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isRead | boolean | | True False +action_result.data.\*.isReadReceiptRequested | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2017-11-02T23:58:59Z +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEbAAAA +action_result.data.\*.receivedDateTime | string | | 2017-10-25T22:29:01Z +action_result.data.\*.replyTo | string | | +action_result.data.\*.sender.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.sender.emailAddress.name | string | | Test Name +action_result.data.\*.sentDateTime | string | | 2017-10-25T22:28:57Z +action_result.data.\*.subject | string | `msgoffice365 subject` | more body formats? +action_result.data.\*.toRecipients.\*.emailAddress.address | string | `email` | Test@testdomain.abc.com +action_result.data.\*.toRecipients.\*.emailAddress.name | string | | Test Name +action_result.data.\*.webLink | string | `url` | https://outlook.office365.com/owa/?ItemID=AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0%2BMMHKonvdoWQcAQSl1b8BFiEmbqZql%2BJiUtwAAAgEbAAAAQSl1b8BFiEmbqZql%2BJiUtwABUH%2FstgAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem +action_result.summary | string | | +action_result.message | string | | Successfully moved email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'delete email' Delete an email @@ -794,19 +882,19 @@ Read only: **False** PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Message ID to delete | string | `msgoffice365 message id` -**email\_address** | required | Email address of the mailbox owner | string | `email` +**email_address** | required | Email address of the mailbox owner | string | `email` #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.id | string | `msgoffice365 message id` -action\_result\.data | string | -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.id | string | `msgoffice365 message id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwBGAAAAAADRlY7ewL4xToKRDciQog5UBwBvUzMoUJx2S4nbgxzZWx2PAAAAAAEMAABvUzMoUJx2S4nbgxzZWx2PAAEIbt7NAAA= +action_result.data | string | | +action_result.summary | string | | +action_result.message | string | | Successfully deleted email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'delete event' Delete an event from user calendar @@ -818,21 +906,21 @@ Read only: **False** PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Event ID to delete | string | `msgoffice365 event id` -**email\_address** | required | Email address of the mailbox owner | string | `email` -**send\_decline\_response** | optional | Send decline response to the organizer | boolean | +**email_address** | required | Email address of the mailbox owner | string | `email` +**send_decline_response** | optional | Send decline response to the organizer | boolean | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.id | string | `msgoffice365 event id` -action\_result\.parameter\.send\_decline\_response | boolean | -action\_result\.data | string | -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.id | string | `msgoffice365 event id` | TestAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwBGAAAAAADRlY7ewL4xToKRDciQog5UBwBvUzMoUJx2S4nbgxzZWx2PAAAAAAEMAABvUzMoUJx2S4nbgxzZWx2PAAEIbt7NAAA= +action_result.parameter.send_decline_response | boolean | | True False +action_result.data | string | | +action_result.summary | string | | +action_result.message | string | | Successfully deleted email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'get email' Get an email from the server @@ -840,335 +928,335 @@ Get an email from the server Type: **investigate** Read only: **True** -If the 'download attachments' parameter is set to true, the action will ingest the '\#microsoft\.graph\.itemAttachment' and '\#microsoft\.graph\.fileAttachment' type of attachments\. +If the 'download attachments' parameter is set to true, the action will ingest the '#microsoft.graph.itemAttachment' and '#microsoft.graph.fileAttachment' type of attachments. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Message ID to get | string | `msgoffice365 message id` -**email\_address** | required | Email address of the mailbox owner | string | `email` -**download\_attachments** | optional | Download attachments to vault | boolean | -**extract\_headers** | optional | Extract email headers | boolean | -**download\_email** | optional | Download email to vault | boolean | +**email_address** | required | Email address of the mailbox owner | string | `email` +**download_attachments** | optional | Download attachments to vault | boolean | +**extract_headers** | optional | Extract email headers | boolean | +**download_email** | optional | Download email to vault | boolean | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.download\_attachments | boolean | -action\_result\.parameter\.download\_email | boolean | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.extract\_headers | boolean | -action\_result\.parameter\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.allowNewTimeProposals | string | -action\_result\.data\.\*\.attachments\.\*\.\@odata\.mediaContentType | string | -action\_result\.data\.\*\.attachments\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.attachments\.\*\.attachmentType | string | -action\_result\.data\.\*\.attachments\.\*\.contentId | string | `email` -action\_result\.data\.\*\.attachments\.\*\.contentLocation | string | -action\_result\.data\.\*\.attachments\.\*\.contentType | string | -action\_result\.data\.\*\.attachments\.\*\.id | string | -action\_result\.data\.\*\.attachments\.\*\.isInline | boolean | -action\_result\.data\.\*\.attachments\.\*\.itemType | string | -action\_result\.data\.\*\.attachments\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.attachments\.\*\.name | string | -action\_result\.data\.\*\.attachments\.\*\.size | numeric | -action\_result\.data\.\*\.attachments\.\*\.vaultId | string | `sha1` `vault id` -action\_result\.data\.\*\.bccRecipients\.email | string | `email` -action\_result\.data\.\*\.bccRecipients\.name | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.bodyPreview | string | -action\_result\.data\.\*\.categories | string | -action\_result\.data\.\*\.ccRecipients\.email | string | `email` -action\_result\.data\.\*\.ccRecipients\.name | string | -action\_result\.data\.\*\.changeKey | string | -action\_result\.data\.\*\.conversationId | string | -action\_result\.data\.\*\.conversationIndex | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.endDateTime\.dateTime | string | -action\_result\.data\.\*\.endDateTime\.timeZone | string | -action\_result\.data\.\*\.event\.\@odata\.etag | string | -action\_result\.data\.\*\.event\.allowNewTimeProposals | boolean | -action\_result\.data\.\*\.event\.attendees\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.event\.attendees\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.event\.attendees\.\*\.status\.response | string | -action\_result\.data\.\*\.event\.attendees\.\*\.status\.time | string | -action\_result\.data\.\*\.event\.attendees\.\*\.type | string | -action\_result\.data\.\*\.event\.body\.content | string | -action\_result\.data\.\*\.event\.body\.contentType | string | -action\_result\.data\.\*\.event\.bodyPreview | string | -action\_result\.data\.\*\.event\.calendar\@odata\.associationLink | string | `url` -action\_result\.data\.\*\.event\.calendar\@odata\.navigationLink | string | `url` -action\_result\.data\.\*\.event\.changeKey | string | -action\_result\.data\.\*\.event\.createdDateTime | string | -action\_result\.data\.\*\.event\.end\.dateTime | string | -action\_result\.data\.\*\.event\.end\.timeZone | string | -action\_result\.data\.\*\.event\.hasAttachments | boolean | -action\_result\.data\.\*\.event\.hideAttendees | boolean | -action\_result\.data\.\*\.event\.iCalUId | string | -action\_result\.data\.\*\.event\.id | string | `msgoffice365 event id` -action\_result\.data\.\*\.event\.importance | string | -action\_result\.data\.\*\.event\.isAllDay | boolean | -action\_result\.data\.\*\.event\.isCancelled | boolean | -action\_result\.data\.\*\.event\.isDraft | boolean | -action\_result\.data\.\*\.event\.isOnlineMeeting | boolean | -action\_result\.data\.\*\.event\.isOrganizer | boolean | -action\_result\.data\.\*\.event\.isReminderOn | boolean | -action\_result\.data\.\*\.event\.lastModifiedDateTime | string | -action\_result\.data\.\*\.event\.location\.displayName | string | -action\_result\.data\.\*\.event\.location\.locationType | string | -action\_result\.data\.\*\.event\.location\.uniqueIdType | string | -action\_result\.data\.\*\.event\.occurrenceId | string | -action\_result\.data\.\*\.event\.onlineMeeting\.joinUrl | string | `url` -action\_result\.data\.\*\.event\.onlineMeetingProvider | string | -action\_result\.data\.\*\.event\.onlineMeetingUrl | string | -action\_result\.data\.\*\.event\.organizer\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.event\.organizer\.emailAddress\.name | string | -action\_result\.data\.\*\.event\.originalEndTimeZone | string | -action\_result\.data\.\*\.event\.originalStartTimeZone | string | -action\_result\.data\.\*\.event\.recurrence | string | -action\_result\.data\.\*\.event\.reminderMinutesBeforeStart | numeric | -action\_result\.data\.\*\.event\.responseRequested | boolean | -action\_result\.data\.\*\.event\.responseStatus\.response | string | -action\_result\.data\.\*\.event\.responseStatus\.time | string | -action\_result\.data\.\*\.event\.sensitivity | string | -action\_result\.data\.\*\.event\.seriesMasterId | string | -action\_result\.data\.\*\.event\.showAs | string | -action\_result\.data\.\*\.event\.start\.dateTime | string | -action\_result\.data\.\*\.event\.start\.timeZone | string | -action\_result\.data\.\*\.event\.subject | string | -action\_result\.data\.\*\.event\.transactionId | string | -action\_result\.data\.\*\.event\.type | string | -action\_result\.data\.\*\.event\.webLink | string | `url` -action\_result\.data\.\*\.flag\.flagStatus | string | -action\_result\.data\.\*\.from\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.from\.emailAddress\.name | string | `email` -action\_result\.data\.\*\.hasAttachments | boolean | -action\_result\.data\.\*\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.importance | string | -action\_result\.data\.\*\.inferenceClassification | string | -action\_result\.data\.\*\.internetMessageHeaders\.ARC\-Authentication\-Results | string | -action\_result\.data\.\*\.internetMessageHeaders\.ARC\-Message\-Signature | string | -action\_result\.data\.\*\.internetMessageHeaders\.ARC\-Seal | string | -action\_result\.data\.\*\.internetMessageHeaders\.Accept\-Language | string | -action\_result\.data\.\*\.internetMessageHeaders\.Authentication\-Results | string | -action\_result\.data\.\*\.internetMessageHeaders\.Authentication\-Results\-Original | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Language | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Transfer\-Encoding | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Type | string | -action\_result\.data\.\*\.internetMessageHeaders\.DKIM\-Signature | string | -action\_result\.data\.\*\.internetMessageHeaders\.Date | string | -action\_result\.data\.\*\.internetMessageHeaders\.From | string | -action\_result\.data\.\*\.internetMessageHeaders\.In\-Reply\-To | string | -action\_result\.data\.\*\.internetMessageHeaders\.MIME\-Version | string | -action\_result\.data\.\*\.internetMessageHeaders\.Message\-ID | string | -action\_result\.data\.\*\.internetMessageHeaders\.Received | string | -action\_result\.data\.\*\.internetMessageHeaders\.Received\-SPF | string | -action\_result\.data\.\*\.internetMessageHeaders\.References | string | -action\_result\.data\.\*\.internetMessageHeaders\.Return\-Path | string | `email` -action\_result\.data\.\*\.internetMessageHeaders\.Subject | string | -action\_result\.data\.\*\.internetMessageHeaders\.Thread\-Index | string | -action\_result\.data\.\*\.internetMessageHeaders\.Thread\-Topic | string | -action\_result\.data\.\*\.internetMessageHeaders\.To | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-EOPAttributedMessage | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-EOPTenantAttributedMessage | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Forefront\-Antispam\-Report | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Forefront\-Antispam\-Report\-Untrusted | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Gm\-Message\-State | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Google\-DKIM\-Signature | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Google\-Smtp\-Source | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-AntiSpam\-MessageData | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-AntiSpam\-MessageData\-Original\-0 | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-AntiSpam\-MessageData\-Original\-ChunkCount | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-AuthAs | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-AuthSource | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-FromEntityHeader | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-MailboxType | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-Network\-Message\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-OriginalArrivalTime | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-UserPrincipalName | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthAs | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthMechanism | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthSource | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationInterval | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationIntervalReason | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationStartTime | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationStartTimeReason | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-MessageDirectionality | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-Network\-Message\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-SCL | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Processed\-By\-BccFoldering | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-CrossTenantHeadersPromoted | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-CrossTenantHeadersStamped | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-CrossTenantHeadersStripped | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-EndToEndLatency | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Has\-Attach | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Office365\-Filtering\-Correlation\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Office365\-Filtering\-Correlation\-Id\-Prvs | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Oob\-TLC\-OOBClassifiers | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-PublicTrafficType | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-TNEF\-Correlator | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-TrafficTypeDiagnostic | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Mailbox\-Delivery | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Message\-Info | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Message\-Info\-Original | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Untrusted | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Originating\-IP | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Received | string | -action\_result\.data\.\*\.internetMessageHeaders\.subject | string | -action\_result\.data\.\*\.internetMessageHeaders\.x\-ms\-exchange\-antispam\-relay | string | -action\_result\.data\.\*\.internetMessageHeaders\.x\-ms\-exchange\-calendar\-series\-instance\-id | string | -action\_result\.data\.\*\.internetMessageHeaders\.x\-ms\-exchange\-senderadcheck | string | -action\_result\.data\.\*\.internetMessageHeaders\.x\-ms\-traffictypediagnostic | string | -action\_result\.data\.\*\.internetMessageId | string | `msgoffice365 internet message id` -action\_result\.data\.\*\.isAllDay | boolean | -action\_result\.data\.\*\.isDelegated | boolean | -action\_result\.data\.\*\.isDeliveryReceiptRequested | boolean | -action\_result\.data\.\*\.isDraft | boolean | -action\_result\.data\.\*\.isOutOfDate | boolean | -action\_result\.data\.\*\.isRead | boolean | -action\_result\.data\.\*\.isReadReceiptRequested | boolean | -action\_result\.data\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.meetingMessageType | string | -action\_result\.data\.\*\.meetingRequestType | string | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.previousEndDateTime | string | -action\_result\.data\.\*\.previousLocation | string | -action\_result\.data\.\*\.previousStartDateTime | string | -action\_result\.data\.\*\.previousEndDateTime\.dateTime | string | -action\_result\.data\.\*\.previousEndDateTime\.timeZone | string | -action\_result\.data\.\*\.previousStartDateTime\.dateTime | string | -action\_result\.data\.\*\.previousStartDateTime\.timeZone | string | -action\_result\.data\.\*\.receivedDateTime | string | -action\_result\.data\.\*\.recurrence | string | -action\_result\.data\.\*\.replyTo | string | -action\_result\.data\.\*\.responseRequested | boolean | -action\_result\.data\.\*\.sender\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.sender\.emailAddress\.name | string | `email` -action\_result\.data\.\*\.sentDateTime | string | -action\_result\.data\.\*\.startDateTime\.dateTime | string | -action\_result\.data\.\*\.startDateTime\.timeZone | string | -action\_result\.data\.\*\.subject | string | `msgoffice365 subject` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.type | string | -action\_result\.data\.\*\.vaultId | string | -action\_result\.data\.\*\.webLink | string | `url` -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.download_attachments | boolean | | True False +action_result.parameter.download_email | boolean | | True False +action_result.parameter.email_address | string | `email` | test@abc.com +action_result.parameter.extract_headers | boolean | | True False +action_result.parameter.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwABS2DpfAAAAA== +action_result.data.\*.@odata.context | string | `url` | https://abc.test.com/v1.0/$metadata#users('test%40abc.com')/messages/$entity +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFLoCsS" +action_result.data.\*.@odata.type | string | | #test.abc.eventMessage +action_result.data.\*.allowNewTimeProposals | string | | +action_result.data.\*.attachments.\*.@odata.mediaContentType | string | | application/octet-stream +action_result.data.\*.attachments.\*.@odata.type | string | | #test.abc.fileAttachment +action_result.data.\*.attachments.\*.attachmentType | string | | #test.abc.fileAttachment +action_result.data.\*.attachments.\*.contentId | string | `email` | F5832F4CF6EFEC41B9CBC6DED238A234@namprd18.prod.outlook.com +action_result.data.\*.attachments.\*.contentLocation | string | | +action_result.data.\*.attachments.\*.contentType | string | | text/plain +action_result.data.\*.attachments.\*.id | string | | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwABS2DpfAAAAAESABAA0EuDIoiFb0ifXM0ETmQMVw== +action_result.data.\*.attachments.\*.isInline | boolean | | True False +action_result.data.\*.attachments.\*.itemType | string | | #test.abc.message +action_result.data.\*.attachments.\*.lastModifiedDateTime | string | | 2017-10-26T01:31:43Z +action_result.data.\*.attachments.\*.name | string | | attachment.txt +action_result.data.\*.attachments.\*.size | numeric | | 355 +action_result.data.\*.attachments.\*.vaultId | string | `sha1` `vault id` | 719dbf72d7c0bc89d7e34306c08a0b66191902b9 +action_result.data.\*.bccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.bccRecipients.name | string | | Test Name +action_result.data.\*.body.content | string | | `Have a good time with these.\\r\\n` +action_result.data.\*.body.contentType | string | | text +action_result.data.\*.bodyPreview | string | | Have a good time with these. +action_result.data.\*.categories | string | | Green category +action_result.data.\*.ccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.ccRecipients.name | string | | Test Domain +action_result.data.\*.changeKey | string | | CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFLoCsS +action_result.data.\*.conversationId | string | | AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQAEU43FQ-fk5LmOxKoTpmHfw= +action_result.data.\*.conversationIndex | string | | AQHWRVB0TS7xy6ZOSEeEl0ahrRHNfQ== +action_result.data.\*.createdDateTime | string | | 2017-10-26T01:31:43Z +action_result.data.\*.endDateTime.dateTime | string | | 2022-07-26T09:30:00.0000000 +action_result.data.\*.endDateTime.timeZone | string | | UTC +action_result.data.\*.event.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFLoCsS" +action_result.data.\*.event.allowNewTimeProposals | boolean | | True False +action_result.data.\*.event.attendees.\*.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.event.attendees.\*.emailAddress.name | string | | Test Name +action_result.data.\*.event.attendees.\*.status.response | string | | none +action_result.data.\*.event.attendees.\*.status.time | string | | 0001-01-01T00:00:00Z +action_result.data.\*.event.attendees.\*.type | string | | required +action_result.data.\*.event.body.content | string | | `plain text?\\r\\n` +action_result.data.\*.event.body.contentType | string | | text +action_result.data.\*.event.bodyPreview | string | | plain text? +action_result.data.\*.event.calendar@odata.associationLink | string | `url` | https://test.abc.com/v1.0/users('test@user.abc.com')/calendars('AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAAAgENAAAA')/$ref +action_result.data.\*.event.calendar@odata.navigationLink | string | `url` | https://test.abc.com/v1.0/users('test@user.abc.com')/calendars('AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAAAgENAAAA') +action_result.data.\*.event.changeKey | string | | CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFQwHj9 +action_result.data.\*.event.createdDateTime | string | | 0001-01-01T00:00:00Z +action_result.data.\*.event.end.dateTime | string | | 0001-01-01T00:00:00.0000000 +action_result.data.\*.event.end.timeZone | string | | UTC +action_result.data.\*.event.hasAttachments | boolean | | True False +action_result.data.\*.event.hideAttendees | boolean | | True False +action_result.data.\*.event.iCalUId | string | | 040000008200E00074C5B7101A82E0080000000074AC2CF9CF5ED8010000000000000000100000005B5B104FC55A6E44BC5C6A093AB7F07C +action_result.data.\*.event.id | string | `msgoffice365 event id` | AAMkAGYwYmE5NmQ0LWVhOGItNGFhMy05OWNlLTE5MzhjMTE5YWYyMQBGAAAAAACkbmmUA5U5RZwZvvg8zew_BwDWyBbuDx-uTKpJ-DXRPByGAAAA1bxhAAAr0tXr3dtaS5qYgFGhi6QjAAQiOoS2AAA= +action_result.data.\*.event.importance | string | | normal +action_result.data.\*.event.isAllDay | boolean | | False True +action_result.data.\*.event.isCancelled | boolean | | True False +action_result.data.\*.event.isDraft | boolean | | True False +action_result.data.\*.event.isOnlineMeeting | boolean | | True False +action_result.data.\*.event.isOrganizer | boolean | | True False +action_result.data.\*.event.isReminderOn | boolean | | True False +action_result.data.\*.event.lastModifiedDateTime | string | | 0001-01-01T00:00:00Z +action_result.data.\*.event.location.displayName | string | | Test +action_result.data.\*.event.location.locationType | string | | default +action_result.data.\*.event.location.uniqueIdType | string | | unknown +action_result.data.\*.event.occurrenceId | string | | +action_result.data.\*.event.onlineMeeting.joinUrl | string | `url` | https://test.abc.com/l/meetup-join/19%3ameeting_ZjViMTdlNjEtZjYxNi00N2QyLWJmOWYtMGU5MjVjMDM3ZTZl%40thread.v2/0?context=%7b%22Tid%22%3a%22a417c578-c7ee-480d-a225-d48057e74df5%22%2c%22Oid%22%3a%22e4c722ac-3b83-478d-8f52-c388885dc30f%22%7d +action_result.data.\*.event.onlineMeetingProvider | string | | teamsForBusiness +action_result.data.\*.event.onlineMeetingUrl | string | | +action_result.data.\*.event.organizer.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.event.organizer.emailAddress.name | string | | Test Name +action_result.data.\*.event.originalEndTimeZone | string | | UTC +action_result.data.\*.event.originalStartTimeZone | string | | UTC +action_result.data.\*.event.recurrence | string | | +action_result.data.\*.event.reminderMinutesBeforeStart | numeric | | 0 +action_result.data.\*.event.responseRequested | boolean | | True False +action_result.data.\*.event.responseStatus.response | string | | accepted +action_result.data.\*.event.responseStatus.time | string | | 0001-01-01T00:00:00Z +action_result.data.\*.event.sensitivity | string | | normal +action_result.data.\*.event.seriesMasterId | string | | +action_result.data.\*.event.showAs | string | | tentative +action_result.data.\*.event.start.dateTime | string | | 0001-01-01T00:00:00.0000000 +action_result.data.\*.event.start.timeZone | string | | UTC +action_result.data.\*.event.subject | string | | Just wanted to say hello +action_result.data.\*.event.transactionId | string | | +action_result.data.\*.event.type | string | | singleInstance +action_result.data.\*.event.webLink | string | `url` | https://test.abc.com/owa?itemid=AAMkAGYwYmE5NmQ0LWVhOGItNGFhMy05OWNlLTE5MzhjMTE5YWYyMQBGAAAAAACkbmmUA5U5RZwZvvg8zew%2BBwDWyBbuDx%2FuTKpJ%2FDXRPByGAAAA1bxhAAAr0tXr3dtaS5qYgFGhi6QjAAQiOoS2AAA%3D&exvsurl=1&path=/calendar/item +action_result.data.\*.flag.flagStatus | string | | notFlagged +action_result.data.\*.from.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.from.emailAddress.name | string | `email` | Test Name +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwABS2DpfAAAAA== +action_result.data.\*.importance | string | | normal +action_result.data.\*.inferenceClassification | string | | focused +action_result.data.\*.internetMessageHeaders.ARC-Authentication-Results | string | | i=1; mx.test.com 1; spf=pass smtp.mailfrom=user.test.com; dmarc=pass action=none header.from=user.abc.com; dkim=pass header.d=test.abc.com; arc=none +action_result.data.\*.internetMessageHeaders.ARC-Message-Signature | string | | i=1; a=rsa-sha256; c=relaxed/relaxed; d=test.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3fZ/7Rn8nzby4BCiwxGpfUUiHgfvSZ6MOHtHg1Hmixs=; b=f7VAkSO/T2NJuxMrJNBzeow/t2iTVZfAkVaZGgtAoYq3Wb9cUDEfAtTE4RmzSqLEqP2iXxLK7JsRfV2uqsbGinp3ZuRnHSqMoRzO0XCN8KjE/Z9hUyUmq05clk2rB3TqCcKK6ipy1+N+4mvCFFb6O+bN/9TGhPos1dY0X0sy33sow9oeND6nm8HvtIzp/hG0xKduPnEHwQiCCwRTmdAtbAzMWmnEyyodRQg/PCgjAPKPpeFELZ+pr/bbEkySxLCu/xY1qhoa8JMIrh1EUFHyFyscTDc580YNnowNqAR//iO8DRGaTG1Znv4MI7mlcmM/vopKYAa6zNPXb2LHDqwKBQ== +action_result.data.\*.internetMessageHeaders.ARC-Seal | string | | i=1; a=rsa-sha256; s=arcselector9901; d=test.com; cv=none; b=GIfa87IhNn+v4Mdn75nJpk9WjELaP8fw9+C+Ey0QFktfU60rPvtJDc5qJS5mN/g6COFa2inOEc4S+Cm3R1BLcBgqkCZR/niPjMp/A2tEHs9OeY75S+T8d5OsfmFcD2jC5/59Dc8EAEKw3UnYKxCC4CKWPFCXrE+Cu3jLEtt04Izr1rXTTQacfCjwYN4OsKI9lHyn6JRDlePR2RZKztMcnt/hcOJz6cwFe+MAUgg0qjKB8p+27o2hQKu+LlQDg8nMRQ6jHkD8DylOclHe2nVKmEhNXi67PTeoqTfZe4+YgSOrnJOUdlra5q/EoWN0FnM9Zt0+0K42ncYSWcC0NpsbqQ== +action_result.data.\*.internetMessageHeaders.Accept-Language | string | | en-US +action_result.data.\*.internetMessageHeaders.Authentication-Results | string | | spf=pass (sender IP is 209.85.210.171) smtp.mailfrom=testdomain.com; .abc.com; dkim=pass (signature was verified) header.d=testdomain.com.20150623.gappssmtp.com;.abc.com; dmarc=pass action=none header.from=testdomain.com;compauth=pass reason=100 +action_result.data.\*.internetMessageHeaders.Authentication-Results-Original | string | | dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=test.abc.com; +action_result.data.\*.internetMessageHeaders.Content-Language | string | | en-US +action_result.data.\*.internetMessageHeaders.Content-Transfer-Encoding | string | | binary +action_result.data.\*.internetMessageHeaders.Content-Type | string | | multipart/related +action_result.data.\*.internetMessageHeaders.DKIM-Signature | string | | v=1; a=rsa-sha256; c=relaxed/relaxed; d=testdomain.com.20150623.gappssmtp.com; s=20150623; h=message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=avAAeJ8jF08K4oIBhxTirRmyB+SXHwdU0zdxv7eqs/zWaWWcgmT0007KP560TTgo5u oD4nb6TvKxpRyWW4QwmkbuMIwHsMvehd2l1gispV3AawyGJjpmN7ErVYfLtIkz2Tap3V YxmluV+SqeyyxTU8pFAEZ7+2C2lOb1DO5TC7xCMv+dyzevSscJdbeN0dFkG+C93zCqkg w2fxubx2HDD7b/U6m2wXllYhH608wKJ/qYzyvQyqxYqNiQOtPRg2gw4sZ2UgN3+UQyVq 8ubO39ZuqakJpzEzYMw10d6E7SQhvHDJH7mFwhBlzhvOpb2gLJDN8n8dJaZo05BozQqq MsvA== +action_result.data.\*.internetMessageHeaders.Date | string | | Thu, 18 Jun 2020 02:11:26 -0700 +action_result.data.\*.internetMessageHeaders.From | string | | "Test" +action_result.data.\*.internetMessageHeaders.In-Reply-To | string | | +action_result.data.\*.internetMessageHeaders.MIME-Version | string | | 1.0 +action_result.data.\*.internetMessageHeaders.Message-ID | string | | <5eeb2fbe.1c69fb81.22b4b.676a@mx.test.com> +action_result.data.\*.internetMessageHeaders.Received | string | | from localhost.localdomain (host-240.test.com. [204.107.141.240]) by test.abc.com with UTF8SMTPSA id ng12sm1923252pjb.15.2020.06.18.02.11.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jun 2020 02:11:26 -0700 (PDT) +action_result.data.\*.internetMessageHeaders.Received-SPF | string | | Pass (protection.test.com: domain of testdomain.com designates 209.85.210.171 as permitted sender) receiver=protection.test.com; client-ip=209.85.210.171; helo=mail-pf1-f171.test.com; +action_result.data.\*.internetMessageHeaders.References | string | | +action_result.data.\*.internetMessageHeaders.Return-Path | string | `email` | notifications@testdomain.com +action_result.data.\*.internetMessageHeaders.Subject | string | | Fw: Email having different attachments +action_result.data.\*.internetMessageHeaders.Thread-Index | string | | AQDEZLqyXR4k4Sc6skyFCMPITcMsbKpGS7At +action_result.data.\*.internetMessageHeaders.Thread-Topic | string | | Email having different attachments +action_result.data.\*.internetMessageHeaders.To | string | | "Test" +action_result.data.\*.internetMessageHeaders.X-EOPAttributedMessage | string | | 0 +action_result.data.\*.internetMessageHeaders.X-EOPTenantAttributedMessage | string | | a417c578-c7ee-480d-a225-d48057e74df5:0 +action_result.data.\*.internetMessageHeaders.X-Forefront-Antispam-Report | string | | CIP:209.85.210.171;CTRY:US;LANG:en;SCL:-1;SRV:;IPV:NLI;SFV:SFE;H:mail-pf1-f171.test.com;PTR:mail-pf1-f171.test.com;CAT:NONE;SFTY:;SFS:;DIR:INB;SFP:; +action_result.data.\*.internetMessageHeaders.X-Forefront-Antispam-Report-Untrusted | string | | CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BYAPR18MB2408.namprd18.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(136003)(396003)(346002)(39830400003)(376002)(366004)(186003)(83380400001)(64756008)(76116006)(66946007)(71200400001)(8676002)(66476007)(66446008)(66556008)(6916009)(55016003)(91956017)(9686003)(41300700001)(6506007)(7696005)(26005)(2906002)(33656002)(38070700005)(86362001)(38100700002)(3480700007)(122000001)(5660300002)(4744005)(316002)(296002)(166002)(478600001)(8936002)(52536014);DIR:OUT;SFP:1102; +action_result.data.\*.internetMessageHeaders.X-Gm-Message-State | string | | AOAM533ynFERIhSIewEEkj4b8B1rPNOEeie1IxBdrd55treEMtBa1jkL cO5ee4Ff6p0FYedfFtVtHKiCglGTpFTOSw== +action_result.data.\*.internetMessageHeaders.X-Google-DKIM-Signature | string | | v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=fPT47NIiheeY6GM0bxUOlsmnOgN4WuiOlalFvZqrAiFiOoYk6zrznvgIcAtiHZ4nxE naQAa+mZs5svqRjib3YI52OvR5U8MitIYaa0Rt3LyYSUO1s3iKTUs4nHyRnqPt1skNl7 2OUwsZPXo3ShJDw/uxZRu/cuN1iIfeuE02PrbR04p4D8+1XRslqt/Xqm/bOWKUauqZWe dH1E7meFY01hXxODreO4nWHIhsZgr49TpP/OqRyFcyKHHFFg2sPGXz+QNah6jP4YQUYd Tty2wzOX3nc/YS7TkVo3ORmbzh9o+UZaqH8wHbQlyTdklYxoMPvJwZTo72rTxZeqiJ9E J7PQ== +action_result.data.\*.internetMessageHeaders.X-Google-Smtp-Source | string | | ABdhPJxrYC7raBubCCIOmauxmxryzS9KsihTN6XCRgaNp2rDrG71TVxryzYCtelFOZ2Xj1LzcYIiMA== +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData | string | | VSM9HTzub/OH3NCwWNKQqkkzjnhdw5kXsgd9WM0SRgZ0qRdPg5D9/o3LA7lf8ziXc5k0mm9M5mHvFoYePXNXs/MGhGdBGxa/qUQ+FVHA2mDgfPkamJCEZxz//OX/uruTDo+zF4p9D1dQJpnIpx1M75OhuvrHX/BxWWzyAh78DXfF214YHdyFBCYepwl56CS7+fSGQL/r3p+OvWIBnIkISC+HJljSro2k47pPPAkspMhoUkb+zklyENFjez+JcEHYlih2FiNeUO8kb9b7qvlm3zPK98HLspzDh4BojpQ6Ff330iy7nfIK726tCMByxjOdnEQSB9Ua2sbE5gxSeeWL8MB5DHcQSSsXg+sR8w4gXrXLO3meE0lNQKRoAv2b1U0Q+yM0QBqeQWlymZG21bKeuH4gtAFQvfXNjoCtIbBQK1n7ZnL7fI21FJZRcMcKEneus6gLYUqD4PdLEq9FEGbfgiLmVYeUAL2A0Q/gectvL1OVudtHVR5gFMJKt65F1OtS04CPulfLLFSl1F4AzpjjtBSyQcK9R7bOsjoHxQXPMd9fMCzMSIq5f551pO0klKqWY7l11Un2Noj6CA7EtXiD1bTv8JmYQEKR+0HTZagNd+79GeTvKjxTvt9MkyO8k3aqWyNqT331ITnVICtksN1TVMCp8GVeDudNMr2PLSW0alOduR5unuEgTWrqHoaTGOovQx0PVjudNlpZ80ANK9hqaC/ZhLLOtNpJ3fZnjs06PzrPLGhE/IeccY1n8sYDvGm1QA9TN6JaaGPl1Pj6ecy16k0XuF/PKGHTL0M4LCpxSS6T87oFFH1zHkKtmbJp3aAI4bt3ihbQmwFb29JyMgL7ZOy+zrIwXGILh1KQGWQQv1uXXnAuqQy29HeFXs6D2hDHxHlBk5ZQ+vgRtsvRvGnq58vJ3CapjntfL3pOINUj1avLyAZxjasBWMTwaZs9JQ4ZIMekzkIk05lh9XfDSeULk2yKaH8YSCC6ENUHxSWa6pPHJfOdp9kXwOtlp09/VTTAikKy862k9ybN4bRWZB45B9Pv5scna8IX3rthIXUih8c= +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData-Original-0 | string | | SC/7FB9jcHrfqMtL+8C1Sp2MBDl48qjRn/ZzFJk8+2yWs9kmQwzxXC8TA3HuU0EMts58S8uTyFbx12+qQUJ45/B5QFEfP5j1o7B5kj1Q0C9S+LAg6YptTwxi29Ei1T4mf+CpfzIeA73NzXB7pWjnmycYYlL3TAn0xJATthWspUZ+g4jZoDzNSIdAZWqoc1j4+dHA6WR+U9zZi0vODxRmplSWq2FeO8uMKqD43StpvYk6chxcaGGc5+rNRxP6RLF7OLirJ0MQ1FfZNRdNfUKBvGAF2r6HLp62apGZg0d5gJ5M7zg/1V4ygWW19cuGXyAr5b9bow1MPIOBfrDrMS3CBk2F9DfATTZ/oFwOv/hCUVs2MkWSdr/upJfPt0xoAYtXk1UjxKpV/nHgTTfQy/ijlxEsYn/HY9O6tfqvn/BRvehvPjjoouvxcZteyP1glEcajum7Op67/kV9p4Wv+U+A+31/kyrb3Tjt4GJGpTIBfLi/VjIiHUDFrpAcBz3rFqxyfKQcCqDsOMjD5CrxBj3ow7uMlQiaQoU0Dxwc4eDggbe9Af/F3YqZuvqpj2H0U0hm7+7j56WjFxewVKHLJBwkCXG6a8UdEmKBtA685mUbfpICdYaoLatC4LYOMeqsx6CeEr75vyfdqTdKOZrBKkhTluMbR0s1pvh0kID7B+HL/LKqFSnpgQidfIugk5FUSh42vsBUjrxq6LWYDSHWwYweeuZi/6vVgKQl1XS5X7JUhwNxZSzSF76pNeCIq6KGlCmfIrAnAAhfd0a0xMGy/gOJiqM8JcWjnCMA25UrRL2XrMLC4mnLpi71rATOU62rcgNyczpKI74uHEQAGtQBHfoJjuAqK1JNAK5+j1kIT9gr1F0CC2iJ+68DOI+dveK2lkGqyNYx+eKeTjJSKO4bfzQiM0oBg9eIwqtU3Wn+sSQEg74MzrMjEfaorXh7X+LdO4DwA7dNyEurnYEgmjvjJoNbcxgjhbLSkTe3LFAX7iUia79VIqgD80bxgwoCWyKiSiCKARb/krBWOCOOuF1I6v6azxPHpwsQxC6AvFlOWW7BXsFY9NcCeGvV7l+9ZnLuRjdbjrgdk1b7PRv6aaRzmVk1I3KPBCPvFasP2XhNJXGgYmv7hxiyOci1Eoq4QcXEfr9VsrOEkcl0z4HI8yHx354Lc7Peck8XFvGCe9ElyhxmEtu/ySFQ3BOakjPikOOIA4XlUj3GsUk8qfwnePHVPBnKKm0jtaqjK6tA8uZyKG8jTNgICFZ9wKmsijFMPXVY2lt5zuPnw1V31D//IYjdXpcU1cMfXgZ06vld4anBSEv3WL3zCZaIJsRhxkB7ixumw4h5yieKNJFIVhbV6Ty4Yog9JFmQbAbRfKh1b8ltoym804+hOH8n7oWVqSbtzuylg7DPCIVOcWdUNraXYgmgtXDM6vq0SsDK1j2diz4ywM2BlBSsnCyAdt1NN5gZyMfOufZ3a8SKdwTaRH3bFh6BmfLEZ8NgYbeJQX7GrVbBU5kHT9+k2g3Klchapmqv8mzl0uKvX1av2hW6ce5xo+owa9Qk/Gza4j4o74bVl8tJ/iYClX4kpHY6kek/TOA/Sxj/IvWb1QZvpgmj0LNNCrLdrLUiTDG3lodE9j+Lr8qhmgL8S78= +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData-Original-ChunkCount | string | | 1 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthAs | string | | Internal +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthSource | string | | SJ0PR22MB4941.namprd11.prod.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-FromEntityHeader | string | | Internet +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Id | string | | a417c578-c7ee-480d-a225-d48057e74df5 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-MailboxType | string | | HOSTED +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Network-Message-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-OriginalArrivalTime | string | | 18 Jun 2020 09:11:28.2511 (UTC) +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-UserPrincipalName | string | | bs91VnpEPjrqCnvlIeymwO6ye5P9rggHggVNUPUbV/tC9uuFPVFOYg7e/Cd0MeGmSqT4AlLW0Nn4ZeEqNieSf/D1gp5iLz/YkwjXhYUSJnLRb/csQN4sRMMZsX3LUkKkwVpifaeJzoukLu8qSWn7og== +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthAs | string | | Anonymous +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthMechanism | string | | 04 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthSource | string | | DM6NAM11FT055.eop-nam11.prod.protection.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationInterval | string | | 1:00:00:00.0000000 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationIntervalReason | string | | OriginalSubmit +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTime | string | | 18 Jun 2020 09:11:28.2531 (UTC) +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTimeReason | string | | OriginalSubmit +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-MessageDirectionality | string | | Incoming +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-Network-Message-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-SCL | string | | -1 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Processed-By-BccFoldering | string | | 15.20.3109.017 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersPromoted | string | | DM6NAM11FT064.eop-nam11.prod.protection.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersStamped | string | | BN6PR18MB1492 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersStripped | string | | DM6NAM11FT064.eop-nam11.prod.protection.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-EndToEndLatency | string | | 00:00:02.7417647 +action_result.data.\*.internetMessageHeaders.X-MS-Has-Attach | string | | yes +action_result.data.\*.internetMessageHeaders.X-MS-Office365-Filtering-Correlation-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Office365-Filtering-Correlation-Id-Prvs | string | | 0c3038e5-2c60-453b-188f-08da6ed1ea0c +action_result.data.\*.internetMessageHeaders.X-MS-Oob-TLC-OOBClassifiers | string | | OLM:1728; +action_result.data.\*.internetMessageHeaders.X-MS-PublicTrafficType | string | | Email +action_result.data.\*.internetMessageHeaders.X-MS-TNEF-Correlator | string | | +action_result.data.\*.internetMessageHeaders.X-MS-TrafficTypeDiagnostic | string | | BN6PR18MB1492: +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam | string | | BCL:0; +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Mailbox-Delivery | string | | wl:1;pcwl:1;ucf:0;jmr:0;auth:0;dest:I;ENG:(750128)(520011016)(520004050)(702028)(944506458)(944626604); +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Message-Info | string | | La+CSxAnpzVJOXq7njrFPhIbsh0khleSwldy+W8NYDRsoyyPruPIiId4Avama7JyfzrxoExzhLk5pDn2lGPAJIpdcguiDSsDQg5T+iBCJgFeaEJXjhstECMi842/JGawB9WsiGw9Q/PpvjO5H/2fNLlQZVZW3AAQVZSsX3az4iOsv1Ggj4aYZRMKHmPAtniWOEtQD7zAEWC0jIZf613lWy3vxHfb/3+pV9X8zqPqazbyGy5Q14PICSNkKnvIw8rmeqJV8eSHhvR51Lchib6OIN4xOpLWxkSkBTt5B95RUPnpgPvgp2yLo0Q+EYRIabLDQ0kMsv+24+RnFmr9vo2gRNuFusw8iEPsVEQyhfgIWtBtsBpyvyykxcfa6lIdzQhixZH3Tlkdh1kb15wFS3Ooz3CjaWbY8jcUot5l1p08Ypsj6r7CpIo3xE6jE0x/EeUkDK3Fu/Ol0pOsJ1N5W4iJLdjqSQM3l/t9QWlcPhD8s6D7D7JM5OUHCeFEPr7sSL+P/5zTgBaeUvwtZrlQSH2GHc+5gPW8rkwlwJLJftVEid0gO2PUOrzItzME5PXYAcdx++sF3XC1YMPLet/jMpX8T7/z7+hxFxNyifgmGJ+DkNOec7yGkkcLBz6iCaHx7OrRGwDHIcdAtV85wCk3NEDDiKyHivQpwp/gY55W+wkLe7aqSHmFzm1rUSslx+DWz8w2EgSjJxOmf0JkoNKbTFl3FObkocR0lUUQUnETuoAXUqvpWGD5B69W9XXUM8c43ozz2oBZseheSAtkLil3tMIr/CMCMILPX/LdoErNtkmiFXCPqaLFSSeyO61oCMl6Ezndtwp22nwMPUg5ofG0kdqFuTW122umhy9C6h5BcREaLhWclSyqDoZPB9RvkRlI2kTRwuwbuFW3iOMzmVwxLIQH9K5JkxdMvC3hvNpjVgz7Q2ZnEF3xSNqeoWVQvkaIe8rQLUc8s+HMRUmSERGdfSuQJAx47g8PDs9s3rS/ThUSzIaljJPbUgXEnFg/G6h3I/yXLj2Nj2OG50snoI5jJmE4+69YmNwasdDZuYpnuQeFgu11HtsLniDthJdjEJyYC1utZNt9hgA+6JlLnm7Dxb43cSIiW8ev+3X+b2kREj2k/m8fSz7YgtoCB8AkuiVXRaH3EUiq8XCExbbWeynKRgwCZ6bzvfSiT3+cg+QQKPHFc/cgot56ta6X80tjhFodpTQNTE6V6C9QFHJ3JCVhsSzVifJAc8crI5hAcPbKFEIjinENcfpF/8reo2Yr1xFElhoX +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Message-Info-Original | string | | MTrWp0GiNTxQrZWPlJ6veyKekVjJA0FKYcYQlNCKCrjhAtIn4oDZCbWPNm21Zr7mX+CXhspXNSQSEjpIERhcHIWABmuzCF/vnMr0xwLTzuh2T0si6wgTdha+BdCpnx/kvbN+TMK3rCmD9ro6qHf/v1dTbLKJUZ3Cwfl+LoqJLCkw+T8E7/De1QBlCJrKVGfSztXncKPdvPxC2Qjw/QoPmYp7oFbqW8uwNZX1q8HmAXfLzYPeOuLDE/h4s61EeZGvIY7nBMwm6DwKdTqfmQqy3+BTMfoTaN/82aHLgfBI8V0NbiPVvbKbUU8UOusHZM5H6pzOpZFOSsS7yWz1jpIvKK5CJtNUK5XkOCLxv06yzbWib2abzwEhoLUBHYhJGnwNaIznz/C7a6vZLPe1hNxyLBv0/SyYmt1m9v0vB3TSdSH2V+Ork2OK5nz/r1KcOScedjs14GZpifgjEXiIhK4eJlTkI8LE7HnqXr+82C39t13fqV8L8oRYjGiJJE9wpGJIhMa4PQYwgP0D2cQGrVwuVK2qP01TsSE+NWOXyB8hAYn11K/wCnq4TqtwRbptF9aiw0k45eDHfvB/sBARv37sajixtW4QuFQ3eYI9bVVfllmcpnKj5VUD1mdMAnkgpOCiQSEiSI6Tlo9cEycBulSc4fmocQoev7eUTFw43FDjmRpebuNF0lmm7OcvXgS8jBJSzkbLPrrsqTj1fluowoLjQTQsSPn/LK5LdOdCt7x70/BaweDCm9VdcGgh5Mqe0Qp4GxnBSpS61OCmDYZEkCL5W1A+M7Ah9mANYucdydHU9bLxJBcoi42VIDK6oYaKs3oobr0k1M/dk/pjDT65LuHwsA== +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Untrusted | string | | BCL:0; +action_result.data.\*.internetMessageHeaders.X-Originating-IP | string | | [5.38.181.162] +action_result.data.\*.internetMessageHeaders.X-Received | string | | by 2002:aa7:84d9:: with SMTP id x25mr2807688pfn.300.1592471487394; Thu, 18 Jun 2020 02:11:27 -0700 (PDT) +action_result.data.\*.internetMessageHeaders.subject | string | | test html +action_result.data.\*.internetMessageHeaders.x-ms-exchange-antispam-relay | string | | 0 +action_result.data.\*.internetMessageHeaders.x-ms-exchange-calendar-series-instance-id | string | | BAAAAIIA4AB0xbcQGoLgCAAAAAAhGy3GuqDYAQAAAAAAAAAAEAAAAMqUNBGdAN9NtAV6x5ZM9JU= +action_result.data.\*.internetMessageHeaders.x-ms-exchange-senderadcheck | string | | 1 +action_result.data.\*.internetMessageHeaders.x-ms-traffictypediagnostic | string | | BYAPR18MB2408:EE_MeetingMessage|BL1PR18MB4325:EE_MeetingMessage|DM6NAM11FT064:EE_|CH0PR11MB5427:EE_ +action_result.data.\*.internetMessageId | string | `msgoffice365 internet message id` | +action_result.data.\*.isAllDay | boolean | | True False +action_result.data.\*.isDelegated | boolean | | True False +action_result.data.\*.isDeliveryReceiptRequested | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isOutOfDate | boolean | | True False +action_result.data.\*.isRead | boolean | | True False +action_result.data.\*.isReadReceiptRequested | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2017-10-26T01:31:43Z +action_result.data.\*.meetingMessageType | string | | meetingRequest +action_result.data.\*.meetingRequestType | string | | newMeetingRequest +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAA +action_result.data.\*.previousEndDateTime | string | | +action_result.data.\*.previousEndDateTime.dateTime | string | | 2022-05-09T13:30:00.0000000 +action_result.data.\*.previousEndDateTime.timeZone | string | | UTC +action_result.data.\*.previousLocation | string | | +action_result.data.\*.previousStartDateTime | string | | +action_result.data.\*.previousStartDateTime.dateTime | string | | 2022-05-09T13:00:00.0000000 +action_result.data.\*.previousStartDateTime.timeZone | string | | UTC +action_result.data.\*.receivedDateTime | string | | 2017-10-26T01:31:43Z +action_result.data.\*.recurrence | string | | +action_result.data.\*.replyTo | string | | +action_result.data.\*.responseRequested | boolean | | True False +action_result.data.\*.sender.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.sender.emailAddress.name | string | `email` | Test Name +action_result.data.\*.sentDateTime | string | | 2017-10-26T01:31:35Z +action_result.data.\*.startDateTime.dateTime | string | | 2022-07-26T09:00:00.0000000 +action_result.data.\*.startDateTime.timeZone | string | | UTC +action_result.data.\*.subject | string | `msgoffice365 subject` | more attachments +action_result.data.\*.toRecipients.\*.emailAddress.address | string | `email` | Test@testdomain.abc.com +action_result.data.\*.toRecipients.\*.emailAddress.name | string | | Test Name +action_result.data.\*.type | string | | singleInstance +action_result.data.\*.vaultId | string | | ff89bab9ec1e063a0f100aa7b0ac5fbc7425ab22 +action_result.data.\*.webLink | string | `url` | https://outlook.office365.com/owa/?ItemID=AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0%2BMMHKonvdoWQcAQSl1b8BFiEmbqZql%2BJiUtwAAAgEMAAAAQSl1b8BFiEmbqZql%2BJiUtwABS2DpfAAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem +action_result.summary | string | | +action_result.message | string | | Successfully fetched email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'get email properties' -Get non\-standard email properties from the server +Get non-standard email properties from the server Type: **investigate** Read only: **True** -For a list of possible properties to retrieve, visit https\://docs\.microsoft\.com/en\-us/graph/api/message\-get?view=graph\-rest\-1\.0&tabs=http\. +For a list of possible properties to retrieve, visit https://docs.microsoft.com/en-us/graph/api/message-get?view=graph-rest-1.0&tabs=http. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- **id** | required | Message ID to get properties of | string | `msgoffice365 message id` -**email\_address** | required | Email address of the mailbox owner | string | `email` -**get\_headers** | optional | Get email headers | boolean | -**get\_body** | optional | Get email body | boolean | -**get\_unique\_body** | optional | Get unique email body | boolean | -**get\_sender** | optional | Get email sender | boolean | -**properties\_list** | optional | Other properties to get \(comma\-separated list\) | string | +**email_address** | required | Email address of the mailbox owner | string | `email` +**get_headers** | optional | Get email headers | boolean | +**get_body** | optional | Get email body | boolean | +**get_unique_body** | optional | Get unique email body | boolean | +**get_sender** | optional | Get email sender | boolean | +**properties_list** | optional | Other properties to get (comma-separated list) | string | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.get\_body | boolean | -action\_result\.parameter\.get\_headers | boolean | -action\_result\.parameter\.get\_sender | boolean | -action\_result\.parameter\.get\_unique\_body | boolean | -action\_result\.parameter\.id | string | `msgoffice365 message id` -action\_result\.parameter\.properties\_list | string | -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.id | string | -action\_result\.data\.\*\.internetMessageHeaders\.Accept\-Language | string | -action\_result\.data\.\*\.internetMessageHeaders\.Authentication\-Results | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Language | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Transfer\-Encoding | string | -action\_result\.data\.\*\.internetMessageHeaders\.Content\-Type | string | -action\_result\.data\.\*\.internetMessageHeaders\.DKIM\-Signature | string | -action\_result\.data\.\*\.internetMessageHeaders\.Date | string | -action\_result\.data\.\*\.internetMessageHeaders\.From | string | -action\_result\.data\.\*\.internetMessageHeaders\.In\-Reply\-To | string | -action\_result\.data\.\*\.internetMessageHeaders\.MIME\-Version | string | -action\_result\.data\.\*\.internetMessageHeaders\.Message\-ID | string | -action\_result\.data\.\*\.internetMessageHeaders\.Received | string | -action\_result\.data\.\*\.internetMessageHeaders\.Received\-SPF | string | -action\_result\.data\.\*\.internetMessageHeaders\.References | string | -action\_result\.data\.\*\.internetMessageHeaders\.Return\-Path | string | `email` -action\_result\.data\.\*\.internetMessageHeaders\.Subject | string | -action\_result\.data\.\*\.internetMessageHeaders\.Thread\-Index | string | -action\_result\.data\.\*\.internetMessageHeaders\.Thread\-Topic | string | -action\_result\.data\.\*\.internetMessageHeaders\.To | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-EOPAttributedMessage | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-EOPTenantAttributedMessage | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Forefront\-Antispam\-Report | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Gm\-Message\-State | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Google\-DKIM\-Signature | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Google\-Smtp\-Source | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-AntiSpam\-MessageData | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-AuthAs | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-AuthSource | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-FromEntityHeader | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-MailboxType | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-Network\-Message\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-OriginalArrivalTime | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-CrossTenant\-UserPrincipalName | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthAs | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthMechanism | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-AuthSource | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationInterval | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationIntervalReason | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationStartTime | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-ExpirationStartTimeReason | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-MessageDirectionality | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-Network\-Message\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Organization\-SCL | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Processed\-By\-BccFoldering | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-CrossTenantHeadersStamped | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Exchange\-Transport\-EndToEndLatency | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Has\-Attach | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Office365\-Filtering\-Correlation\-Id | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-Oob\-TLC\-OOBClassifiers | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-PublicTrafficType | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-TNEF\-Correlator | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-MS\-TrafficTypeDiagnostic | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Mailbox\-Delivery | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Microsoft\-Antispam\-Message\-Info | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Originating\-IP | string | -action\_result\.data\.\*\.internetMessageHeaders\.X\-Received | string | -action\_result\.data\.\*\.internetMessageHeaders\.subject | string | -action\_result\.data\.\*\.receivedDateTime | string | -action\_result\.data\.\*\.sender\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.sender\.emailAddress\.name | string | `email` -action\_result\.data\.\*\.subject | string | -action\_result\.data\.\*\.uniqueBody\.content | string | -action\_result\.data\.\*\.uniqueBody\.contentType | string | -action\_result\.summary | string | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | user@abc.com +action_result.parameter.get_body | boolean | | True False +action_result.parameter.get_headers | boolean | | True False +action_result.parameter.get_sender | boolean | | True False +action_result.parameter.get_unique_body | boolean | | True False +action_result.parameter.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA== +action_result.parameter.properties_list | string | | subject,receivedDateTime +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#users('user%40.abc.com')/messages(internetMessageHeaders,body,uniqueBody,sender,subject)/$entity +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAO8DBJl" +action_result.data.\*.body.content | string | | `\\r\\n

HTML heading

HTML body.` +action_result.data.\*.body.contentType | string | | html +action_result.data.\*.id | string | | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA== +action_result.data.\*.internetMessageHeaders.Accept-Language | string | | en-US +action_result.data.\*.internetMessageHeaders.Authentication-Results | string | | spf=pass (sender IP is 209.85.210.171) smtp.mailfrom=testdomain.com; .abc.com; dkim=pass (signature was verified) header.d=testdomain.com.20150623.gappssmtp.com;.abc.com; dmarc=pass action=none header.from=testdomain.com;compauth=pass reason=100 +action_result.data.\*.internetMessageHeaders.Content-Language | string | | en-US +action_result.data.\*.internetMessageHeaders.Content-Transfer-Encoding | string | | binary +action_result.data.\*.internetMessageHeaders.Content-Type | string | | multipart/related +action_result.data.\*.internetMessageHeaders.DKIM-Signature | string | | v=1; a=rsa-sha256; c=relaxed/relaxed; d=testdomain.com.20150623.gappssmtp.com; s=20150623; h=message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=avAAeJ8jF08K4oIBhxTirRmyB+SXHwdU0zdxv7eqs/zWaWWcgmT0007KP560TTgo5u oD4nb6TvKxpRyWW4QwmkbuMIwHsMvehd2l1gispV3AawyGJjpmN7ErVYfLtIkz2Tap3V YxmluV+SqeyyxTU8pFAEZ7+2C2lOb1DO5TC7xCMv+dyzevSscJdbeN0dFkG+C93zCqkg w2fxubx2HDD7b/U6m2wXllYhH608wKJ/qYzyvQyqxYqNiQOtPRg2gw4sZ2UgN3+UQyVq 8ubO39ZuqakJpzEzYMw10d6E7SQhvHDJH7mFwhBlzhvOpb2gLJDN8n8dJaZo05BozQqq MsvA== +action_result.data.\*.internetMessageHeaders.Date | string | | Thu, 18 Jun 2020 02:11:26 -0700 +action_result.data.\*.internetMessageHeaders.From | string | | "Test" +action_result.data.\*.internetMessageHeaders.In-Reply-To | string | | +action_result.data.\*.internetMessageHeaders.MIME-Version | string | | 1.0 +action_result.data.\*.internetMessageHeaders.Message-ID | string | | <5eeb2fbe.1c69fb81.22b4b.676a@mx.test.com> +action_result.data.\*.internetMessageHeaders.Received | string | | from localhost.localdomain (host-240.test.com. [204.107.141.240]) by tset.abc.com with UTF8SMTPSA id ng12sm1923252pjb.15.2020.06.18.02.11.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jun 2020 02:11:26 -0700 (PDT) +action_result.data.\*.internetMessageHeaders.Received-SPF | string | | Pass (protection.test.com: domain of testdomain.com designates 209.85.210.171 as permitted sender) receiver=protection.test.com; client-ip=209.85.210.171; helo=mail-pf1-f171.test.com; +action_result.data.\*.internetMessageHeaders.References | string | | +action_result.data.\*.internetMessageHeaders.Return-Path | string | `email` | notifications@testdomain.com +action_result.data.\*.internetMessageHeaders.Subject | string | | Fw: Email having different attachments +action_result.data.\*.internetMessageHeaders.Thread-Index | string | | AQHWZLqyXR4k4Sc6skyFCMPITcMsbKpGS7Bm +action_result.data.\*.internetMessageHeaders.Thread-Topic | string | | Email having different attachments +action_result.data.\*.internetMessageHeaders.To | string | | "Test" +action_result.data.\*.internetMessageHeaders.X-EOPAttributedMessage | string | | 0 +action_result.data.\*.internetMessageHeaders.X-EOPTenantAttributedMessage | string | | a417c578-c7ee-480d-a225-d48057e74df5:0 +action_result.data.\*.internetMessageHeaders.X-Forefront-Antispam-Report | string | | CIP:209.85.210.171;CTRY:US;LANG:en;SCL:-1;SRV:;IPV:NLI;SFV:SFE;H:mail-pf1-f171.test.com;PTR:mail-pf1-f171.test.com;CAT:NONE;SFTY:;SFS:;DIR:INB;SFP:; +action_result.data.\*.internetMessageHeaders.X-Gm-Message-State | string | | AOAM533ynFERIhSIewEEkj4b8B1rPNOEeie1IxBdrd55treEMtBa1jkL cO5ee4Ff6p0FYedfFtVtHKiCglGTpFTOSw== +action_result.data.\*.internetMessageHeaders.X-Google-DKIM-Signature | string | | v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=fPT47NIiheeY6GM0bxUOlsmnOgN4WuiOlalFvZqrAiFiOoYk6zrznvgIcAtiHZ4nxE naQAa+mZs5svqRjib3YI52OvR5U8MitIYaa0Rt3LyYSUO1s3iKTUs4nHyRnqPt1skNl7 2OUwsZPXo3ShJDw/uxZRu/cuN1iIfeuE02PrbR04p4D8+1XRslqt/Xqm/bOWKUauqZWe dH1E7meFY01hXxODreO4nWHIhsZgr49TpP/OqRyFcyKHHFFg2sPGXz+QNah6jP4YQUYd Tty2wzOX3nc/YS7TkVo3ORmbzh9o+UZaqH8wHbQlyTdklYxoMPvJwZTo72rTxZeqiJ9E J7PQ== +action_result.data.\*.internetMessageHeaders.X-Google-Smtp-Source | string | | ABdhPJxrYC7raBubCCIOmauxmxryzS9KsihTN6XCRgaNp2rDrG71TVxryzYCtelFOZ2Xj1LzcYIiMA== +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData | string | | VSM9HTzub/OH3NCwKXEQqkkzjnhdw5kXsgd9WM0SRgZ0qRdPg5D9/o3LA7lf8ziXc5k0mm9M5mHvFoYePXNXs/MGhGdBGxa/qUQ+FVHA2mDgfPkamJCEZxz//OX/uruTDo+zF4p9D1dQJpnIpx1M75OhuvrHX/BxWWzyAh78DXfF214YHdyFBCYepwl56CS7+fSGQL/r3p+OvWIBnIkISC+HJljSro2k47pPPAkspMhoUkb+zklyENFjez+JcEHYlih2FiNeUO8kb9b7qvlm3zPK98HLspzDh4BojpQ6Ff330iy7nfIK726tCMByxjOdnEQSB9Ua2sbE5gxSeeWL8MB5DHcQSSsXg+sR8w4gXrXLO3meE0lNQKRoAv2b1U0Q+yM0QBqeQWlymZG21bKeuH4gtAFQvfXNjoCtIbBQK1n7ZnL7fI21FJZRcMcKEneus6gLYUqD4PdLEq9FEGbfgiLmVYeUAL2A0Q/gectvL1OVudtHVR5gFMJKt65F1OtS04CPulfLLFSl1F4AzpjjtBSyQcK9R7bOsjoHxQXPMd9fMCzMSIq5f551pO0klKqWY7l11Un2Noj6CA7EtXiD1bTv8JmYQEKR+0HTZagNd+79GeTvKjxTvt9MkyO8k3aqWyNqT331ITnVICtksN1TVMCp8GVeDudNMr2PLSW0alOduR5unuEgTWrqHoaTGOovQx0PVjudNlpZ80ANK9hqaC/ZhLLOtNpJ3fZnjs06PzrPLGhE/IeccY1n8sYDvGm1QA9TN6JaaGPl1Pj6ecy16k0XuF/PKGHTL0M4LCpxSS6T87oFFH1zHkKtmbJp3aAI4bt3ihbQmwFb29JyMgL7ZOy+zrIwXGILh1KQGWQQv1uXXnAuqQy29HeFXs6D2hDHxHlBk5ZQ+vgRtsvRvGnq58vJ3CapjntfL3pOINUj1avLyAZxjasBWMTwaZs9JQ4ZIMekzkIk05lh9XfDSeULk2yKaH8YSCC6ENUHxSWa6pPHJfOdp9kXwOtlp09/VTTAikKy862k9ybN4bRWZB45B9Pv5scna8IX3rthIXUih8c= +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthAs | string | | Internal +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthSource | string | | SJ0QA11MB4941.namprd11.prod.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-FromEntityHeader | string | | Internet +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Id | string | | a417c578-c7ee-480d-a225-d48057e74df5 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-MailboxType | string | | HOSTED +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Network-Message-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-OriginalArrivalTime | string | | 18 Jun 2020 09:11:28.2511 (UTC) +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-CrossTenant-UserPrincipalName | string | | bs91VnpEPjrqCnvlIeymwO6ye4Q8rggHggVNUPUbV/tC9uuFPVFOYg7e/Cd0MeGmSqT4AlLW0Nn4ZeEqNieSf/D1gp5iLz/YkwjXhYUSJnLRb/csQN4sRMMZsX3LUkKkwVpifaeJzoukLu8qSWn7og== +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthAs | string | | Anonymous +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthMechanism | string | | 04 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-AuthSource | string | | DM6NAM11FT055.eop-nam11.prod.protection.outlook.com +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationInterval | string | | 1:00:00:00.0000000 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationIntervalReason | string | | OriginalSubmit +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTime | string | | 18 Jun 2020 09:11:28.2531 (UTC) +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTimeReason | string | | OriginalSubmit +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-MessageDirectionality | string | | Incoming +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-Network-Message-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Organization-SCL | string | | -1 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Processed-By-BccFoldering | string | | 15.20.3109.017 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersStamped | string | | BN6PR18MB1492 +action_result.data.\*.internetMessageHeaders.X-MS-Exchange-Transport-EndToEndLatency | string | | 00:00:02.7417647 +action_result.data.\*.internetMessageHeaders.X-MS-Has-Attach | string | | yes +action_result.data.\*.internetMessageHeaders.X-MS-Office365-Filtering-Correlation-Id | string | | 4b1ef179-4fe7-4248-7ec0-08d81367956e +action_result.data.\*.internetMessageHeaders.X-MS-Oob-TLC-OOBClassifiers | string | | OLM:1728; +action_result.data.\*.internetMessageHeaders.X-MS-PublicTrafficType | string | | Email +action_result.data.\*.internetMessageHeaders.X-MS-TNEF-Correlator | string | | +action_result.data.\*.internetMessageHeaders.X-MS-TrafficTypeDiagnostic | string | | BN6PR18MB1492: +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam | string | | BCL:0; +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Mailbox-Delivery | string | | wl:1;pcwl:1;ucf:0;jmr:0;auth:0;dest:I;ENG:(750128)(520011016)(520004050)(702028)(944506458)(944626604); +action_result.data.\*.internetMessageHeaders.X-Microsoft-Antispam-Message-Info | string | | La+CSxAnpzVJOXq7njrFPhIbsh0khleSwldy+W8NYDRsoyyPruPIiId4Avama7JyfzrxoExzhLk5pDn2lGPAJIpdcguiDSsDQg5T+iBCJgFeaEJXjhstECMi842/JGawB9WsiGw9Q/PpvjO5H/2fNLlQZVZW3AAQVZSsX3az4iOsv1Ggj4aYZRMKHmPAtniWOEtQD7zAEWC0jIZf613lWy3vxHfb/3+pV9X8zqPqazbyGy5Q14PICSNkKnvIw8rmeqJV8eSHhvR51Lchib6OIN4xOpLWxkSkBTt5B95RUPnpgPvgp2yLo0Q+EYRIabLDQ0kMsv+24+RnFmr9vo2gRNuFusw8iEPsVEQyhfgIWtBtsBpyvyykxcfa6lIdzQhixZH3Tlkdh1kb15wFS3Ooz3CjaWbY8jcUot5l1p08Ypsj6r7CpIo3xE6jE0x/EeUkDK3Fu/Ol0pOsJ1N5W4iJLdjqSQM3l/t9QWlcPhD8s6D7D7JM5OUHCeFEPr7sSL+P/5zTgBaeUvwtZrlQSH2GHc+5gPW8rkwlwJLJftVEid0gO2PUOrzItzME5PXYAcdx++sF3XC1YMPLet/jMpX8T7/z7+hxFxNyifgmGJ+DkNOec7yGkkcLBz6iCaHx7OrRGwDHIcdAtV85wCk3NEDDiKyHivQpwp/gY55W+wkLe7aqSHmFzm1rUSslx+DWz8w2EgSjJxOmf0JkoNKbTFl3FObkocR0lUUQUnETuoAXUqvpWGD5B69W9XXUM8c43ozz2oBZseheSAtkLil3tMIr/CMCMILPX/LdoErNtkmiFXCPqaLFSSeyO61oCMl6Ezndtwp22nwMPUg5ofG0kdqFuTW122umhy9C6h5BcREaLhWclSyqDoZPB9RvkRlI2kTRwuwbuFW3iOMzmVwxLIQH9K5JkxdMvC3hvNpjVgz7Q2ZnEF3xSNqeoWVQvkaIe8rQLUc8s+HMRUmSERGdfSuQJAx47g8PDs9s3rS/ThUSzIaljJPbUgXEnFg/G6h3I/yXLj2Nj2OG50snoI5jJmE4+69YmNwasdDZuYpnuQeFgu11HtsLniDthJdjEJyYC1utZNt9hgA+6JlLnm7Dxb43cSIiW8ev+3X+b2kREj2k/m8fSz7YgtoCB8AkuiVXRaH3EUiq8XCExbbWeynKRgwCZ6bzvfSiT3+cg+QQKPHFc/cgot56ta6X80tjhFodpTQNTE6V6C9QFHJ3JCVhsSzVifJAc8crI5hAcPbKFEIjinENcfpF/8reo2Yr1xFElhoX +action_result.data.\*.internetMessageHeaders.X-Originating-IP | string | | [2.39.180.162] +action_result.data.\*.internetMessageHeaders.X-Received | string | | by 2002:aa7:84d9:: with SMTP id x25mr2807688pfn.300.1592471487394; Thu, 18 Jun 2020 02:11:27 -0700 (PDT) +action_result.data.\*.internetMessageHeaders.subject | string | | test html +action_result.data.\*.receivedDateTime | string | | 2020-06-18T09:11:31Z +action_result.data.\*.sender.emailAddress.address | string | `email` | notifications@testdomain.com +action_result.data.\*.sender.emailAddress.name | string | `email` | notifications@testdomain.com +action_result.data.\*.subject | string | | test html +action_result.data.\*.uniqueBody.content | string | |
\\r\\n
\\r\\n

HTML heading

\\r\\nHTML body.
\\r\\n
\\r\\n +action_result.data.\*.uniqueBody.contentType | string | | html +action_result.summary | string | | +action_result.message | string | | Successfully fetched email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'run query' Search emails @@ -1176,104 +1264,104 @@ Search emails Type: **investigate** Read only: **True** -If the query or internet\_message\_id parameters are included, the subject, sender, body, and range parameters will be ignored\. The internet\_message\_id parameter will take precedence over the query parameter\.

For information on formatting the query parameter, see https\://developer\.microsoft\.com/en\-us/graph/docs/concepts/query\_parameters\.

If the limit parameter is not included, the action will default to limiting to ten emails that match the rest of the query\. The get\_folder\_id parameter should be enabled only when you specified folder name/folder path in the folder parameter\. If you provide folder ID in the folder parameter and set get\_folder\_id parameter to true, it will throw an error of folder ID not found for given folder name \(because the action considers folder parameter value as folder name/folder path\)\. The folder parameter must be either a \(case sensitive\) well\-known name \[list here; https\://docs\.microsoft\.com/en\-us/graph/api/resources/mailfolder?view=graph\-rest\-1\.0\] or the internal o365 folder ID\. The action supports searching for a folder that is nested within another\. To copy in such a folder, specify the complete folder path using the '/' \(forward slash\) as the separator\.
e\.g\. to search in a folder named phishing which is nested within \(is a child of\) Inbox, set the value as Inbox/phishing\. If a folder name has a literal forward slash\('/'\) in the name escape it with a backslash\('\\'\) to differentiate\.
When the search\_well\_known\_folders parameter is set to true, action will ignore values provided in the folder and get\_folder\_id parameters and the user will get details from all 17 well\-known folders which are listed below\:
  • Archive
  • Clutter
  • Conflicts
  • Conversation History
  • Deleted Items
  • Drafts
  • Inbox
  • Junk Email
  • Local Failures
  • Msg Folder Root
  • Outbox
  • Recoverable Items Deletions
  • Scheduled
  • Search Folders
  • Sent Items
  • Server Failures
  • Sync Issues

If the limit parameter is provided, the user will get the number of messages provided in the limit from every folder if present\. +If the query or internet_message_id parameters are included, the subject, sender, body, and range parameters will be ignored. The internet_message_id parameter will take precedence over the query parameter.

For information on formatting the query parameter, see https://developer.microsoft.com/en-us/graph/docs/concepts/query_parameters.

If the limit parameter is not included, the action will default to limiting to ten emails that match the rest of the query. The get_folder_id parameter should be enabled only when you specified folder name/folder path in the folder parameter. If you provide folder ID in the folder parameter and set get_folder_id parameter to true, it will throw an error of folder ID not found for given folder name (because the action considers folder parameter value as folder name/folder path). The folder parameter must be either a (case sensitive) well-known name [list here; https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0] or the internal o365 folder ID. The action supports searching for a folder that is nested within another. To copy in such a folder, specify the complete folder path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.
When the search_well_known_folders parameter is set to true, action will ignore values provided in the folder and get_folder_id parameters and the user will get details from all 17 well-known folders which are listed below:
  • Archive
  • Clutter
  • Conflicts
  • Conversation History
  • Deleted Items
  • Drafts
  • Inbox
  • Junk Email
  • Local Failures
  • Msg Folder Root
  • Outbox
  • Recoverable Items Deletions
  • Scheduled
  • Search Folders
  • Sent Items
  • Server Failures
  • Sync Issues

If the limit parameter is provided, the user will get the number of messages provided in the limit from every folder if present. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**email\_address** | required | User's email \(mailbox to search in\) | string | `email` -**folder** | optional | Destination folder; this must be either a \(case\-sensitive\) well\-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -**search\_well\_known\_folders** | optional | Checks all well known folders for messages, ignores folder name provided in parameter | boolean | -**get\_folder\_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/'\(forward slash\) ; i\.e\. Inbox/dir1/dir2/dir3\. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | +**email_address** | required | User's email (mailbox to search in) | string | `email` +**folder** | optional | Destination folder; this must be either a (case-sensitive) well-known name or the internal o365 folder ID | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` +**search_well_known_folders** | optional | Checks all well known folders for messages, ignores folder name provided in parameter | boolean | +**get_folder_id** | optional | Assume the folder parameter contains a folder name/folder path, separated by '/'(forward slash) ; i.e. Inbox/dir1/dir2/dir3. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value | boolean | **subject** | optional | Substring to search in subject | string | `msgoffice365 subject` **body** | optional | Substring to search in body | string | **sender** | optional | Sender email address to match | string | `email` **limit** | optional | Maximum emails to return | numeric | **query** | optional | MS Graph query string | string | -**internet\_message\_id** | optional | Internet message ID | string | `msgoffice365 internet message id` +**internet_message_id** | optional | Internet message ID | string | `msgoffice365 internet message id` #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.body | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` -action\_result\.parameter\.get\_folder\_id | boolean | -action\_result\.parameter\.internet\_message\_id | string | `msgoffice365 internet message id` -action\_result\.parameter\.limit | numeric | -action\_result\.parameter\.query | string | -action\_result\.parameter\.search\_well\_known\_folders | boolean | -action\_result\.parameter\.sender | string | `email` -action\_result\.parameter\.subject | string | `msgoffice365 subject` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.\@odata\.type | string | -action\_result\.data\.\*\.allowNewTimeProposals | string | -action\_result\.data\.\*\.bccRecipients\.\*\.emailAddress\.address | string | -action\_result\.data\.\*\.bccRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.bccRecipients\.email | string | `email` -action\_result\.data\.\*\.bccRecipients\.name | string | -action\_result\.data\.\*\.body\.content | string | -action\_result\.data\.\*\.body\.contentType | string | -action\_result\.data\.\*\.bodyPreview | string | -action\_result\.data\.\*\.categories | string | -action\_result\.data\.\*\.ccRecipients\.\*\.emailAddress\.address | string | -action\_result\.data\.\*\.ccRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.ccRecipients\.email | string | `email` -action\_result\.data\.\*\.ccRecipients\.name | string | -action\_result\.data\.\*\.changeKey | string | -action\_result\.data\.\*\.conversationId | string | -action\_result\.data\.\*\.conversationIndex | string | -action\_result\.data\.\*\.createdDateTime | string | -action\_result\.data\.\*\.endDateTime\.dateTime | string | -action\_result\.data\.\*\.endDateTime\.timeZone | string | -action\_result\.data\.\*\.flag\.flagStatus | string | -action\_result\.data\.\*\.from\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.from\.emailAddress\.name | string | -action\_result\.data\.\*\.hasAttachments | boolean | -action\_result\.data\.\*\.id | string | `msgoffice365 message id` -action\_result\.data\.\*\.importance | string | -action\_result\.data\.\*\.inferenceClassification | string | -action\_result\.data\.\*\.internetMessageId | string | `msgoffice365 internet message id` -action\_result\.data\.\*\.isAllDay | boolean | -action\_result\.data\.\*\.isDelegated | boolean | -action\_result\.data\.\*\.isDeliveryReceiptRequested | boolean | -action\_result\.data\.\*\.isDraft | boolean | -action\_result\.data\.\*\.isOutOfDate | boolean | -action\_result\.data\.\*\.isRead | boolean | -action\_result\.data\.\*\.isReadReceiptRequested | boolean | -action\_result\.data\.\*\.lastModifiedDateTime | string | -action\_result\.data\.\*\.meetingMessageType | string | -action\_result\.data\.\*\.meetingRequestType | string | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.previousEndDateTime | string | -action\_result\.data\.\*\.previousEndDateTime\.dateTime | string | -action\_result\.data\.\*\.previousEndDateTime\.timeZone | string | -action\_result\.data\.\*\.previousLocation | string | -action\_result\.data\.\*\.previousStartDateTime | string | -action\_result\.data\.\*\.previousStartDateTime\.dateTime | string | -action\_result\.data\.\*\.previousStartDateTime\.timeZone | string | -action\_result\.data\.\*\.receivedDateTime | string | -action\_result\.data\.\*\.recurrence | string | -action\_result\.data\.\*\.replyTo | string | -action\_result\.data\.\*\.replyTo\.\*\.emailAddress\.address | string | -action\_result\.data\.\*\.replyTo\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.responseRequested | boolean | -action\_result\.data\.\*\.sender\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.sender\.emailAddress\.name | string | -action\_result\.data\.\*\.sentDateTime | string | -action\_result\.data\.\*\.startDateTime\.dateTime | string | -action\_result\.data\.\*\.startDateTime\.timeZone | string | -action\_result\.data\.\*\.subject | string | `msgoffice365 subject` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.address | string | `email` -action\_result\.data\.\*\.toRecipients\.\*\.emailAddress\.name | string | -action\_result\.data\.\*\.type | string | -action\_result\.data\.\*\.vaultId | string | `sha1` `vault id` -action\_result\.data\.\*\.webLink | string | `url` -action\_result\.summary\.emails\_matched | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.body | string | | How are you doing this fine evening? +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` `msgoffice365 folder id` | Archive +action_result.parameter.get_folder_id | boolean | | True False +action_result.parameter.internet_message_id | string | `msgoffice365 internet message id` | +action_result.parameter.limit | numeric | | 5 +action_result.parameter.query | string | | $filter=contains(subject,'Urgent') +action_result.parameter.search_well_known_folders | boolean | | True False +action_result.parameter.sender | string | `email` | test@testdomain.abc.com +action_result.parameter.subject | string | `msgoffice365 subject` | Just wanted to say hello +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE" +action_result.data.\*.@odata.type | string | | #test.abc.eventMessageRequests +action_result.data.\*.allowNewTimeProposals | string | | +action_result.data.\*.bccRecipients.\*.emailAddress.address | string | | test3.test@gmail.com +action_result.data.\*.bccRecipients.\*.emailAddress.name | string | | test3.test@gmail.com +action_result.data.\*.bccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.bccRecipients.name | string | | Test Name +action_result.data.\*.body.content | string | | `\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n
\\r\\nTest
\\r\\n
\\r\\n\\r\\n\\r\\n` +action_result.data.\*.body.contentType | string | | text +action_result.data.\*.bodyPreview | string | | How are you doing this fine evening? +action_result.data.\*.categories | string | | +action_result.data.\*.ccRecipients.\*.emailAddress.address | string | | test3.test@gmail.com +action_result.data.\*.ccRecipients.\*.emailAddress.name | string | | test3.test@gmail.com +action_result.data.\*.ccRecipients.email | string | `email` | test@testdomain.abc.com +action_result.data.\*.ccRecipients.name | string | | Test Name +action_result.data.\*.changeKey | string | | CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE +action_result.data.\*.conversationId | string | | AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQAGqbDRkVLxZMtetM-dKqAPo= +action_result.data.\*.conversationIndex | string | | AQHXHRZ01/QE6F/kQkdaSwXyspIYQagZQ== +action_result.data.\*.createdDateTime | string | | 2017-10-30T22:32:42Z +action_result.data.\*.endDateTime.dateTime | string | | 2020-08-15T12:30:00.0000000 +action_result.data.\*.endDateTime.timeZone | string | | UTC +action_result.data.\*.flag.flagStatus | string | | notFlagged +action_result.data.\*.from.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.from.emailAddress.name | string | | Test Name +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 message id` | AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA= +action_result.data.\*.importance | string | | normal +action_result.data.\*.inferenceClassification | string | | focused +action_result.data.\*.internetMessageId | string | `msgoffice365 internet message id` | +action_result.data.\*.isAllDay | boolean | | True False +action_result.data.\*.isDelegated | boolean | | True False +action_result.data.\*.isDeliveryReceiptRequested | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isOutOfDate | boolean | | True False +action_result.data.\*.isRead | boolean | | True False +action_result.data.\*.isReadReceiptRequested | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2017-10-30T22:32:53Z +action_result.data.\*.meetingMessageType | string | | meetingRequest +action_result.data.\*.meetingRequestType | string | | informationalUpdate +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA= +action_result.data.\*.previousEndDateTime | string | | +action_result.data.\*.previousEndDateTime.dateTime | string | | 2020-08-15T12:30:00.0000000 +action_result.data.\*.previousEndDateTime.timeZone | string | | UTC +action_result.data.\*.previousLocation | string | | +action_result.data.\*.previousStartDateTime | string | | +action_result.data.\*.previousStartDateTime.dateTime | string | | 2020-08-15T12:00:00.0000000 +action_result.data.\*.previousStartDateTime.timeZone | string | | UTC +action_result.data.\*.receivedDateTime | string | | 2017-10-30T22:32:42Z +action_result.data.\*.recurrence | string | | +action_result.data.\*.replyTo | string | | +action_result.data.\*.replyTo.\*.emailAddress.address | string | | hellohi@okta.com +action_result.data.\*.replyTo.\*.emailAddress.name | string | | hellohi@okta.com +action_result.data.\*.responseRequested | boolean | | True False +action_result.data.\*.sender.emailAddress.address | string | `email` | test@testdomain.abc.com +action_result.data.\*.sender.emailAddress.name | string | | Test Name +action_result.data.\*.sentDateTime | string | | 2017-10-30T22:32:37Z +action_result.data.\*.startDateTime.dateTime | string | | 2020-08-15T12:00:00.0000000 +action_result.data.\*.startDateTime.timeZone | string | | UTC +action_result.data.\*.subject | string | `msgoffice365 subject` | Just wanted to say hello +action_result.data.\*.toRecipients.\*.emailAddress.address | string | `email` | Test@testdomain.abc.com +action_result.data.\*.toRecipients.\*.emailAddress.name | string | | Test Name +action_result.data.\*.type | string | | singleInstance +action_result.data.\*.vaultId | string | `sha1` `vault id` | 719dbf72d7c0bc89d7e34306c08a0b66191902b9 +action_result.data.\*.webLink | string | `url` | https://outlook.office365.com/owa/?ItemID=AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk%2FsdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA%3D&exvsurl=1&viewmodel=ReadMessageItem +action_result.summary.emails_matched | numeric | | 1 +action_result.message | string | | Emails matched: 1 +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'create folder' Create a new folder @@ -1281,37 +1369,37 @@ Create a new folder Type: **generic** Read only: **False** -Create a new folder either in the mailbox root or inside an existing folder\. The action supports creating a folder that is nested within another\. To create in such a folder, specify the complete path using the '/' \(forward slash\) as the separator\.
e\.g\. to search in a folder named phishing which is nested within \(is a child of\) Inbox, set the value as Inbox/phishing\. If a folder name has a literal forward slash\('/'\) in the name escape it with a backslash\('\\'\) to differentiate\. +Create a new folder either in the mailbox root or inside an existing folder. The action supports creating a folder that is nested within another. To create in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate. #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**email\_address** | required | User's email \(mailbox to create folders\) | string | `email` -**folder** | required | Folder Name/Path\. Use '/'to separate folder elements; i\.e\. Inbox/dir1/dir2/dir3 | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` -**all\_subdirs** | optional | Make any missing directories in the path if they don't exist instead of failing | boolean | +**email_address** | required | User's email (mailbox to create folders) | string | `email` +**folder** | required | Folder Name/Path. Use '/'to separate folder elements; i.e. Inbox/dir1/dir2/dir3 | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` +**all_subdirs** | optional | Make any missing directories in the path if they don't exist instead of failing | boolean | #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.all\_subdirs | boolean | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` -action\_result\.data\.\*\.\@odata\.context | string | `url` -action\_result\.data\.\*\.\@odata\.etag | string | -action\_result\.data\.\*\.childFolderCount | numeric | -action\_result\.data\.\*\.displayName | string | -action\_result\.data\.\*\.id | string | `msgoffice365 folder id` -action\_result\.data\.\*\.isHidden | boolean | -action\_result\.data\.\*\.parentFolderId | string | `msgoffice365 folder id` -action\_result\.data\.\*\.sizeInBytes | numeric | -action\_result\.data\.\*\.totalItemCount | numeric | -action\_result\.data\.\*\.unreadItemCount | numeric | -action\_result\.summary\.folder | string | -action\_result\.summary\.folders created | numeric | -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.all_subdirs | boolean | | True False +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` | Archive +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#users('abc%def.test.com')/mailFolders/$entity +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE" +action_result.data.\*.childFolderCount | numeric | | 1 +action_result.data.\*.displayName | string | | +action_result.data.\*.id | string | `msgoffice365 folder id` | AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA= +action_result.data.\*.isHidden | boolean | | True False +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA= +action_result.data.\*.sizeInBytes | numeric | | 0 +action_result.data.\*.totalItemCount | numeric | | 1 +action_result.data.\*.unreadItemCount | numeric | | 1 +action_result.summary.folder | string | | AQMkAMExNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAFA6de0wAAAA== +action_result.summary.folders created | numeric | | 1 +action_result.message | string | | Emails matched: 1 +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'get folder id' Get the API ID of the folder @@ -1319,27 +1407,95 @@ Get the API ID of the folder Type: **investigate** Read only: **True** -The action supports searching a folder that is nested within another\. To search in such a folder, specify the complete path using the '/' \(forward slash\) as the separator\.
e\.g\. to search in a folder named phishing which is nested within \(is a child of\) Inbox, set the value as Inbox/phishing\. If a folder name has a literal forward slash\('/'\) in the name escape it with a backslash\('\\'\) to differentiate\. +The action supports searching a folder that is nested within another. To search in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate. + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**email_address** | required | User's email (mailbox) | string | `email` +**folder** | required | Folder Name/Path. Use '/' to separate folder elements; i.e. Inbox/dir1/dir2/dir3 | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.email_address | string | `email` | test@testdomain.abc.com +action_result.parameter.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` | Test/Testy/subfolders +action_result.data.\*.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` | Test +action_result.data.\*.folder_id | string | `msgoffice365 folder id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCRAAA= +action_result.data.\*.path | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` | +action_result.summary.folder_id | string | `msgoffice365 folder id` | AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA= +action_result.message | string | | Folder id: AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA= +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 + +## action: 'send email' +Sends an email with optional text rendering. Attachments are allowed a Content-ID tag for reference within the html + +Type: **generic** +Read only: **False** + +
Notes
  • If the from parameter is not provided, then the action will consider the username parameter provided in the asset configuration as the sender's email address.
  • The send email action is executed in two stages. Before sending an email it creates a draft of the email. Once the draft is successfully saved, the email is sent.
#### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**email\_address** | required | User's email \(mailbox\) | string | `email` -**folder** | required | Folder Name/Path\. Use '/' to separate folder elements; i\.e\. Inbox/dir1/dir2/dir3 | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` +**from** | optional | From field | string | `email` +**to** | required | List of recipients email addresses | string | `email` +**cc** | optional | List of recipients email addresses to include on cc line | string | `email` +**bcc** | optional | List of recipients email addresses to include on bcc line | string | `email` +**subject** | required | Message Subject | string | +**headers** | optional | Serialized json dictionary. Additional email headers to be added to the message | string | +**body** | required | Html rendering of message | string | +**attachments** | optional | List of vault ids of files to attach to the email. Vault id is used as content id | string | `sha1` `vault id` #### Action Output -DATA PATH | TYPE | CONTAINS ---------- | ---- | -------- -action\_result\.status | string | -action\_result\.parameter\.email\_address | string | `email` -action\_result\.parameter\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` -action\_result\.data\.\*\.folder | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` -action\_result\.data\.\*\.folder\_id | string | `msgoffice365 folder id` -action\_result\.data\.\*\.path | string | `msgoffice365 mail folder` `msgoffice365 mail folder path` -action\_result\.summary\.folder\_id | string | `msgoffice365 folder id` -action\_result\.message | string | -summary\.total\_objects | numeric | -summary\.total\_objects\_successful | numeric | +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.attachments | string | `sha1` `vault id` | da39a3ee5e6b4b0d3255bfef95601890afd80709 +action_result.parameter.bcc | string | `email` | test@testdomain.abc.com +action_result.parameter.body | string | |

Have a good time with these.

+action_result.parameter.cc | string | `email` | test@testdomain.abc.com +action_result.parameter.from | string | `email` | test@testdomain.abc.com +action_result.parameter.headers | string | | {"x-custom-header":"Custom value"} +action_result.parameter.subject | string | | Example subject +action_result.parameter.to | string | `email` | test@testdomain.abc.com +action_result.data.\*.@odata.context | string | `url` | https://test.abc.com/v1.0/$metadata#users('user%40.abc.com')/messages(internetMessageHeaders,body,uniqueBody,sender,subject)/$entity +action_result.data.\*.@odata.etag | string | | W/"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAO8DBJl" +action_result.data.\*.body.content | string | | `Have a good time with these.\\r\\n` +action_result.data.\*.body.contentType | string | | html +action_result.data.\*.bodyPreview | string | | Have a good time with these. +action_result.data.\*.changeKey | string | | CQAAABYAAADTteE6Q2eCQKSqg19j6T+NAAYzSv5R +action_result.data.\*.conversationId | string | | AAQkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAQAORC3aOpHnZMsHD4-7L40sY= +action_result.data.\*.conversationIndex | string | | AQHZopYz5ELdo6kedkywcPj/svjSxg== +action_result.data.\*.createdDateTime | string | | 2023-06-19T10:09:58Z +action_result.data.\*.flag.flagStatus | string | | notFlagged +action_result.data.\*.from.emailAddress.address | string | `email` | cisco@phantomengineering2.onmicrosoft.com +action_result.data.\*.from.emailAddress.name | string | | Ryan Edwards +action_result.data.\*.hasAttachments | boolean | | True False +action_result.data.\*.id | string | `msgoffice365 message id` | AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA== +action_result.data.\*.importance | string | | normal +action_result.data.\*.inferenceClassification | string | | focused +action_result.data.\*.internetMessageId | string | `msgoffice365 internet message id` | +action_result.data.\*.isDeliveryReceiptRequested | boolean | | True False +action_result.data.\*.isDraft | boolean | | True False +action_result.data.\*.isRead | boolean | | True False +action_result.data.\*.isReadReceiptRequested | boolean | | True False +action_result.data.\*.lastModifiedDateTime | string | | 2023-06-19T10:09:58Z +action_result.data.\*.parentFolderId | string | `msgoffice365 folder id` | AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAAAgEPAAAA +action_result.data.\*.receivedDateTime | string | | 2020-06-18T09:11:31Z +action_result.data.\*.sender.emailAddress.address | string | `email` | notifications@testdomain.com +action_result.data.\*.sender.emailAddress.name | string | `email` | notifications@testdomain.com +action_result.data.\*.sentDateTime | string | | 2023-06-19T10:09:58Z +action_result.data.\*.subject | string | | test html +action_result.data.\*.toRecipients.\*.emailAddress.address | string | `email` | cisco@phantomengineering2.onmicrosoft.com +action_result.data.\*.toRecipients.\*.emailAddress.name | string | | Ryan Edwards +action_result.data.\*.webLink | string | | https://outlook.office365.com/owa/?ItemID=AAkALgAAAAAAHYQDEapmEc2byACqAC%2FEWg0A07XhOkNngkCkqoNfY%2Bk%2FjQAGNNQOowAA&exvsurl=1&viewmodel=ReadMessageItem +action_result.summary | string | | +action_result.message | string | | Successfully sent email +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'on poll' Ingest emails from Office 365 using Graph API @@ -1350,11 +1506,11 @@ Read only: **True** #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**start\_time** | optional | Parameter Ignored in this app | numeric | -**end\_time** | optional | Parameter Ignored in this app | numeric | -**container\_id** | optional | Parameter Ignored in this app | string | -**container\_count** | required | Maximum number of emails to ingest | numeric | -**artifact\_count** | optional | Parameter Ignored in this app | numeric | +**start_time** | optional | Parameter Ignored in this app | numeric | +**end_time** | optional | Parameter Ignored in this app | numeric | +**container_id** | optional | Parameter Ignored in this app | string | +**container_count** | required | Maximum number of emails to ingest | numeric | +**artifact_count** | optional | Parameter Ignored in this app | numeric | #### Action Output No Output \ No newline at end of file diff --git a/__init__.py b/__init__.py index 7a7c38d..ed269c4 100644 --- a/__init__.py +++ b/__init__.py @@ -1,6 +1,6 @@ # File: __init__.py # -# Copyright (c) 2017-2022 Splunk Inc. +# Copyright (c) 2017-2023 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/office365.json b/office365.json index 2d93d07..db9125f 100644 --- a/office365.json +++ b/office365.json @@ -12,16 +12,22 @@ "contributors": [ { "name": "Alan Shaikh" + }, + { + "name": "Chris Hutto" + }, + { + "name": "Mathieu A. Cormier" } ], - "license": "Copyright (c) 2017-2022 Splunk Inc.", - "app_version": "2.7.1", + "license": "Copyright (c) 2017-2023 Splunk Inc.", + "app_version": "2.8.0", "utctime_updated": "2022-02-04T01:20:46.000000Z", "package_name": "phantom_msgraphoffice365", "main_module": "office365_connector.py", - "min_phantom_version": "5.3.0", + "min_phantom_version": "6.0.0", "latest_tested_versions": [ - "Cloud 3 August, 2022" + "Cloud 12 April, 2023" ], "app_wizard_version": "1.0.0", "python_version": "3", @@ -161,6 +167,12 @@ "data_type": "numeric", "default": 60, "order": 22 + }, + "extract_eml": { + "data_type": "boolean", + "description": "Extract root (primary) email as Vault", + "order": 23, + "default": false } }, "actions": [ @@ -524,7 +536,7 @@ "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "\r\n\r\n\r\n\r\n
 
\r\n\r\n\r\n" + "`\\r\\n\\r\\n\\r\\n\\r\\n
 
\\r\\n\\r\\n\\r\\n`" ] }, { @@ -1057,21 +1069,33 @@ "versions": "EQ(*)" }, { - "action": "list users", - "identifier": "list_users", - "description": "Retrieve a list of users", + "action": "get rule", + "identifier": "get_rule", + "description": "Get the properties and relationships of a messageRule object", "type": "investigate", "read_only": true, "parameters": { - "filter": { - "description": "Search for specific results", + "user_id": { + "description": "User ID/Principal name", "data_type": "string", - "order": 0 + "required": true, + "primary": true, + "order": 0, + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" + ] }, - "limit": { - "description": "Maximum number of users to return", - "data_type": "numeric", - "order": 1 + "rule_id": { + "description": "Inbox rule ID", + "data_type": "string", + "required": true, + "primary": true, + "order": 1, + "contains": [ + "msgoffice365 rule id" + ] } }, "output": [ @@ -1084,116 +1108,127 @@ ] }, { - "data_path": "action_result.parameter.filter", + "data_path": "action_result.parameter.rule_id", "data_type": "string", "example_values": [ - "displayName eq 'User Name'" + "AQAABgFGMAc=" + ], + "contains": [ + "msgoffice365 rule id" ] }, { - "data_path": "action_result.parameter.limit", - "data_type": "numeric", + "data_path": "action_result.parameter.user_id", + "data_type": "string", "example_values": [ - 20 + "test@testdomain.abc.com" + ], + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" ] }, { - "data_path": "action_result.data.*.businessPhones", + "data_path": "action_result.data.*.@odata.context", "data_type": "string", "example_values": [ - "2056120271" + "https://graph.microsoft.com/v1.0/$metadata#users('eeb3645f-df19-47a1-8e8c-fcd234cb5f6f')/mailFolders('inbox')/messageRules/$entity" ] }, { - "data_path": "action_result.data.*.displayName", + "data_path": "action_result.data.*.actions_copyToFolder", "data_type": "string", "example_values": [ - "Test Admin" - ], - "column_name": "Display Name", - "column_order": 2 + "AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTswAAAA==" + ] }, { - "data_path": "action_result.data.*.givenName", - "data_type": "string", + "data_path": "action_result.data.*.actions_stopProcessingRules", + "data_type": "boolean", "example_values": [ - "Test" - ], - "column_name": "Given Name", - "column_order": 3 + true, + false + ] }, { - "data_path": "action_result.data.*.id", + "data_path": "action_result.data.*.conditions_fromAddresses_0_emailAddress_address", "data_type": "string", - "example_values": [ - "6132ca31-7a09-434f-a269-abe836d0c01e" - ], "contains": [ - "msgoffice365 user id" + "email" ], - "column_name": "User ID", - "column_order": 0 + "example_values": [ + "cisco@phantomengineering2.onmicrosoft.com" + ] }, { - "data_path": "action_result.data.*.jobTitle", - "data_type": "string" + "data_path": "action_result.data.*.conditions_fromAddresses_0_emailAddress_name", + "data_type": "string", + "example_values": [ + "Ryan Edwards" + ] }, { - "data_path": "action_result.data.*.mail", + "data_path": "action_result.data.*.displayName", "data_type": "string", - "contains": [ - "email" - ], "example_values": [ - "test@testdomain.abc.com" + "Move all messages from Casey Edwards to test-msgoffice365-test" ] }, { - "data_path": "action_result.data.*.mobilePhone", - "data_type": "string" + "data_path": "action_result.data.*.hasError", + "data_type": "boolean", + "example_values": [ + true, + false + ] }, { - "data_path": "action_result.data.*.officeLocation", - "data_type": "string" + "data_path": "action_result.data.*.id", + "data_type": "string", + "example_values": [ + "AQAABgFGL8A=" + ] }, { - "data_path": "action_result.data.*.preferredLanguage", - "data_type": "string" + "data_path": "action_result.data.*.isEnabled", + "data_type": "boolean", + "example_values": [ + true, + false + ] }, { - "data_path": "action_result.data.*.surname", - "data_type": "string", + "data_path": "action_result.data.*.isReadOnly", + "data_type": "boolean", "example_values": [ - "Globaltest" - ], - "column_name": "Surname", - "column_order": 4 + true, + false + ] }, { - "data_path": "action_result.data.*.userPrincipalName", - "data_type": "string", + "data_path": "action_result.data.*.sequence", + "data_type": "numeric", "example_values": [ - "test@testdomain.abc.com" - ], - "contains": [ - "msgoffice365 user principal name", - "email" - ], - "column_name": "User Principal Name", - "column_order": 1 + 2 + ] }, { - "data_path": "action_result.summary.total_users_returned", - "data_type": "numeric", + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string", "example_values": [ - 11 + "Successfully retrieved specified inbox rule" ] }, { "data_path": "action_result.message", "data_type": "string", "example_values": [ - "Successfully retrieved 11 users" + "Successfully retrieved specified inbox rule" ] }, { @@ -1213,28 +1248,31 @@ ], "render": { "width": 12, - "title": "List Users", - "type": "table", - "height": 5 + "title": "get rule", + "type": "custom", + "height": 5, + "view": "office365_view.display_view" }, "versions": "EQ(*)" }, { - "action": "list groups", - "identifier": "list_groups", - "description": "List all the groups in an organization, including but not limited to Office 365 groups", + "action": "list rules", + "identifier": "list_rules", + "description": "Get all the messageRule objects defined for the user's inbox", "type": "investigate", "read_only": true, "parameters": { - "filter": { - "description": "Search for specific results", + "user_id": { + "description": "User ID/Principal name", "data_type": "string", - "order": 0 - }, - "limit": { - "description": "Maximum number of groups to return", - "data_type": "numeric", - "order": 1 + "required": true, + "primary": true, + "order": 0, + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" + ] } }, "output": [ @@ -1247,102 +1285,111 @@ ] }, { - "data_path": "action_result.parameter.filter", + "data_path": "action_result.parameter.user_id", "data_type": "string", "example_values": [ - "displayName eq 'Group Name'" + "test@testdomain.abc.com" + ], + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" ] }, { - "data_path": "action_result.parameter.limit", - "data_type": "numeric", + "data_path": "action_result.data.*.actions.copyToFolder", + "data_type": "string", + "contains": [ + "msgoffice365 folder id" + ], "example_values": [ - 20 + "AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTswAAAA==" ] }, { - "data_path": "action_result.data.*.classification", - "data_type": "string" + "data_path": "action_result.data.*.actions.delete", + "data_type": "boolean", + "example_values": [ + true, + false + ], + "column_name": "Delete Email Enabled", + "column_order": 2 }, { - "data_path": "action_result.data.*.createdDateTime", - "data_type": "string", + "data_path": "action_result.data.*.actions.markAsRead", + "data_type": "boolean", "example_values": [ - "2018-09-11T09:51:07Z" + true, + false ] }, { - "data_path": "action_result.data.*.creationOptions", + "data_path": "action_result.data.*.actions.moveToFolder", "data_type": "string", + "contains": [ + "msgoffice365 folder id" + ], "example_values": [ - "ExchangeProvisioningFlags:3552" + "AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAF6qrTtAAAAA==" ] }, { - "data_path": "action_result.data.*.deletedDateTime", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.description", - "data_type": "string", + "data_path": "action_result.data.*.actions.stopProcessingRules", + "data_type": "boolean", "example_values": [ - "This is for testing purpose" - ], - "column_name": "Description", - "column_order": 3 + true, + false + ] }, { - "data_path": "action_result.data.*.displayName", + "data_path": "action_result.data.*.conditions.fromAddresses.*.emailAddress.address", "data_type": "string", "example_values": [ - "Test-test-site" + "cisco@phantomengineering2.onmicrosoft.com" ], - "column_name": "Display Name", - "column_order": 2 - }, - { - "data_path": "action_result.data.*.expirationDateTime", - "data_type": "string" + "contains": [ + "email" + ] }, { - "data_path": "action_result.data.*.groupTypes", + "data_path": "action_result.data.*.conditions.fromAddresses.*.emailAddress.name", "data_type": "string", "example_values": [ - "Unified" - ], - "column_name": "Group Type", - "column_order": 4 + "Ryan Edwards" + ] }, { - "data_path": "action_result.data.*.id", + "data_path": "action_result.data.*.displayName", "data_type": "string", "example_values": [ - "2a201c95-101b-42d9-a7af-9a2fdf8193f1" - ], - "contains": [ - "msgoffice365 group id" + "Emails to Trash" ], - "column_name": "Group ID", + "column_name": "Rule Name", "column_order": 0 }, { - "data_path": "action_result.data.*.isAssignableToRole", - "data_type": "string" + "data_path": "action_result.data.*.hasError", + "data_type": "boolean", + "example_values": [ + true, + false + ] }, { - "data_path": "action_result.data.*.mail", + "data_path": "action_result.data.*.id", "data_type": "string", + "column_name": "Rule ID", "example_values": [ - "Test-test-site@testdomain.abc.com" + "AQAABiQdmB8=" ], "contains": [ - "email" + "msgoffice365 rule id" ], - "column_name": "Group Mail ID", "column_order": 1 }, { - "data_path": "action_result.data.*.mailEnabled", + "data_path": "action_result.data.*.isEnabled", "data_type": "boolean", "example_values": [ true, @@ -1350,120 +1397,32 @@ ] }, { - "data_path": "action_result.data.*.mailNickname", - "data_type": "string", - "example_values": [ - "Test-test-site" - ] - }, - { - "data_path": "action_result.data.*.membershipRule", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.membershipRuleProcessingState", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesDomainName", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesLastSyncDateTime", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesNetBiosName", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesSamAccountName", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesSecurityIdentifier", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.onPremisesSyncEnabled", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.preferredDataLocation", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.preferredLanguage", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.proxyAddresses", - "data_type": "string", - "example_values": [ - "SMTP:test-h@testdomain.abc.com" - ] - }, - { - "data_path": "action_result.data.*.renewedDateTime", - "data_type": "string", - "example_values": [ - "2018-09-11T09:51:07Z" - ] - }, - { - "data_path": "action_result.data.*.resourceBehaviorOptions", - "data_type": "string", - "example_values": [ - "WelcomeEmailDisabled" - ] - }, - { - "data_path": "action_result.data.*.resourceProvisioningOptions", - "data_type": "string", - "example_values": [ - "Team" - ] - }, - { - "data_path": "action_result.data.*.securityEnabled", - "data_type": "boolean", + "data_path": "action_result.data.*.isReadOnly", + "data_type": "boolean", "example_values": [ true, false ] }, { - "data_path": "action_result.data.*.securityIdentifier", - "data_type": "string", + "data_path": "action_result.data.*.sequence", + "data_type": "numeric", "example_values": [ - "S-1-12-1-294681889-1319597617-672379543-28952022" + 1 ] }, { - "data_path": "action_result.data.*.theme", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.visibility", - "data_type": "string", - "example_values": [ - "Private" - ], - "column_name": "Visibility", - "column_order": 5 - }, - { - "data_path": "action_result.summary.total_groups_returned", + "data_path": "action_result.summary.total_rules_returned", "data_type": "numeric", "example_values": [ - 9 + 14 ] }, { "data_path": "action_result.message", "data_type": "string", "example_values": [ - "Successfully retrieved 9 groups" + "Successfully retrieved 7 rules" ] }, { @@ -1482,45 +1441,28 @@ } ], "render": { - "width": 12, - "title": "List Groups", - "type": "table", - "height": 5 + "title": "list rules", + "type": "custom", + "view": "office365_view.display_view" }, "versions": "EQ(*)" }, { - "action": "list group members", - "identifier": "list_group_members", - "description": "List all the members in group", + "action": "list users", + "identifier": "list_users", + "description": "Retrieve a list of users", "type": "investigate", "read_only": true, "parameters": { - "group_id": { - "description": "Group ID", - "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "msgoffice365 group id" - ], - "order": 0 - }, - "get_transitive_members": { - "description": "Get a list of the group's members. A group can have users, devices, organizational contacts, and other groups as members. This operation is transitive and returns a flat list of all nested members", - "data_type": "boolean", - "default": true, - "order": 1 - }, "filter": { "description": "Search for specific results", "data_type": "string", - "order": 2 + "order": 0 }, "limit": { - "description": "Maximum number of members to return", + "description": "Maximum number of users to return", "data_type": "numeric", - "order": 3 + "order": 1 } }, "output": [ @@ -1536,25 +1478,7 @@ "data_path": "action_result.parameter.filter", "data_type": "string", "example_values": [ - "displayName eq 'Group Name'" - ] - }, - { - "data_path": "action_result.parameter.get_transitive_members", - "data_type": "boolean", - "example_values": [ - true, - false - ] - }, - { - "data_path": "action_result.parameter.group_id", - "data_type": "string", - "contains": [ - "msgoffice365 group id" - ], - "example_values": [ - "11907d21-7631-4ea7-97b2-1328d1c5b901" + "displayName eq 'User Name'" ] }, { @@ -1564,13 +1488,6 @@ 20 ] }, - { - "data_path": "action_result.data.*.@odata.type", - "data_type": "string", - "example_values": [ - "#test.abc.user" - ] - }, { "data_path": "action_result.data.*.businessPhones", "data_type": "string", @@ -1657,17 +1574,17 @@ "column_order": 1 }, { - "data_path": "action_result.summary.total_members_returned", + "data_path": "action_result.summary.total_users_returned", "data_type": "numeric", "example_values": [ - 9 + 11 ] }, { "data_path": "action_result.message", "data_type": "string", "example_values": [ - "Successfully retrieved 9 groups" + "Successfully retrieved 11 users" ] }, { @@ -1687,40 +1604,28 @@ ], "render": { "width": 12, - "title": "List Group Members", + "title": "List Users", "type": "table", "height": 5 }, "versions": "EQ(*)" }, { - "action": "list folders", - "identifier": "list_folders", - "description": "Retrieve a list of mail folders", - "verbose": "If you want to list all the child folders (includes all the sub-levels) of the specific parent folder, then, you have to provide the parent folder_id parameter. If you don't provide folder_id it will list all the folders on Office 365 account (includes all the sub-level folders).", + "action": "list groups", + "identifier": "list_groups", + "description": "List all the groups in an organization, including but not limited to Office 365 groups", "type": "investigate", "read_only": true, "parameters": { - "user_id": { - "description": "User ID/Principal name", + "filter": { + "description": "Search for specific results", "data_type": "string", - "required": true, - "primary": true, - "order": 0, - "contains": [ - "msgoffice365 user id", - "msgoffice365 user principal name", - "email" - ] + "order": 0 }, - "folder_id": { - "description": "Parent mail folder ID", - "data_type": "string", - "primary": true, - "order": 1, - "contains": [ - "msgoffice365 folder id" - ] + "limit": { + "description": "Maximum number of groups to return", + "data_type": "numeric", + "order": 1 } }, "output": [ @@ -1733,74 +1638,560 @@ ] }, { - "data_path": "action_result.parameter.folder_id", + "data_path": "action_result.parameter.filter", "data_type": "string", "example_values": [ - "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA=" - ], - "contains": [ - "msgoffice365 folder id" + "displayName eq 'Group Name'" ] }, { - "data_path": "action_result.parameter.user_id", - "data_type": "string", + "data_path": "action_result.parameter.limit", + "data_type": "numeric", "example_values": [ - "test@testdomain.abc.com" - ], - "contains": [ - "msgoffice365 user id", - "msgoffice365 user principal name", - "email" + 20 ] }, { - "data_path": "action_result.data.*.childFolderCount", - "data_type": "numeric", - "example_values": [ - 1 - ], - "column_name": "Child Folder Count", - "column_order": 3 + "data_path": "action_result.data.*.classification", + "data_type": "string" }, { - "data_path": "action_result.data.*.displayName", + "data_path": "action_result.data.*.createdDateTime", "data_type": "string", "example_values": [ - "test" - ], - "column_name": "Display Name", - "column_order": 0 + "2018-09-11T09:51:07Z" + ] }, { - "data_path": "action_result.data.*.id", + "data_path": "action_result.data.*.creationOptions", "data_type": "string", "example_values": [ - "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA=" - ], - "column_name": "Folder ID", - "column_order": 1, - "contains": [ - "msgoffice365 folder id" + "ExchangeProvisioningFlags:3552" ] }, { - "data_path": "action_result.data.*.isHidden", - "data_type": "boolean", - "example_values": [ - true, - false - ] + "data_path": "action_result.data.*.deletedDateTime", + "data_type": "string" }, { - "data_path": "action_result.data.*.parentFolderId", + "data_path": "action_result.data.*.description", "data_type": "string", "example_values": [ - "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAAAAAEIAAA=" + "This is for testing purpose" ], - "column_name": "Parent Folder ID", - "column_order": 2, - "contains": [ + "column_name": "Description", + "column_order": 3 + }, + { + "data_path": "action_result.data.*.displayName", + "data_type": "string", + "example_values": [ + "Test-test-site" + ], + "column_name": "Display Name", + "column_order": 2 + }, + { + "data_path": "action_result.data.*.expirationDateTime", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.groupTypes", + "data_type": "string", + "example_values": [ + "Unified" + ], + "column_name": "Group Type", + "column_order": 4 + }, + { + "data_path": "action_result.data.*.id", + "data_type": "string", + "example_values": [ + "2a201c95-101b-42d9-a7af-9a2fdf8193f1" + ], + "contains": [ + "msgoffice365 group id" + ], + "column_name": "Group ID", + "column_order": 0 + }, + { + "data_path": "action_result.data.*.isAssignableToRole", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.mail", + "data_type": "string", + "example_values": [ + "Test-test-site@testdomain.abc.com" + ], + "contains": [ + "email" + ], + "column_name": "Group Mail ID", + "column_order": 1 + }, + { + "data_path": "action_result.data.*.mailEnabled", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.data.*.mailNickname", + "data_type": "string", + "example_values": [ + "Test-test-site" + ] + }, + { + "data_path": "action_result.data.*.membershipRule", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.membershipRuleProcessingState", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesDomainName", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesLastSyncDateTime", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesNetBiosName", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesSamAccountName", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesSecurityIdentifier", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.onPremisesSyncEnabled", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.preferredDataLocation", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.preferredLanguage", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.proxyAddresses", + "data_type": "string", + "example_values": [ + "SMTP:test-h@testdomain.abc.com" + ] + }, + { + "data_path": "action_result.data.*.renewedDateTime", + "data_type": "string", + "example_values": [ + "2018-09-11T09:51:07Z" + ] + }, + { + "data_path": "action_result.data.*.resourceBehaviorOptions", + "data_type": "string", + "example_values": [ + "WelcomeEmailDisabled" + ] + }, + { + "data_path": "action_result.data.*.resourceProvisioningOptions", + "data_type": "string", + "example_values": [ + "Team" + ] + }, + { + "data_path": "action_result.data.*.securityEnabled", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.data.*.securityIdentifier", + "data_type": "string", + "example_values": [ + "S-1-12-1-294681889-1319597617-672379543-28952022" + ] + }, + { + "data_path": "action_result.data.*.theme", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.visibility", + "data_type": "string", + "example_values": [ + "Private" + ], + "column_name": "Visibility", + "column_order": 5 + }, + { + "data_path": "action_result.summary.total_groups_returned", + "data_type": "numeric", + "example_values": [ + 9 + ] + }, + { + "data_path": "action_result.message", + "data_type": "string", + "example_values": [ + "Successfully retrieved 9 groups" + ] + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "render": { + "width": 12, + "title": "List Groups", + "type": "table", + "height": 5 + }, + "versions": "EQ(*)" + }, + { + "action": "list group members", + "identifier": "list_group_members", + "description": "List all the members in group", + "type": "investigate", + "read_only": true, + "parameters": { + "group_id": { + "description": "Group ID", + "data_type": "string", + "required": true, + "primary": true, + "contains": [ + "msgoffice365 group id" + ], + "order": 0 + }, + "get_transitive_members": { + "description": "Get a list of the group's members. A group can have users, devices, organizational contacts, and other groups as members. This operation is transitive and returns a flat list of all nested members", + "data_type": "boolean", + "default": true, + "order": 1 + }, + "filter": { + "description": "Search for specific results", + "data_type": "string", + "order": 2 + }, + "limit": { + "description": "Maximum number of members to return", + "data_type": "numeric", + "order": 3 + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.filter", + "data_type": "string", + "example_values": [ + "displayName eq 'Group Name'" + ] + }, + { + "data_path": "action_result.parameter.get_transitive_members", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.parameter.group_id", + "data_type": "string", + "contains": [ + "msgoffice365 group id" + ], + "example_values": [ + "11907d21-7631-4ea7-97b2-1328d1c5b901" + ] + }, + { + "data_path": "action_result.parameter.limit", + "data_type": "numeric", + "example_values": [ + 20 + ] + }, + { + "data_path": "action_result.data.*.@odata.type", + "data_type": "string", + "example_values": [ + "#test.abc.user" + ] + }, + { + "data_path": "action_result.data.*.businessPhones", + "data_type": "string", + "example_values": [ + "2056120271" + ] + }, + { + "data_path": "action_result.data.*.displayName", + "data_type": "string", + "example_values": [ + "Test Admin" + ], + "column_name": "Display Name", + "column_order": 2 + }, + { + "data_path": "action_result.data.*.givenName", + "data_type": "string", + "example_values": [ + "Test" + ], + "column_name": "Given Name", + "column_order": 3 + }, + { + "data_path": "action_result.data.*.id", + "data_type": "string", + "example_values": [ + "6132ca31-7a09-434f-a269-abe836d0c01e" + ], + "contains": [ + "msgoffice365 user id" + ], + "column_name": "User ID", + "column_order": 0 + }, + { + "data_path": "action_result.data.*.jobTitle", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.mail", + "data_type": "string", + "contains": [ + "email" + ], + "example_values": [ + "test@testdomain.abc.com" + ] + }, + { + "data_path": "action_result.data.*.mobilePhone", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.officeLocation", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.preferredLanguage", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.surname", + "data_type": "string", + "example_values": [ + "Globaltest" + ], + "column_name": "Surname", + "column_order": 4 + }, + { + "data_path": "action_result.data.*.userPrincipalName", + "data_type": "string", + "example_values": [ + "test@testdomain.abc.com" + ], + "contains": [ + "msgoffice365 user principal name", + "email" + ], + "column_name": "User Principal Name", + "column_order": 1 + }, + { + "data_path": "action_result.summary.total_members_returned", + "data_type": "numeric", + "example_values": [ + 9 + ] + }, + { + "data_path": "action_result.message", + "data_type": "string", + "example_values": [ + "Successfully retrieved 9 groups" + ] + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "render": { + "width": 12, + "title": "List Group Members", + "type": "table", + "height": 5 + }, + "versions": "EQ(*)" + }, + { + "action": "list folders", + "identifier": "list_folders", + "description": "Retrieve a list of mail folders", + "verbose": "If you want to list all the child folders (includes all the sub-levels) of the specific parent folder, then, you have to provide the parent folder_id parameter. If you don't provide folder_id it will list all the folders on Office 365 account (includes all the sub-level folders).", + "type": "investigate", + "read_only": true, + "parameters": { + "user_id": { + "description": "User ID/Principal name", + "data_type": "string", + "required": true, + "primary": true, + "order": 0, + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" + ] + }, + "folder_id": { + "description": "Parent mail folder ID", + "data_type": "string", + "primary": true, + "order": 1, + "contains": [ + "msgoffice365 folder id" + ] + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.folder_id", + "data_type": "string", + "example_values": [ + "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA=" + ], + "contains": [ + "msgoffice365 folder id" + ] + }, + { + "data_path": "action_result.parameter.user_id", + "data_type": "string", + "example_values": [ + "test@testdomain.abc.com" + ], + "contains": [ + "msgoffice365 user id", + "msgoffice365 user principal name", + "email" + ] + }, + { + "data_path": "action_result.data.*.childFolderCount", + "data_type": "numeric", + "example_values": [ + 1 + ], + "column_name": "Child Folder Count", + "column_order": 3 + }, + { + "data_path": "action_result.data.*.displayName", + "data_type": "string", + "example_values": [ + "test" + ], + "column_name": "Display Name", + "column_order": 0 + }, + { + "data_path": "action_result.data.*.id", + "data_type": "string", + "example_values": [ + "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAD9nLiRAAA=" + ], + "column_name": "Folder ID", + "column_order": 1, + "contains": [ + "msgoffice365 folder id" + ] + }, + { + "data_path": "action_result.data.*.isHidden", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.data.*.parentFolderId", + "data_type": "string", + "example_values": [ + "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAAAAAEIAAA=" + ], + "column_name": "Parent Folder ID", + "column_order": 2, + "contains": [ "msgoffice365 folder id" ] }, @@ -2011,7 +2402,7 @@ "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "plain text?\r\n" + "`plain text?\\r\\n`" ] }, { @@ -2447,7 +2838,7 @@ "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "plain text?\r\n" + "`plain text?\\r\\n`" ] }, { @@ -3196,7 +3587,7 @@ "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "Have a good time with these.\r\n" + "`Have a good time with these.\\r\\n`" ] }, { @@ -3336,7 +3727,7 @@ "data_path": "action_result.data.*.event.body.content", "data_type": "string", "example_values": [ - "plain text?\r\n" + "`plain text?\\r\\n`" ] }, { @@ -4347,19 +4738,11 @@ "msgoffice365 folder id" ], "example_values": [ - "AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAA" - ] - }, - { - "data_path": "action_result.data.*.previousEndDateTime", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.previousLocation", - "data_type": "string" + "AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAADyW3X5P7Hb0_MMHKonvdoWQEAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAA" + ] }, { - "data_path": "action_result.data.*.previousStartDateTime", + "data_path": "action_result.data.*.previousEndDateTime", "data_type": "string" }, { @@ -4376,6 +4759,14 @@ "UTC" ] }, + { + "data_path": "action_result.data.*.previousLocation", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.previousStartDateTime", + "data_type": "string" + }, { "data_path": "action_result.data.*.previousStartDateTime.dateTime", "data_type": "string", @@ -4673,652 +5064,941 @@ ] }, { - "data_path": "action_result.data.*.@odata.etag", + "data_path": "action_result.data.*.@odata.etag", + "data_type": "string", + "example_values": [ + "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAO8DBJl\"" + ] + }, + { + "data_path": "action_result.data.*.body.content", + "data_type": "string", + "example_values": [ + "`\\r\\n

HTML heading

HTML body.`" + ] + }, + { + "data_path": "action_result.data.*.body.contentType", + "data_type": "string", + "example_values": [ + "html" + ] + }, + { + "data_path": "action_result.data.*.id", + "data_type": "string", + "example_values": [ + "AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA==" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Accept-Language", + "data_type": "string", + "example_values": [ + "en-US" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Authentication-Results", + "data_type": "string", + "example_values": [ + "spf=pass (sender IP is 209.85.210.171) smtp.mailfrom=testdomain.com; .abc.com; dkim=pass (signature was verified) header.d=testdomain.com.20150623.gappssmtp.com;.abc.com; dmarc=pass action=none header.from=testdomain.com;compauth=pass reason=100" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Content-Language", + "data_type": "string", + "example_values": [ + "en-US" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Content-Transfer-Encoding", + "data_type": "string", + "example_values": [ + "binary" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Content-Type", + "data_type": "string", + "example_values": [ + "multipart/related" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.DKIM-Signature", + "data_type": "string", + "example_values": [ + "v=1; a=rsa-sha256; c=relaxed/relaxed; d=testdomain.com.20150623.gappssmtp.com; s=20150623; h=message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=avAAeJ8jF08K4oIBhxTirRmyB+SXHwdU0zdxv7eqs/zWaWWcgmT0007KP560TTgo5u oD4nb6TvKxpRyWW4QwmkbuMIwHsMvehd2l1gispV3AawyGJjpmN7ErVYfLtIkz2Tap3V YxmluV+SqeyyxTU8pFAEZ7+2C2lOb1DO5TC7xCMv+dyzevSscJdbeN0dFkG+C93zCqkg w2fxubx2HDD7b/U6m2wXllYhH608wKJ/qYzyvQyqxYqNiQOtPRg2gw4sZ2UgN3+UQyVq 8ubO39ZuqakJpzEzYMw10d6E7SQhvHDJH7mFwhBlzhvOpb2gLJDN8n8dJaZo05BozQqq MsvA==" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Date", + "data_type": "string", + "example_values": [ + "Thu, 18 Jun 2020 02:11:26 -0700" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.From", + "data_type": "string", + "example_values": [ + "\"Test\" " + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.In-Reply-To", + "data_type": "string", + "example_values": [ + "" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.MIME-Version", + "data_type": "string", + "example_values": [ + "1.0" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Message-ID", + "data_type": "string", + "example_values": [ + "<5eeb2fbe.1c69fb81.22b4b.676a@mx.test.com>" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Received", + "data_type": "string", + "example_values": [ + "from localhost.localdomain (host-240.test.com. [204.107.141.240]) by tset.abc.com with UTF8SMTPSA id ng12sm1923252pjb.15.2020.06.18.02.11.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jun 2020 02:11:26 -0700 (PDT)" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Received-SPF", + "data_type": "string", + "example_values": [ + "Pass (protection.test.com: domain of testdomain.com designates 209.85.210.171 as permitted sender) receiver=protection.test.com; client-ip=209.85.210.171; helo=mail-pf1-f171.test.com;" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.References", + "data_type": "string", + "example_values": [ + "" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Return-Path", + "data_type": "string", + "example_values": [ + "notifications@testdomain.com" + ], + "contains": [ + "email" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Subject", + "data_type": "string", + "example_values": [ + "Fw: Email having different attachments" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Thread-Index", + "data_type": "string", + "example_values": [ + "AQHWZLqyXR4k4Sc6skyFCMPITcMsbKpGS7Bm" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.Thread-Topic", + "data_type": "string", + "example_values": [ + "Email having different attachments" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.To", + "data_type": "string", + "example_values": [ + "\"Test\" " + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-EOPAttributedMessage", + "data_type": "string", + "example_values": [ + "0" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-EOPTenantAttributedMessage", + "data_type": "string", + "example_values": [ + "a417c578-c7ee-480d-a225-d48057e74df5:0" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-Forefront-Antispam-Report", + "data_type": "string", + "example_values": [ + "CIP:209.85.210.171;CTRY:US;LANG:en;SCL:-1;SRV:;IPV:NLI;SFV:SFE;H:mail-pf1-f171.test.com;PTR:mail-pf1-f171.test.com;CAT:NONE;SFTY:;SFS:;DIR:INB;SFP:;" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-Gm-Message-State", + "data_type": "string", + "example_values": [ + "AOAM533ynFERIhSIewEEkj4b8B1rPNOEeie1IxBdrd55treEMtBa1jkL\tcO5ee4Ff6p0FYedfFtVtHKiCglGTpFTOSw==" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-Google-DKIM-Signature", + "data_type": "string", + "example_values": [ + "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=fPT47NIiheeY6GM0bxUOlsmnOgN4WuiOlalFvZqrAiFiOoYk6zrznvgIcAtiHZ4nxE naQAa+mZs5svqRjib3YI52OvR5U8MitIYaa0Rt3LyYSUO1s3iKTUs4nHyRnqPt1skNl7 2OUwsZPXo3ShJDw/uxZRu/cuN1iIfeuE02PrbR04p4D8+1XRslqt/Xqm/bOWKUauqZWe dH1E7meFY01hXxODreO4nWHIhsZgr49TpP/OqRyFcyKHHFFg2sPGXz+QNah6jP4YQUYd Tty2wzOX3nc/YS7TkVo3ORmbzh9o+UZaqH8wHbQlyTdklYxoMPvJwZTo72rTxZeqiJ9E J7PQ==" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-Google-Smtp-Source", + "data_type": "string", + "example_values": [ + "ABdhPJxrYC7raBubCCIOmauxmxryzS9KsihTN6XCRgaNp2rDrG71TVxryzYCtelFOZ2Xj1LzcYIiMA==" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData", + "data_type": "string", + "example_values": [ + "VSM9HTzub/OH3NCwKXEQqkkzjnhdw5kXsgd9WM0SRgZ0qRdPg5D9/o3LA7lf8ziXc5k0mm9M5mHvFoYePXNXs/MGhGdBGxa/qUQ+FVHA2mDgfPkamJCEZxz//OX/uruTDo+zF4p9D1dQJpnIpx1M75OhuvrHX/BxWWzyAh78DXfF214YHdyFBCYepwl56CS7+fSGQL/r3p+OvWIBnIkISC+HJljSro2k47pPPAkspMhoUkb+zklyENFjez+JcEHYlih2FiNeUO8kb9b7qvlm3zPK98HLspzDh4BojpQ6Ff330iy7nfIK726tCMByxjOdnEQSB9Ua2sbE5gxSeeWL8MB5DHcQSSsXg+sR8w4gXrXLO3meE0lNQKRoAv2b1U0Q+yM0QBqeQWlymZG21bKeuH4gtAFQvfXNjoCtIbBQK1n7ZnL7fI21FJZRcMcKEneus6gLYUqD4PdLEq9FEGbfgiLmVYeUAL2A0Q/gectvL1OVudtHVR5gFMJKt65F1OtS04CPulfLLFSl1F4AzpjjtBSyQcK9R7bOsjoHxQXPMd9fMCzMSIq5f551pO0klKqWY7l11Un2Noj6CA7EtXiD1bTv8JmYQEKR+0HTZagNd+79GeTvKjxTvt9MkyO8k3aqWyNqT331ITnVICtksN1TVMCp8GVeDudNMr2PLSW0alOduR5unuEgTWrqHoaTGOovQx0PVjudNlpZ80ANK9hqaC/ZhLLOtNpJ3fZnjs06PzrPLGhE/IeccY1n8sYDvGm1QA9TN6JaaGPl1Pj6ecy16k0XuF/PKGHTL0M4LCpxSS6T87oFFH1zHkKtmbJp3aAI4bt3ihbQmwFb29JyMgL7ZOy+zrIwXGILh1KQGWQQv1uXXnAuqQy29HeFXs6D2hDHxHlBk5ZQ+vgRtsvRvGnq58vJ3CapjntfL3pOINUj1avLyAZxjasBWMTwaZs9JQ4ZIMekzkIk05lh9XfDSeULk2yKaH8YSCC6ENUHxSWa6pPHJfOdp9kXwOtlp09/VTTAikKy862k9ybN4bRWZB45B9Pv5scna8IX3rthIXUih8c=" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthAs", + "data_type": "string", + "example_values": [ + "Internal" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthSource", + "data_type": "string", + "example_values": [ + "SJ0QA11MB4941.namprd11.prod.outlook.com" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-FromEntityHeader", + "data_type": "string", + "example_values": [ + "Internet" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Id", + "data_type": "string", + "example_values": [ + "a417c578-c7ee-480d-a225-d48057e74df5" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-MailboxType", + "data_type": "string", + "example_values": [ + "HOSTED" + ] + }, + { + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Network-Message-Id", "data_type": "string", "example_values": [ - "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAO8DBJl\"" + "4b1ef179-4fe7-4248-7ec0-08d81367956e" ] }, { - "data_path": "action_result.data.*.body.content", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-OriginalArrivalTime", "data_type": "string", "example_values": [ - "\r\n

HTML heading

HTML body." + "18 Jun 2020 09:11:28.2511 (UTC)" ] }, { - "data_path": "action_result.data.*.body.contentType", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-UserPrincipalName", "data_type": "string", "example_values": [ - "html" + "bs91VnpEPjrqCnvlIeymwO6ye4Q8rggHggVNUPUbV/tC9uuFPVFOYg7e/Cd0MeGmSqT4AlLW0Nn4ZeEqNieSf/D1gp5iLz/YkwjXhYUSJnLRb/csQN4sRMMZsX3LUkKkwVpifaeJzoukLu8qSWn7og==" ] }, { - "data_path": "action_result.data.*.id", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthAs", "data_type": "string", "example_values": [ - "AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA==" + "Anonymous" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Accept-Language", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthMechanism", "data_type": "string", "example_values": [ - "en-US" + "04" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Authentication-Results", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthSource", "data_type": "string", "example_values": [ - "spf=pass (sender IP is 209.85.210.171) smtp.mailfrom=testdomain.com; .abc.com; dkim=pass (signature was verified) header.d=testdomain.com.20150623.gappssmtp.com;.abc.com; dmarc=pass action=none header.from=testdomain.com;compauth=pass reason=100" + "DM6NAM11FT055.eop-nam11.prod.protection.outlook.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Content-Language", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationInterval", "data_type": "string", "example_values": [ - "en-US" + "1:00:00:00.0000000" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Content-Transfer-Encoding", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationIntervalReason", "data_type": "string", "example_values": [ - "binary" + "OriginalSubmit" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Content-Type", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTime", "data_type": "string", "example_values": [ - "multipart/related" + "18 Jun 2020 09:11:28.2531 (UTC)" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.DKIM-Signature", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTimeReason", "data_type": "string", "example_values": [ - "v=1; a=rsa-sha256; c=relaxed/relaxed; d=testdomain.com.20150623.gappssmtp.com; s=20150623; h=message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=avAAeJ8jF08K4oIBhxTirRmyB+SXHwdU0zdxv7eqs/zWaWWcgmT0007KP560TTgo5u oD4nb6TvKxpRyWW4QwmkbuMIwHsMvehd2l1gispV3AawyGJjpmN7ErVYfLtIkz2Tap3V YxmluV+SqeyyxTU8pFAEZ7+2C2lOb1DO5TC7xCMv+dyzevSscJdbeN0dFkG+C93zCqkg w2fxubx2HDD7b/U6m2wXllYhH608wKJ/qYzyvQyqxYqNiQOtPRg2gw4sZ2UgN3+UQyVq 8ubO39ZuqakJpzEzYMw10d6E7SQhvHDJH7mFwhBlzhvOpb2gLJDN8n8dJaZo05BozQqq MsvA==" + "OriginalSubmit" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Date", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-MessageDirectionality", "data_type": "string", "example_values": [ - "Thu, 18 Jun 2020 02:11:26 -0700" + "Incoming" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.From", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-Network-Message-Id", "data_type": "string", "example_values": [ - "\"Test\" " + "4b1ef179-4fe7-4248-7ec0-08d81367956e" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.In-Reply-To", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-SCL", "data_type": "string", "example_values": [ - "" + "-1" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.MIME-Version", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Processed-By-BccFoldering", "data_type": "string", "example_values": [ - "1.0" + "15.20.3109.017" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Message-ID", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersStamped", "data_type": "string", "example_values": [ - "<5eeb2fbe.1c69fb81.22b4b.676a@mx.test.com>" + "BN6PR18MB1492" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Received", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Transport-EndToEndLatency", "data_type": "string", "example_values": [ - "from localhost.localdomain (host-240.test.com. [204.107.141.240]) by tset.abc.com with UTF8SMTPSA id ng12sm1923252pjb.15.2020.06.18.02.11.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jun 2020 02:11:26 -0700 (PDT)" + "00:00:02.7417647" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Received-SPF", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Has-Attach", "data_type": "string", "example_values": [ - "Pass (protection.test.com: domain of testdomain.com designates 209.85.210.171 as permitted sender) receiver=protection.test.com; client-ip=209.85.210.171; helo=mail-pf1-f171.test.com;" + "yes" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.References", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Office365-Filtering-Correlation-Id", "data_type": "string", "example_values": [ - "" + "4b1ef179-4fe7-4248-7ec0-08d81367956e" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Return-Path", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Oob-TLC-OOBClassifiers", "data_type": "string", "example_values": [ - "notifications@testdomain.com" - ], - "contains": [ - "email" + "OLM:1728;" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Subject", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-PublicTrafficType", "data_type": "string", "example_values": [ - "Fw: Email having different attachments" + "Email" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Thread-Index", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-TNEF-Correlator", "data_type": "string", "example_values": [ - "AQHWZLqyXR4k4Sc6skyFCMPITcMsbKpGS7Bm" + "" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.Thread-Topic", + "data_path": "action_result.data.*.internetMessageHeaders.X-MS-TrafficTypeDiagnostic", "data_type": "string", "example_values": [ - "Email having different attachments" + "BN6PR18MB1492:" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.To", + "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam", "data_type": "string", "example_values": [ - "\"Test\" " + "BCL:0;" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-EOPAttributedMessage", + "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam-Mailbox-Delivery", "data_type": "string", "example_values": [ - "0" + "wl:1;pcwl:1;ucf:0;jmr:0;auth:0;dest:I;ENG:(750128)(520011016)(520004050)(702028)(944506458)(944626604);" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-EOPTenantAttributedMessage", + "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam-Message-Info", "data_type": "string", "example_values": [ - "a417c578-c7ee-480d-a225-d48057e74df5:0" + "La+CSxAnpzVJOXq7njrFPhIbsh0khleSwldy+W8NYDRsoyyPruPIiId4Avama7JyfzrxoExzhLk5pDn2lGPAJIpdcguiDSsDQg5T+iBCJgFeaEJXjhstECMi842/JGawB9WsiGw9Q/PpvjO5H/2fNLlQZVZW3AAQVZSsX3az4iOsv1Ggj4aYZRMKHmPAtniWOEtQD7zAEWC0jIZf613lWy3vxHfb/3+pV9X8zqPqazbyGy5Q14PICSNkKnvIw8rmeqJV8eSHhvR51Lchib6OIN4xOpLWxkSkBTt5B95RUPnpgPvgp2yLo0Q+EYRIabLDQ0kMsv+24+RnFmr9vo2gRNuFusw8iEPsVEQyhfgIWtBtsBpyvyykxcfa6lIdzQhixZH3Tlkdh1kb15wFS3Ooz3CjaWbY8jcUot5l1p08Ypsj6r7CpIo3xE6jE0x/EeUkDK3Fu/Ol0pOsJ1N5W4iJLdjqSQM3l/t9QWlcPhD8s6D7D7JM5OUHCeFEPr7sSL+P/5zTgBaeUvwtZrlQSH2GHc+5gPW8rkwlwJLJftVEid0gO2PUOrzItzME5PXYAcdx++sF3XC1YMPLet/jMpX8T7/z7+hxFxNyifgmGJ+DkNOec7yGkkcLBz6iCaHx7OrRGwDHIcdAtV85wCk3NEDDiKyHivQpwp/gY55W+wkLe7aqSHmFzm1rUSslx+DWz8w2EgSjJxOmf0JkoNKbTFl3FObkocR0lUUQUnETuoAXUqvpWGD5B69W9XXUM8c43ozz2oBZseheSAtkLil3tMIr/CMCMILPX/LdoErNtkmiFXCPqaLFSSeyO61oCMl6Ezndtwp22nwMPUg5ofG0kdqFuTW122umhy9C6h5BcREaLhWclSyqDoZPB9RvkRlI2kTRwuwbuFW3iOMzmVwxLIQH9K5JkxdMvC3hvNpjVgz7Q2ZnEF3xSNqeoWVQvkaIe8rQLUc8s+HMRUmSERGdfSuQJAx47g8PDs9s3rS/ThUSzIaljJPbUgXEnFg/G6h3I/yXLj2Nj2OG50snoI5jJmE4+69YmNwasdDZuYpnuQeFgu11HtsLniDthJdjEJyYC1utZNt9hgA+6JlLnm7Dxb43cSIiW8ev+3X+b2kREj2k/m8fSz7YgtoCB8AkuiVXRaH3EUiq8XCExbbWeynKRgwCZ6bzvfSiT3+cg+QQKPHFc/cgot56ta6X80tjhFodpTQNTE6V6C9QFHJ3JCVhsSzVifJAc8crI5hAcPbKFEIjinENcfpF/8reo2Yr1xFElhoX" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Forefront-Antispam-Report", + "data_path": "action_result.data.*.internetMessageHeaders.X-Originating-IP", "data_type": "string", "example_values": [ - "CIP:209.85.210.171;CTRY:US;LANG:en;SCL:-1;SRV:;IPV:NLI;SFV:SFE;H:mail-pf1-f171.test.com;PTR:mail-pf1-f171.test.com;CAT:NONE;SFTY:;SFS:;DIR:INB;SFP:;" + "[2.39.180.162]" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Gm-Message-State", + "data_path": "action_result.data.*.internetMessageHeaders.X-Received", "data_type": "string", "example_values": [ - "AOAM533ynFERIhSIewEEkj4b8B1rPNOEeie1IxBdrd55treEMtBa1jkL\tcO5ee4Ff6p0FYedfFtVtHKiCglGTpFTOSw==" + "by 2002:aa7:84d9:: with SMTP id x25mr2807688pfn.300.1592471487394; Thu, 18 Jun 2020 02:11:27 -0700 (PDT)" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Google-DKIM-Signature", + "data_path": "action_result.data.*.internetMessageHeaders.subject", "data_type": "string", "example_values": [ - "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:date:mime-version:from:to:subject; bh=tlTaRbacq4aWozhUPvcWg8i8flbpYQGZNs27nncn83I=; b=fPT47NIiheeY6GM0bxUOlsmnOgN4WuiOlalFvZqrAiFiOoYk6zrznvgIcAtiHZ4nxE naQAa+mZs5svqRjib3YI52OvR5U8MitIYaa0Rt3LyYSUO1s3iKTUs4nHyRnqPt1skNl7 2OUwsZPXo3ShJDw/uxZRu/cuN1iIfeuE02PrbR04p4D8+1XRslqt/Xqm/bOWKUauqZWe dH1E7meFY01hXxODreO4nWHIhsZgr49TpP/OqRyFcyKHHFFg2sPGXz+QNah6jP4YQUYd Tty2wzOX3nc/YS7TkVo3ORmbzh9o+UZaqH8wHbQlyTdklYxoMPvJwZTo72rTxZeqiJ9E J7PQ==" + "test html" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Google-Smtp-Source", + "data_path": "action_result.data.*.receivedDateTime", "data_type": "string", "example_values": [ - "ABdhPJxrYC7raBubCCIOmauxmxryzS9KsihTN6XCRgaNp2rDrG71TVxryzYCtelFOZ2Xj1LzcYIiMA==" + "2020-06-18T09:11:31Z" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-AntiSpam-MessageData", + "data_path": "action_result.data.*.sender.emailAddress.address", "data_type": "string", "example_values": [ - "VSM9HTzub/OH3NCwKXEQqkkzjnhdw5kXsgd9WM0SRgZ0qRdPg5D9/o3LA7lf8ziXc5k0mm9M5mHvFoYePXNXs/MGhGdBGxa/qUQ+FVHA2mDgfPkamJCEZxz//OX/uruTDo+zF4p9D1dQJpnIpx1M75OhuvrHX/BxWWzyAh78DXfF214YHdyFBCYepwl56CS7+fSGQL/r3p+OvWIBnIkISC+HJljSro2k47pPPAkspMhoUkb+zklyENFjez+JcEHYlih2FiNeUO8kb9b7qvlm3zPK98HLspzDh4BojpQ6Ff330iy7nfIK726tCMByxjOdnEQSB9Ua2sbE5gxSeeWL8MB5DHcQSSsXg+sR8w4gXrXLO3meE0lNQKRoAv2b1U0Q+yM0QBqeQWlymZG21bKeuH4gtAFQvfXNjoCtIbBQK1n7ZnL7fI21FJZRcMcKEneus6gLYUqD4PdLEq9FEGbfgiLmVYeUAL2A0Q/gectvL1OVudtHVR5gFMJKt65F1OtS04CPulfLLFSl1F4AzpjjtBSyQcK9R7bOsjoHxQXPMd9fMCzMSIq5f551pO0klKqWY7l11Un2Noj6CA7EtXiD1bTv8JmYQEKR+0HTZagNd+79GeTvKjxTvt9MkyO8k3aqWyNqT331ITnVICtksN1TVMCp8GVeDudNMr2PLSW0alOduR5unuEgTWrqHoaTGOovQx0PVjudNlpZ80ANK9hqaC/ZhLLOtNpJ3fZnjs06PzrPLGhE/IeccY1n8sYDvGm1QA9TN6JaaGPl1Pj6ecy16k0XuF/PKGHTL0M4LCpxSS6T87oFFH1zHkKtmbJp3aAI4bt3ihbQmwFb29JyMgL7ZOy+zrIwXGILh1KQGWQQv1uXXnAuqQy29HeFXs6D2hDHxHlBk5ZQ+vgRtsvRvGnq58vJ3CapjntfL3pOINUj1avLyAZxjasBWMTwaZs9JQ4ZIMekzkIk05lh9XfDSeULk2yKaH8YSCC6ENUHxSWa6pPHJfOdp9kXwOtlp09/VTTAikKy862k9ybN4bRWZB45B9Pv5scna8IX3rthIXUih8c=" + "notifications@testdomain.com" + ], + "contains": [ + "email" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthAs", + "data_path": "action_result.data.*.sender.emailAddress.name", "data_type": "string", "example_values": [ - "Internal" + "notifications@testdomain.com" + ], + "contains": [ + "email" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-AuthSource", + "data_path": "action_result.data.*.subject", "data_type": "string", "example_values": [ - "SJ0QA11MB4941.namprd11.prod.outlook.com" + "test html" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-FromEntityHeader", + "data_path": "action_result.data.*.uniqueBody.content", "data_type": "string", "example_values": [ - "Internet" + "
\\r\\n
\\r\\n

HTML heading

\\r\\nHTML body.
\\r\\n
\\r\\n" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Id", + "data_path": "action_result.data.*.uniqueBody.contentType", "data_type": "string", "example_values": [ - "a417c578-c7ee-480d-a225-d48057e74df5" + "html" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-MailboxType", + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", "data_type": "string", "example_values": [ - "HOSTED" + "Successfully fetched email" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-Network-Message-Id", - "data_type": "string", + "data_path": "summary.total_objects", + "data_type": "numeric", "example_values": [ - "4b1ef179-4fe7-4248-7ec0-08d81367956e" + 1 ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-OriginalArrivalTime", - "data_type": "string", + "data_path": "summary.total_objects_successful", + "data_type": "numeric", "example_values": [ - "18 Jun 2020 09:11:28.2511 (UTC)" + 1 ] + } + ], + "render": { + "type": "json" + }, + "versions": "EQ(*)" + }, + { + "action": "run query", + "identifier": "run_query", + "description": "Search emails", + "verbose": "If the query or internet_message_id parameters are included, the subject, sender, body, and range parameters will be ignored. The internet_message_id parameter will take precedence over the query parameter.

For information on formatting the query parameter, see https://developer.microsoft.com/en-us/graph/docs/concepts/query_parameters.

If the limit parameter is not included, the action will default to limiting to ten emails that match the rest of the query. The get_folder_id parameter should be enabled only when you specified folder name/folder path in the folder parameter. If you provide folder ID in the folder parameter and set get_folder_id parameter to true, it will throw an error of folder ID not found for given folder name (because the action considers folder parameter value as folder name/folder path). The folder parameter must be either a (case sensitive) well-known name [list here; https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0] or the internal o365 folder ID. The action supports searching for a folder that is nested within another. To copy in such a folder, specify the complete folder path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.
When the search_well_known_folders parameter is set to true, action will ignore values provided in the folder and get_folder_id parameters and the user will get details from all 17 well-known folders which are listed below:
  • Archive
  • Clutter
  • Conflicts
  • Conversation History
  • Deleted Items
  • Drafts
  • Inbox
  • Junk Email
  • Local Failures
  • Msg Folder Root
  • Outbox
  • Recoverable Items Deletions
  • Scheduled
  • Search Folders
  • Sent Items
  • Server Failures
  • Sync Issues

If the limit parameter is provided, the user will get the number of messages provided in the limit from every folder if present.", + "type": "investigate", + "read_only": true, + "parameters": { + "email_address": { + "description": "User's email (mailbox to search in)", + "data_type": "string", + "required": true, + "primary": true, + "contains": [ + "email" + ], + "order": 0 + }, + "folder": { + "description": "Destination folder; this must be either a (case-sensitive) well-known name or the internal o365 folder ID", + "data_type": "string", + "primary": true, + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path", + "msgoffice365 folder id" + ], + "default": "Inbox", + "order": 1 + }, + "search_well_known_folders": { + "description": "Checks all well known folders for messages, ignores folder name provided in parameter", + "data_type": "boolean", + "order": 2 + }, + "get_folder_id": { + "description": "Assume the folder parameter contains a folder name/folder path, separated by '/'(forward slash) ; i.e. Inbox/dir1/dir2/dir3. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value", + "data_type": "boolean", + "default": true, + "order": 3 + }, + "subject": { + "description": "Substring to search in subject", + "data_type": "string", + "primary": true, + "contains": [ + "msgoffice365 subject" + ], + "order": 4 + }, + "body": { + "description": "Substring to search in body", + "data_type": "string", + "order": 5 + }, + "sender": { + "description": "Sender email address to match", + "data_type": "string", + "primary": true, + "contains": [ + "email" + ], + "order": 6 + }, + "limit": { + "description": "Maximum emails to return", + "data_type": "numeric", + "order": 7 + }, + "query": { + "description": "MS Graph query string", + "data_type": "string", + "order": 8 }, + "internet_message_id": { + "description": "Internet message ID", + "data_type": "string", + "primary": true, + "contains": [ + "msgoffice365 internet message id" + ], + "order": 9 + } + }, + "output": [ { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-CrossTenant-UserPrincipalName", + "data_path": "action_result.status", "data_type": "string", "example_values": [ - "bs91VnpEPjrqCnvlIeymwO6ye4Q8rggHggVNUPUbV/tC9uuFPVFOYg7e/Cd0MeGmSqT4AlLW0Nn4ZeEqNieSf/D1gp5iLz/YkwjXhYUSJnLRb/csQN4sRMMZsX3LUkKkwVpifaeJzoukLu8qSWn7og==" + "success", + "failed" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthAs", + "data_path": "action_result.parameter.body", "data_type": "string", "example_values": [ - "Anonymous" + "How are you doing this fine evening?" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthMechanism", + "data_path": "action_result.parameter.email_address", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "04" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-AuthSource", + "data_path": "action_result.parameter.folder", "data_type": "string", + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path", + "msgoffice365 folder id" + ], "example_values": [ - "DM6NAM11FT055.eop-nam11.prod.protection.outlook.com" + "Archive" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationInterval", - "data_type": "string", + "data_path": "action_result.parameter.get_folder_id", + "data_type": "boolean", "example_values": [ - "1:00:00:00.0000000" + true, + false ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationIntervalReason", + "data_path": "action_result.parameter.internet_message_id", "data_type": "string", + "contains": [ + "msgoffice365 internet message id" + ], "example_values": [ - "OriginalSubmit" + "" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTime", - "data_type": "string", + "data_path": "action_result.parameter.limit", + "data_type": "numeric", "example_values": [ - "18 Jun 2020 09:11:28.2531 (UTC)" + 5 ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-ExpirationStartTimeReason", + "data_path": "action_result.parameter.query", "data_type": "string", "example_values": [ - "OriginalSubmit" + "$filter=contains(subject,'Urgent')" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-MessageDirectionality", - "data_type": "string", + "data_path": "action_result.parameter.search_well_known_folders", + "data_type": "boolean", "example_values": [ - "Incoming" + true, + false ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-Network-Message-Id", + "data_path": "action_result.parameter.sender", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "4b1ef179-4fe7-4248-7ec0-08d81367956e" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Organization-SCL", + "data_path": "action_result.parameter.subject", "data_type": "string", "example_values": [ - "-1" + "Just wanted to say hello" + ], + "contains": [ + "msgoffice365 subject" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Processed-By-BccFoldering", + "data_path": "action_result.data.*.@odata.etag", "data_type": "string", "example_values": [ - "15.20.3109.017" + "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE\"" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "data_path": "action_result.data.*.@odata.type", "data_type": "string", "example_values": [ - "BN6PR18MB1492" + "#test.abc.eventMessageRequests" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Exchange-Transport-EndToEndLatency", - "data_type": "string", - "example_values": [ - "00:00:02.7417647" - ] + "data_path": "action_result.data.*.allowNewTimeProposals", + "data_type": "string" }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Has-Attach", + "data_path": "action_result.data.*.bccRecipients.*.emailAddress.address", "data_type": "string", "example_values": [ - "yes" + "test3.test@gmail.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Office365-Filtering-Correlation-Id", + "data_path": "action_result.data.*.bccRecipients.*.emailAddress.name", "data_type": "string", "example_values": [ - "4b1ef179-4fe7-4248-7ec0-08d81367956e" + "test3.test@gmail.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-Oob-TLC-OOBClassifiers", + "data_path": "action_result.data.*.bccRecipients.email", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "OLM:1728;" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-PublicTrafficType", + "data_path": "action_result.data.*.bccRecipients.name", "data_type": "string", "example_values": [ - "Email" + "Test Name" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-TNEF-Correlator", + "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "" + "`\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n
\\r\\nTest
\\r\\n
\\r\\n\\r\\n\\r\\n`" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-MS-TrafficTypeDiagnostic", + "data_path": "action_result.data.*.body.contentType", "data_type": "string", "example_values": [ - "BN6PR18MB1492:" + "text" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam", + "data_path": "action_result.data.*.bodyPreview", "data_type": "string", "example_values": [ - "BCL:0;" + "How are you doing this fine evening?" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam-Mailbox-Delivery", - "data_type": "string", - "example_values": [ - "wl:1;pcwl:1;ucf:0;jmr:0;auth:0;dest:I;ENG:(750128)(520011016)(520004050)(702028)(944506458)(944626604);" - ] + "data_path": "action_result.data.*.categories", + "data_type": "string" }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Microsoft-Antispam-Message-Info", + "data_path": "action_result.data.*.ccRecipients.*.emailAddress.address", "data_type": "string", "example_values": [ - "La+CSxAnpzVJOXq7njrFPhIbsh0khleSwldy+W8NYDRsoyyPruPIiId4Avama7JyfzrxoExzhLk5pDn2lGPAJIpdcguiDSsDQg5T+iBCJgFeaEJXjhstECMi842/JGawB9WsiGw9Q/PpvjO5H/2fNLlQZVZW3AAQVZSsX3az4iOsv1Ggj4aYZRMKHmPAtniWOEtQD7zAEWC0jIZf613lWy3vxHfb/3+pV9X8zqPqazbyGy5Q14PICSNkKnvIw8rmeqJV8eSHhvR51Lchib6OIN4xOpLWxkSkBTt5B95RUPnpgPvgp2yLo0Q+EYRIabLDQ0kMsv+24+RnFmr9vo2gRNuFusw8iEPsVEQyhfgIWtBtsBpyvyykxcfa6lIdzQhixZH3Tlkdh1kb15wFS3Ooz3CjaWbY8jcUot5l1p08Ypsj6r7CpIo3xE6jE0x/EeUkDK3Fu/Ol0pOsJ1N5W4iJLdjqSQM3l/t9QWlcPhD8s6D7D7JM5OUHCeFEPr7sSL+P/5zTgBaeUvwtZrlQSH2GHc+5gPW8rkwlwJLJftVEid0gO2PUOrzItzME5PXYAcdx++sF3XC1YMPLet/jMpX8T7/z7+hxFxNyifgmGJ+DkNOec7yGkkcLBz6iCaHx7OrRGwDHIcdAtV85wCk3NEDDiKyHivQpwp/gY55W+wkLe7aqSHmFzm1rUSslx+DWz8w2EgSjJxOmf0JkoNKbTFl3FObkocR0lUUQUnETuoAXUqvpWGD5B69W9XXUM8c43ozz2oBZseheSAtkLil3tMIr/CMCMILPX/LdoErNtkmiFXCPqaLFSSeyO61oCMl6Ezndtwp22nwMPUg5ofG0kdqFuTW122umhy9C6h5BcREaLhWclSyqDoZPB9RvkRlI2kTRwuwbuFW3iOMzmVwxLIQH9K5JkxdMvC3hvNpjVgz7Q2ZnEF3xSNqeoWVQvkaIe8rQLUc8s+HMRUmSERGdfSuQJAx47g8PDs9s3rS/ThUSzIaljJPbUgXEnFg/G6h3I/yXLj2Nj2OG50snoI5jJmE4+69YmNwasdDZuYpnuQeFgu11HtsLniDthJdjEJyYC1utZNt9hgA+6JlLnm7Dxb43cSIiW8ev+3X+b2kREj2k/m8fSz7YgtoCB8AkuiVXRaH3EUiq8XCExbbWeynKRgwCZ6bzvfSiT3+cg+QQKPHFc/cgot56ta6X80tjhFodpTQNTE6V6C9QFHJ3JCVhsSzVifJAc8crI5hAcPbKFEIjinENcfpF/8reo2Yr1xFElhoX" + "test3.test@gmail.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Originating-IP", + "data_path": "action_result.data.*.ccRecipients.*.emailAddress.name", "data_type": "string", "example_values": [ - "[2.39.180.162]" + "test3.test@gmail.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.X-Received", + "data_path": "action_result.data.*.ccRecipients.email", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "by 2002:aa7:84d9:: with SMTP id x25mr2807688pfn.300.1592471487394; Thu, 18 Jun 2020 02:11:27 -0700 (PDT)" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.internetMessageHeaders.subject", + "data_path": "action_result.data.*.ccRecipients.name", "data_type": "string", "example_values": [ - "test html" + "Test Name" ] }, { - "data_path": "action_result.data.*.receivedDateTime", + "data_path": "action_result.data.*.changeKey", "data_type": "string", "example_values": [ - "2020-06-18T09:11:31Z" + "CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE" ] }, { - "data_path": "action_result.data.*.sender.emailAddress.address", + "data_path": "action_result.data.*.conversationId", "data_type": "string", "example_values": [ - "notifications@testdomain.com" - ], - "contains": [ - "email" + "AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQAGqbDRkVLxZMtetM-dKqAPo=" ] }, { - "data_path": "action_result.data.*.sender.emailAddress.name", + "data_path": "action_result.data.*.conversationIndex", "data_type": "string", "example_values": [ - "notifications@testdomain.com" - ], - "contains": [ - "email" + "AQHXHRZ01/QE6F/kQkdaSwXyspIYQagZQ==" ] }, { - "data_path": "action_result.data.*.subject", + "data_path": "action_result.data.*.createdDateTime", "data_type": "string", "example_values": [ - "test html" + "2017-10-30T22:32:42Z" ] }, { - "data_path": "action_result.data.*.uniqueBody.content", + "data_path": "action_result.data.*.endDateTime.dateTime", "data_type": "string", "example_values": [ - "
\r\n
\r\n

HTML heading

\r\nHTML body.
\r\n
\r\n" + "2020-08-15T12:30:00.0000000" ] }, { - "data_path": "action_result.data.*.uniqueBody.contentType", + "data_path": "action_result.data.*.endDateTime.timeZone", "data_type": "string", "example_values": [ - "html" + "UTC" ] }, { - "data_path": "action_result.summary", - "data_type": "string" - }, - { - "data_path": "action_result.message", + "data_path": "action_result.data.*.flag.flagStatus", "data_type": "string", "example_values": [ - "Successfully fetched email" - ] - }, - { - "data_path": "summary.total_objects", - "data_type": "numeric", - "example_values": [ - 1 - ] - }, - { - "data_path": "summary.total_objects_successful", - "data_type": "numeric", - "example_values": [ - 1 + "notFlagged" ] - } - ], - "render": { - "type": "json" - }, - "versions": "EQ(*)" - }, - { - "action": "run query", - "identifier": "run_query", - "description": "Search emails", - "verbose": "If the query or internet_message_id parameters are included, the subject, sender, body, and range parameters will be ignored. The internet_message_id parameter will take precedence over the query parameter.

For information on formatting the query parameter, see https://developer.microsoft.com/en-us/graph/docs/concepts/query_parameters.

If the limit parameter is not included, the action will default to limiting to ten emails that match the rest of the query. The get_folder_id parameter should be enabled only when you specified folder name/folder path in the folder parameter. If you provide folder ID in the folder parameter and set get_folder_id parameter to true, it will throw an error of folder ID not found for given folder name (because the action considers folder parameter value as folder name/folder path). The folder parameter must be either a (case sensitive) well-known name [list here; https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0] or the internal o365 folder ID. The action supports searching for a folder that is nested within another. To copy in such a folder, specify the complete folder path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.
When the search_well_known_folders parameter is set to true, action will ignore values provided in the folder and get_folder_id parameters and the user will get details from all 17 well-known folders which are listed below:
  • Archive
  • Clutter
  • Conflicts
  • Conversation History
  • Deleted Items
  • Drafts
  • Inbox
  • Junk Email
  • Local Failures
  • Msg Folder Root
  • Outbox
  • Recoverable Items Deletions
  • Scheduled
  • Search Folders
  • Sent Items
  • Server Failures
  • Sync Issues

If the limit parameter is provided, the user will get the number of messages provided in the limit from every folder if present.", - "type": "investigate", - "read_only": true, - "parameters": { - "email_address": { - "description": "User's email (mailbox to search in)", - "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "email" - ], - "order": 0 - }, - "folder": { - "description": "Destination folder; this must be either a (case-sensitive) well-known name or the internal o365 folder ID", - "data_type": "string", - "primary": true, - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path", - "msgoffice365 folder id" - ], - "default": "Inbox", - "order": 1 - }, - "search_well_known_folders": { - "description": "Checks all well known folders for messages, ignores folder name provided in parameter", - "data_type": "boolean", - "order": 2 - }, - "get_folder_id": { - "description": "Assume the folder parameter contains a folder name/folder path, separated by '/'(forward slash) ; i.e. Inbox/dir1/dir2/dir3. If this parameter is enabled, it retrieves the folder ID for the provided folder name/folder path automatically and replaces the parameter value", - "data_type": "boolean", - "default": true, - "order": 3 }, - "subject": { - "description": "Substring to search in subject", - "data_type": "string", - "primary": true, - "contains": [ - "msgoffice365 subject" - ], - "order": 4 - }, - "body": { - "description": "Substring to search in body", - "data_type": "string", - "order": 5 - }, - "sender": { - "description": "Sender email address to match", + { + "data_path": "action_result.data.*.from.emailAddress.address", "data_type": "string", - "primary": true, + "example_values": [ + "test@testdomain.abc.com" + ], "contains": [ "email" - ], - "order": 6 - }, - "limit": { - "description": "Maximum emails to return", - "data_type": "numeric", - "order": 7 + ] }, - "query": { - "description": "MS Graph query string", + { + "data_path": "action_result.data.*.from.emailAddress.name", "data_type": "string", - "order": 8 + "example_values": [ + "Test Name" + ] }, - "internet_message_id": { - "description": "Internet message ID", + { + "data_path": "action_result.data.*.hasAttachments", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.data.*.id", "data_type": "string", - "primary": true, "contains": [ - "msgoffice365 internet message id" + "msgoffice365 message id" ], - "order": 9 - } - }, - "output": [ + "example_values": [ + "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA=" + ] + }, { - "data_path": "action_result.status", + "data_path": "action_result.data.*.importance", "data_type": "string", "example_values": [ - "success", - "failed" + "normal" ] }, { - "data_path": "action_result.parameter.body", + "data_path": "action_result.data.*.inferenceClassification", "data_type": "string", "example_values": [ - "How are you doing this fine evening?" + "focused" ] }, { - "data_path": "action_result.parameter.email_address", + "data_path": "action_result.data.*.internetMessageId", "data_type": "string", - "contains": [ - "email" + "example_values": [ + "" ], + "contains": [ + "msgoffice365 internet message id" + ] + }, + { + "data_path": "action_result.data.*.isAllDay", + "data_type": "boolean", "example_values": [ - "test@testdomain.abc.com" + true, + false ] }, { - "data_path": "action_result.parameter.folder", - "data_type": "string", - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path", - "msgoffice365 folder id" - ], + "data_path": "action_result.data.*.isDelegated", + "data_type": "boolean", "example_values": [ - "Archive" + true, + false ] }, { - "data_path": "action_result.parameter.get_folder_id", + "data_path": "action_result.data.*.isDeliveryReceiptRequested", "data_type": "boolean", "example_values": [ true, @@ -5326,31 +6006,31 @@ ] }, { - "data_path": "action_result.parameter.internet_message_id", - "data_type": "string", - "contains": [ - "msgoffice365 internet message id" - ], + "data_path": "action_result.data.*.isDraft", + "data_type": "boolean", "example_values": [ - "" + true, + false ] }, { - "data_path": "action_result.parameter.limit", - "data_type": "numeric", + "data_path": "action_result.data.*.isOutOfDate", + "data_type": "boolean", "example_values": [ - 5 + true, + false ] }, { - "data_path": "action_result.parameter.query", - "data_type": "string", + "data_path": "action_result.data.*.isRead", + "data_type": "boolean", "example_values": [ - "$filter=contains(subject,'Urgent')" + true, + false ] }, { - "data_path": "action_result.parameter.search_well_known_folders", + "data_path": "action_result.data.*.isReadReceiptRequested", "data_type": "boolean", "example_values": [ true, @@ -5358,198 +6038,290 @@ ] }, { - "data_path": "action_result.parameter.sender", + "data_path": "action_result.data.*.lastModifiedDateTime", "data_type": "string", - "contains": [ - "email" - ], "example_values": [ - "test@testdomain.abc.com" + "2017-10-30T22:32:53Z" ] }, { - "data_path": "action_result.parameter.subject", + "data_path": "action_result.data.*.meetingMessageType", "data_type": "string", "example_values": [ - "Just wanted to say hello" - ], + "meetingRequest" + ] + }, + { + "data_path": "action_result.data.*.meetingRequestType", + "data_type": "string", + "example_values": [ + "informationalUpdate" + ] + }, + { + "data_path": "action_result.data.*.parentFolderId", + "data_type": "string", "contains": [ - "msgoffice365 subject" + "msgoffice365 folder id" + ], + "example_values": [ + "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA=" ] }, { - "data_path": "action_result.data.*.@odata.etag", + "data_path": "action_result.data.*.previousEndDateTime", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.previousEndDateTime.dateTime", "data_type": "string", "example_values": [ - "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE\"" + "2020-08-15T12:30:00.0000000" ] }, { - "data_path": "action_result.data.*.@odata.type", + "data_path": "action_result.data.*.previousEndDateTime.timeZone", "data_type": "string", "example_values": [ - "#test.abc.eventMessageRequests" + "UTC" ] }, { - "data_path": "action_result.data.*.allowNewTimeProposals", + "data_path": "action_result.data.*.previousLocation", "data_type": "string" }, { - "data_path": "action_result.data.*.bccRecipients.*.emailAddress.address", + "data_path": "action_result.data.*.previousStartDateTime", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.previousStartDateTime.dateTime", "data_type": "string", "example_values": [ - "test3.test@gmail.com" + "2020-08-15T12:00:00.0000000" ] }, { - "data_path": "action_result.data.*.bccRecipients.*.emailAddress.name", + "data_path": "action_result.data.*.previousStartDateTime.timeZone", "data_type": "string", "example_values": [ - "test3.test@gmail.com" + "UTC" ] }, { - "data_path": "action_result.data.*.bccRecipients.email", + "data_path": "action_result.data.*.receivedDateTime", "data_type": "string", - "contains": [ - "email" - ], "example_values": [ - "test@testdomain.abc.com" + "2017-10-30T22:32:42Z" ] }, { - "data_path": "action_result.data.*.bccRecipients.name", + "data_path": "action_result.data.*.recurrence", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.replyTo", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.replyTo.*.emailAddress.address", "data_type": "string", "example_values": [ - "Test Name" + "hellohi@okta.com" ] }, { - "data_path": "action_result.data.*.body.content", + "data_path": "action_result.data.*.replyTo.*.emailAddress.name", "data_type": "string", "example_values": [ - "\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\nTest
\r\n
\r\n\r\n\r\n" + "hellohi@okta.com" ] }, { - "data_path": "action_result.data.*.body.contentType", + "data_path": "action_result.data.*.responseRequested", + "data_type": "boolean", + "example_values": [ + true, + false + ] + }, + { + "data_path": "action_result.data.*.sender.emailAddress.address", "data_type": "string", "example_values": [ - "text" + "test@testdomain.abc.com" + ], + "contains": [ + "email" ] }, { - "data_path": "action_result.data.*.bodyPreview", + "data_path": "action_result.data.*.sender.emailAddress.name", "data_type": "string", "example_values": [ - "How are you doing this fine evening?" + "Test Name" ] }, { - "data_path": "action_result.data.*.categories", - "data_type": "string" + "data_path": "action_result.data.*.sentDateTime", + "data_type": "string", + "example_values": [ + "2017-10-30T22:32:37Z" + ] }, { - "data_path": "action_result.data.*.ccRecipients.*.emailAddress.address", + "data_path": "action_result.data.*.startDateTime.dateTime", "data_type": "string", "example_values": [ - "test3.test@gmail.com" + "2020-08-15T12:00:00.0000000" ] }, { - "data_path": "action_result.data.*.ccRecipients.*.emailAddress.name", + "data_path": "action_result.data.*.startDateTime.timeZone", "data_type": "string", "example_values": [ - "test3.test@gmail.com" + "UTC" ] }, { - "data_path": "action_result.data.*.ccRecipients.email", + "data_path": "action_result.data.*.subject", "data_type": "string", - "contains": [ - "email" - ], "example_values": [ - "test@testdomain.abc.com" + "Just wanted to say hello" + ], + "contains": [ + "msgoffice365 subject" ] }, { - "data_path": "action_result.data.*.ccRecipients.name", + "data_path": "action_result.data.*.toRecipients.*.emailAddress.address", "data_type": "string", "example_values": [ - "Test Name" + "Test@testdomain.abc.com" + ], + "contains": [ + "email" ] }, { - "data_path": "action_result.data.*.changeKey", + "data_path": "action_result.data.*.toRecipients.*.emailAddress.name", "data_type": "string", "example_values": [ - "CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE" + "Test Name" ] }, { - "data_path": "action_result.data.*.conversationId", + "data_path": "action_result.data.*.type", "data_type": "string", "example_values": [ - "AAQkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAQAGqbDRkVLxZMtetM-dKqAPo=" + "singleInstance" ] }, { - "data_path": "action_result.data.*.conversationIndex", + "data_path": "action_result.data.*.vaultId", "data_type": "string", "example_values": [ - "AQHXHRZ01/QE6F/kQkdaSwXyspIYQagZQ==" + "719dbf72d7c0bc89d7e34306c08a0b66191902b9" + ], + "contains": [ + "sha1", + "vault id" ] }, { - "data_path": "action_result.data.*.createdDateTime", + "data_path": "action_result.data.*.webLink", "data_type": "string", "example_values": [ - "2017-10-30T22:32:42Z" + "https://outlook.office365.com/owa/?ItemID=AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk%2FsdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA%3D&exvsurl=1&viewmodel=ReadMessageItem" + ], + "contains": [ + "url" ] }, { - "data_path": "action_result.data.*.endDateTime.dateTime", - "data_type": "string", + "data_path": "action_result.summary.emails_matched", + "data_type": "numeric", "example_values": [ - "2020-08-15T12:30:00.0000000" + 1 ] }, { - "data_path": "action_result.data.*.endDateTime.timeZone", + "data_path": "action_result.message", "data_type": "string", "example_values": [ - "UTC" + "Emails matched: 1" ] }, { - "data_path": "action_result.data.*.flag.flagStatus", - "data_type": "string", + "data_path": "summary.total_objects", + "data_type": "numeric", "example_values": [ - "notFlagged" + 1 ] }, { - "data_path": "action_result.data.*.from.emailAddress.address", - "data_type": "string", + "data_path": "summary.total_objects_successful", + "data_type": "numeric", "example_values": [ - "test@testdomain.abc.com" - ], + 1 + ] + } + ], + "render": { + "width": 12, + "title": "Run query", + "type": "custom", + "height": 5, + "view": "office365_view.display_view" + }, + "versions": "EQ(*)" + }, + { + "action": "create folder", + "identifier": "create_folder", + "description": "Create a new folder", + "verbose": "Create a new folder either in the mailbox root or inside an existing folder. The action supports creating a folder that is nested within another. To create in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.", + "type": "generic", + "read_only": false, + "parameters": { + "email_address": { + "description": "User's email (mailbox to create folders)", + "data_type": "string", + "required": true, + "primary": true, "contains": [ "email" - ] + ], + "order": 0 + }, + "folder": { + "description": "Folder Name/Path. Use '/'to separate folder elements; i.e. Inbox/dir1/dir2/dir3", + "data_type": "string", + "required": true, + "primary": true, + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ], + "order": 1 }, + "all_subdirs": { + "description": "Make any missing directories in the path if they don't exist instead of failing", + "data_type": "boolean", + "order": 2 + } + }, + "output": [ { - "data_path": "action_result.data.*.from.emailAddress.name", + "data_path": "action_result.status", "data_type": "string", "example_values": [ - "Test Name" + "success", + "failed" ] }, { - "data_path": "action_result.data.*.hasAttachments", + "data_path": "action_result.parameter.all_subdirs", "data_type": "boolean", "example_values": [ true, @@ -5557,65 +6329,70 @@ ] }, { - "data_path": "action_result.data.*.id", + "data_path": "action_result.parameter.email_address", "data_type": "string", "contains": [ - "msgoffice365 message id" + "email" ], "example_values": [ - "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA=" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.importance", + "data_path": "action_result.parameter.folder", "data_type": "string", + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ], "example_values": [ - "normal" + "Archive" ] }, { - "data_path": "action_result.data.*.inferenceClassification", + "data_path": "action_result.data.*.@odata.context", "data_type": "string", "example_values": [ - "focused" + "https://test.abc.com/v1.0/$metadata#users('abc%def.test.com')/mailFolders/$entity" + ], + "contains": [ + "url" ] }, { - "data_path": "action_result.data.*.internetMessageId", + "data_path": "action_result.data.*.@odata.etag", "data_type": "string", "example_values": [ - "" - ], - "contains": [ - "msgoffice365 internet message id" + "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE\"" ] }, { - "data_path": "action_result.data.*.isAllDay", - "data_type": "boolean", + "data_path": "action_result.data.*.childFolderCount", + "data_type": "numeric", "example_values": [ - true, - false + 1 ] }, { - "data_path": "action_result.data.*.isDelegated", - "data_type": "boolean", - "example_values": [ - true, - false - ] + "data_path": "action_result.data.*.displayName", + "data_type": "string", + "column_name": "Display Name", + "column_order": 0 }, { - "data_path": "action_result.data.*.isDeliveryReceiptRequested", - "data_type": "boolean", + "data_path": "action_result.data.*.id", + "data_type": "string", + "column_name": "Folder ID", + "column_order": 1, + "contains": [ + "msgoffice365 folder id" + ], "example_values": [ - true, - false + "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA=" ] }, { - "data_path": "action_result.data.*.isDraft", + "data_path": "action_result.data.*.isHidden", "data_type": "boolean", "example_values": [ true, @@ -5623,578 +6400,638 @@ ] }, { - "data_path": "action_result.data.*.isOutOfDate", - "data_type": "boolean", + "data_path": "action_result.data.*.parentFolderId", + "data_type": "string", + "column_name": "Parent Folder ID", + "column_order": 2, + "contains": [ + "msgoffice365 folder id" + ], "example_values": [ - true, - false + "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA=" ] }, { - "data_path": "action_result.data.*.isRead", - "data_type": "boolean", + "data_path": "action_result.data.*.sizeInBytes", + "data_type": "numeric", "example_values": [ - true, - false + 0 ] }, { - "data_path": "action_result.data.*.isReadReceiptRequested", - "data_type": "boolean", + "data_path": "action_result.data.*.totalItemCount", + "data_type": "numeric", "example_values": [ - true, - false + 1 ] }, { - "data_path": "action_result.data.*.lastModifiedDateTime", - "data_type": "string", + "data_path": "action_result.data.*.unreadItemCount", + "data_type": "numeric", "example_values": [ - "2017-10-30T22:32:53Z" + 1 ] }, { - "data_path": "action_result.data.*.meetingMessageType", + "data_path": "action_result.summary.folder", "data_type": "string", "example_values": [ - "meetingRequest" + "AQMkAMExNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAFA6de0wAAAA==" ] }, { - "data_path": "action_result.data.*.meetingRequestType", - "data_type": "string", + "data_path": "action_result.summary.folders created", + "data_type": "numeric", "example_values": [ - "informationalUpdate" + 1 ] }, { - "data_path": "action_result.data.*.parentFolderId", + "data_path": "action_result.message", "data_type": "string", - "contains": [ - "msgoffice365 folder id" - ], "example_values": [ - "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA=" + "Emails matched: 1" ] }, { - "data_path": "action_result.data.*.previousEndDateTime", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.previousEndDateTime.dateTime", - "data_type": "string", + "data_path": "summary.total_objects", + "data_type": "numeric", "example_values": [ - "2020-08-15T12:30:00.0000000" + 1 ] }, { - "data_path": "action_result.data.*.previousEndDateTime.timeZone", - "data_type": "string", + "data_path": "summary.total_objects_successful", + "data_type": "numeric", "example_values": [ - "UTC" + 1 ] + } + ], + "render": { + "width": 12, + "title": "Create folder", + "type": "table", + "height": 5 + }, + "versions": "EQ(*)" + }, + { + "action": "get folder id", + "identifier": "get_folder_id", + "description": "Get the API ID of the folder", + "verbose": "The action supports searching a folder that is nested within another. To search in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.", + "type": "investigate", + "read_only": true, + "parameters": { + "email_address": { + "description": "User's email (mailbox)", + "data_type": "string", + "required": true, + "primary": true, + "contains": [ + "email" + ], + "order": 0 }, + "folder": { + "description": "Folder Name/Path. Use '/' to separate folder elements; i.e. Inbox/dir1/dir2/dir3", + "data_type": "string", + "required": true, + "primary": true, + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ], + "order": 1 + } + }, + "output": [ { - "data_path": "action_result.data.*.previousLocation", - "data_type": "string" - }, - { - "data_path": "action_result.data.*.previousStartDateTime", - "data_type": "string" + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] }, { - "data_path": "action_result.data.*.previousStartDateTime.dateTime", + "data_path": "action_result.parameter.email_address", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "2020-08-15T12:00:00.0000000" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.previousStartDateTime.timeZone", + "data_path": "action_result.parameter.folder", "data_type": "string", + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ], "example_values": [ - "UTC" + "Test/Testy/subfolders" ] }, { - "data_path": "action_result.data.*.receivedDateTime", + "data_path": "action_result.data.*.folder", "data_type": "string", + "column_name": "Folder Name", + "column_order": 1, + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ], "example_values": [ - "2017-10-30T22:32:42Z" + "Test" ] }, { - "data_path": "action_result.data.*.recurrence", - "data_type": "string" + "data_path": "action_result.data.*.folder_id", + "data_type": "string", + "column_name": "Folder ID", + "column_order": 2, + "example_values": [ + "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCRAAA=" + ], + "contains": [ + "msgoffice365 folder id" + ] }, { - "data_path": "action_result.data.*.replyTo", - "data_type": "string" + "data_path": "action_result.data.*.path", + "data_type": "string", + "column_name": "Path", + "column_order": 0, + "contains": [ + "msgoffice365 mail folder", + "msgoffice365 mail folder path" + ] }, { - "data_path": "action_result.data.*.replyTo.*.emailAddress.address", + "data_path": "action_result.summary.folder_id", "data_type": "string", "example_values": [ - "hellohi@okta.com" + "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA=" + ], + "contains": [ + "msgoffice365 folder id" ] }, { - "data_path": "action_result.data.*.replyTo.*.emailAddress.name", + "data_path": "action_result.message", "data_type": "string", "example_values": [ - "hellohi@okta.com" + "Folder id: AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA=" ] }, { - "data_path": "action_result.data.*.responseRequested", - "data_type": "boolean", + "data_path": "summary.total_objects", + "data_type": "numeric", "example_values": [ - true, - false + 1 ] }, { - "data_path": "action_result.data.*.sender.emailAddress.address", - "data_type": "string", + "data_path": "summary.total_objects_successful", + "data_type": "numeric", "example_values": [ - "test@testdomain.abc.com" - ], + 1 + ] + } + ], + "render": { + "width": 12, + "title": "Get Folder ID", + "type": "table", + "height": 5 + }, + "versions": "EQ(*)" + }, + { + "action": "send email", + "identifier": "send_email", + "description": "Sends an email with optional text rendering. Attachments are allowed a Content-ID tag for reference within the html", + "verbose": "
Notes
  • If the from parameter is not provided, then the action will consider the username parameter provided in the asset configuration as the sender's email address.
  • The send email action is executed in two stages. Before sending an email it creates a draft of the email. Once the draft is successfully saved, the email is sent.
", + "type": "generic", + "read_only": false, + "parameters": { + "from": { + "description": "From field", + "data_type": "string", + "order": 0, + "primary": true, "contains": [ "email" ] }, + "to": { + "description": "List of recipients email addresses", + "data_type": "string", + "order": 1, + "required": true, + "primary": true, + "contains": [ + "email" + ], + "allow_list": true + }, + "cc": { + "description": "List of recipients email addresses to include on cc line", + "data_type": "string", + "order": 2, + "primary": true, + "contains": [ + "email" + ], + "allow_list": true + }, + "bcc": { + "description": "List of recipients email addresses to include on bcc line", + "data_type": "string", + "order": 3, + "contains": [ + "email" + ], + "allow_list": true, + "primary": true + }, + "subject": { + "description": "Message Subject", + "data_type": "string", + "order": 4, + "required": true + }, + "headers": { + "description": "Serialized json dictionary. Additional email headers to be added to the message", + "data_type": "string", + "order": 5 + }, + "body": { + "description": "Html rendering of message", + "data_type": "string", + "order": 6, + "required": true + }, + "attachments": { + "description": "List of vault ids of files to attach to the email. Vault id is used as content id", + "data_type": "string", + "order": 7, + "allow_list": true, + "contains": [ + "sha1", + "vault id" + ], + "primary": true + } + }, + "output": [ { - "data_path": "action_result.data.*.sender.emailAddress.name", + "data_path": "action_result.status", "data_type": "string", "example_values": [ - "Test Name" + "success", + "failed" ] }, { - "data_path": "action_result.data.*.sentDateTime", + "data_path": "action_result.parameter.attachments", "data_type": "string", + "contains": [ + "sha1", + "vault id" + ], "example_values": [ - "2017-10-30T22:32:37Z" + "da39a3ee5e6b4b0d3255bfef95601890afd80709" ] }, { - "data_path": "action_result.data.*.startDateTime.dateTime", + "data_path": "action_result.parameter.bcc", "data_type": "string", + "contains": [ + "email" + ], "example_values": [ - "2020-08-15T12:00:00.0000000" + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.startDateTime.timeZone", + "data_path": "action_result.parameter.body", "data_type": "string", "example_values": [ - "UTC" + "

Have a good time with these.

" ] }, { - "data_path": "action_result.data.*.subject", + "data_path": "action_result.parameter.cc", "data_type": "string", - "example_values": [ - "Just wanted to say hello" - ], "contains": [ - "msgoffice365 subject" + "email" + ], + "example_values": [ + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.toRecipients.*.emailAddress.address", + "data_path": "action_result.parameter.from", "data_type": "string", - "example_values": [ - "Test@testdomain.abc.com" - ], "contains": [ "email" + ], + "example_values": [ + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.toRecipients.*.emailAddress.name", + "data_path": "action_result.parameter.headers", "data_type": "string", "example_values": [ - "Test Name" + "{\"x-custom-header\":\"Custom value\"}" ] }, { - "data_path": "action_result.data.*.type", + "data_path": "action_result.parameter.subject", "data_type": "string", "example_values": [ - "singleInstance" + "Example subject" ] }, { - "data_path": "action_result.data.*.vaultId", + "data_path": "action_result.parameter.to", "data_type": "string", - "example_values": [ - "719dbf72d7c0bc89d7e34306c08a0b66191902b9" - ], "contains": [ - "sha1", - "vault id" + "email" + ], + "example_values": [ + "test@testdomain.abc.com" ] }, { - "data_path": "action_result.data.*.webLink", + "data_path": "action_result.data.*.@odata.context", "data_type": "string", "example_values": [ - "https://outlook.office365.com/owa/?ItemID=AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk%2FsdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA%3D&exvsurl=1&viewmodel=ReadMessageItem" + "https://test.abc.com/v1.0/$metadata#users('user%40.abc.com')/messages(internetMessageHeaders,body,uniqueBody,sender,subject)/$entity" ], "contains": [ "url" ] }, { - "data_path": "action_result.summary.emails_matched", - "data_type": "numeric", + "data_path": "action_result.data.*.@odata.etag", + "data_type": "string", "example_values": [ - 1 + "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAO8DBJl\"" ] }, { - "data_path": "action_result.message", + "data_path": "action_result.data.*.body.content", "data_type": "string", "example_values": [ - "Emails matched: 1" + "`Have a good time with these.\\r\\n`" ] }, { - "data_path": "summary.total_objects", - "data_type": "numeric", + "data_path": "action_result.data.*.body.contentType", + "data_type": "string", "example_values": [ - 1 + "html" ] }, { - "data_path": "summary.total_objects_successful", - "data_type": "numeric", - "example_values": [ - 1 - ] - } - ], - "render": { - "width": 12, - "title": "Run query", - "type": "custom", - "height": 5, - "view": "office365_view.display_view" - }, - "versions": "EQ(*)" - }, - { - "action": "create folder", - "identifier": "create_folder", - "description": "Create a new folder", - "verbose": "Create a new folder either in the mailbox root or inside an existing folder. The action supports creating a folder that is nested within another. To create in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.", - "type": "generic", - "read_only": false, - "parameters": { - "email_address": { - "description": "User's email (mailbox to create folders)", + "data_path": "action_result.data.*.bodyPreview", "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "email" + "example_values": [ + "Have a good time with these." ], - "order": 0 + "column_name": "Body Preview", + "column_order": 2 }, - "folder": { - "description": "Folder Name/Path. Use '/'to separate folder elements; i.e. Inbox/dir1/dir2/dir3", + { + "data_path": "action_result.data.*.changeKey", "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" - ], - "order": 1 + "example_values": [ + "CQAAABYAAADTteE6Q2eCQKSqg19j6T+NAAYzSv5R" + ] }, - "all_subdirs": { - "description": "Make any missing directories in the path if they don't exist instead of failing", - "data_type": "boolean", - "order": 2 - } - }, - "output": [ { - "data_path": "action_result.status", + "data_path": "action_result.data.*.conversationId", "data_type": "string", "example_values": [ - "success", - "failed" + "AAQkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAQAORC3aOpHnZMsHD4-7L40sY=" ] }, { - "data_path": "action_result.parameter.all_subdirs", - "data_type": "boolean", + "data_path": "action_result.data.*.conversationIndex", + "data_type": "string", "example_values": [ - true, - false + "AQHZopYz5ELdo6kedkywcPj/svjSxg==" ] }, { - "data_path": "action_result.parameter.email_address", + "data_path": "action_result.data.*.createdDateTime", "data_type": "string", - "contains": [ - "email" - ], "example_values": [ - "test@testdomain.abc.com" + "2023-06-19T10:09:58Z" ] }, { - "data_path": "action_result.parameter.folder", + "data_path": "action_result.data.*.flag.flagStatus", "data_type": "string", - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" - ], "example_values": [ - "Archive" + "notFlagged" ] }, { - "data_path": "action_result.data.*.@odata.context", + "data_path": "action_result.data.*.from.emailAddress.address", "data_type": "string", "example_values": [ - "https://test.abc.com/v1.0/$metadata#users('abc%def.test.com')/mailFolders/$entity" + "cisco@phantomengineering2.onmicrosoft.com" ], "contains": [ - "url" + "email" ] }, { - "data_path": "action_result.data.*.@odata.etag", + "data_path": "action_result.data.*.from.emailAddress.name", "data_type": "string", "example_values": [ - "W/\"CQAAABYAAABBKXVvwEWISZupmqX4mJS3AAFOpxtE\"" + "Ryan Edwards" ] }, { - "data_path": "action_result.data.*.childFolderCount", - "data_type": "numeric", + "data_path": "action_result.data.*.hasAttachments", + "data_type": "boolean", "example_values": [ - 1 - ] - }, - { - "data_path": "action_result.data.*.displayName", - "data_type": "string", - "column_name": "Display Name", - "column_order": 0 + true, + false + ], + "column_name": "Has Attachments", + "column_order": 3 }, { "data_path": "action_result.data.*.id", "data_type": "string", - "column_name": "Folder ID", - "column_order": 1, + "example_values": [ + "AQMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAADyW3X5P7Hb0_MMHKonvdoWQcAQSl1b8BFiEmbqZql_JiUtwAAAgEMAAAAQSl1b8BFiEmbqZql_JiUtwADu9Tv8QAAAA==" + ], "contains": [ - "msgoffice365 folder id" + "msgoffice365 message id" ], - "example_values": [ - "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQBGAAAAAADJbdfk-sdvT4wwcqie92hZBwBBKXVvwEWISZupmqX4mJS3AACEV3zJAABBKXVvwEWISZupmqX4mJS3AAFOZwS4AAA=" - ] + "column_name": "Message ID", + "column_order": 0 }, { - "data_path": "action_result.data.*.isHidden", - "data_type": "boolean", + "data_path": "action_result.data.*.importance", + "data_type": "string", "example_values": [ - true, - false + "normal" ] }, { - "data_path": "action_result.data.*.parentFolderId", + "data_path": "action_result.data.*.inferenceClassification", "data_type": "string", - "column_name": "Parent Folder ID", - "column_order": 2, - "contains": [ - "msgoffice365 folder id" - ], "example_values": [ - "AAMkADU3NDk3MzJlLTY3MDQtNDE2Ny1iZDk1LTc4YjEwYzhmZDc5YQAuAAAAAADJbdfk-sdvT4wwcqie92hZAQBBKXVvwEWISZupmqX4mJS3AACEV3zJAAA=" + "focused" ] }, { - "data_path": "action_result.data.*.sizeInBytes", - "data_type": "numeric", + "data_path": "action_result.data.*.internetMessageId", + "data_type": "string", "example_values": [ - 0 + "" + ], + "contains": [ + "msgoffice365 internet message id" ] }, { - "data_path": "action_result.data.*.totalItemCount", - "data_type": "numeric", + "data_path": "action_result.data.*.isDeliveryReceiptRequested", + "data_type": "boolean", "example_values": [ - 1 + true, + false ] }, { - "data_path": "action_result.data.*.unreadItemCount", - "data_type": "numeric", + "data_path": "action_result.data.*.isDraft", + "data_type": "boolean", "example_values": [ - 1 + true, + false ] }, { - "data_path": "action_result.summary.folder", - "data_type": "string", + "data_path": "action_result.data.*.isRead", + "data_type": "boolean", "example_values": [ - "AQMkAMExNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAFA6de0wAAAA==" + true, + false ] }, { - "data_path": "action_result.summary.folders created", - "data_type": "numeric", + "data_path": "action_result.data.*.isReadReceiptRequested", + "data_type": "boolean", "example_values": [ - 1 + true, + false ] }, { - "data_path": "action_result.message", + "data_path": "action_result.data.*.lastModifiedDateTime", "data_type": "string", "example_values": [ - "Emails matched: 1" + "2023-06-19T10:09:58Z" ] }, { - "data_path": "summary.total_objects", - "data_type": "numeric", + "data_path": "action_result.data.*.parentFolderId", + "data_type": "string", "example_values": [ - 1 + "AQMkAGYxNGJmOWQyLTlhMjctNGRiOS1iODU0LTA1ZWE3ZmQ3NDU3MQAuAAADeDDJKaEf4EihMWU6SZgKbAEA07XhOkNngkCkqoNfY_k-jQAAAgEPAAAA" + ], + "contains": [ + "msgoffice365 folder id" ] }, { - "data_path": "summary.total_objects_successful", - "data_type": "numeric", + "data_path": "action_result.data.*.receivedDateTime", + "data_type": "string", "example_values": [ - 1 + "2020-06-18T09:11:31Z" ] - } - ], - "render": { - "width": 12, - "title": "Create folder", - "type": "table", - "height": 5 - }, - "versions": "EQ(*)" - }, - { - "action": "get folder id", - "identifier": "get_folder_id", - "description": "Get the API ID of the folder", - "verbose": "The action supports searching a folder that is nested within another. To search in such a folder, specify the complete path using the '/' (forward slash) as the separator.
e.g. to search in a folder named phishing which is nested within (is a child of) Inbox, set the value as Inbox/phishing. If a folder name has a literal forward slash('/') in the name escape it with a backslash('\\') to differentiate.", - "type": "investigate", - "read_only": true, - "parameters": { - "email_address": { - "description": "User's email (mailbox)", - "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "email" - ], - "order": 0 }, - "folder": { - "description": "Folder Name/Path. Use '/' to separate folder elements; i.e. Inbox/dir1/dir2/dir3", - "data_type": "string", - "required": true, - "primary": true, - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" - ], - "order": 1 - } - }, - "output": [ { - "data_path": "action_result.status", + "data_path": "action_result.data.*.sender.emailAddress.address", "data_type": "string", "example_values": [ - "success", - "failed" + "notifications@testdomain.com" + ], + "contains": [ + "email" ] }, { - "data_path": "action_result.parameter.email_address", + "data_path": "action_result.data.*.sender.emailAddress.name", "data_type": "string", + "example_values": [ + "notifications@testdomain.com" + ], "contains": [ "email" - ], - "example_values": [ - "test@testdomain.abc.com" ] }, { - "data_path": "action_result.parameter.folder", + "data_path": "action_result.data.*.sentDateTime", "data_type": "string", - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" - ], "example_values": [ - "Test/Testy/subfolders" + "2023-06-19T10:09:58Z" ] }, { - "data_path": "action_result.data.*.folder", + "data_path": "action_result.data.*.subject", "data_type": "string", - "column_name": "Folder Name", - "column_order": 1, - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" - ], "example_values": [ - "Test" - ] + "test html" + ], + "column_name": "Subject", + "column_order": 1 }, { - "data_path": "action_result.data.*.folder_id", + "data_path": "action_result.data.*.toRecipients.*.emailAddress.address", "data_type": "string", - "column_name": "Folder ID", - "column_order": 2, "example_values": [ - "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCRAAA=" + "cisco@phantomengineering2.onmicrosoft.com" ], "contains": [ - "msgoffice365 folder id" + "email" ] }, { - "data_path": "action_result.data.*.path", + "data_path": "action_result.data.*.toRecipients.*.emailAddress.name", "data_type": "string", - "column_name": "Path", - "column_order": 0, - "contains": [ - "msgoffice365 mail folder", - "msgoffice365 mail folder path" + "example_values": [ + "Ryan Edwards" ] }, { - "data_path": "action_result.summary.folder_id", + "data_path": "action_result.data.*.webLink", "data_type": "string", "example_values": [ - "AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA=" - ], - "contains": [ - "msgoffice365 folder id" + "https://outlook.office365.com/owa/?ItemID=AAkALgAAAAAAHYQDEapmEc2byACqAC%2FEWg0A07XhOkNngkCkqoNfY%2Bk%2FjQAGNNQOowAA&exvsurl=1&viewmodel=ReadMessageItem" ] }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, { "data_path": "action_result.message", "data_type": "string", "example_values": [ - "Folder id: AAMkAGFmNTRhODA4LWIxMjQtNDJjYy05NDM2LWQ5MzY1MGFhMTkzYwAuAAAAAADRlY7ewL4xToKRDciQog5UAQBvUzMoUJx2S4nbgxzZWx2PAAEApxCTAAA=" + "Successfully sent email" ] }, { @@ -6213,10 +7050,7 @@ } ], "render": { - "width": 12, - "title": "Get Folder ID", - "type": "table", - "height": 5 + "type": "table" }, "versions": "EQ(*)" }, @@ -6264,7 +7098,7 @@ "wheel": [ { "module": "Django", - "input_file": "wheels/py3/Django-3.2.15-py3-none-any.whl" + "input_file": "wheels/py3/Django-3.2.19-py3-none-any.whl" }, { "module": "asgiref", @@ -6274,29 +7108,13 @@ "module": "beautifulsoup4", "input_file": "wheels/py3/beautifulsoup4-4.9.1-py3-none-any.whl" }, - { - "module": "certifi", - "input_file": "wheels/py3/certifi-2022.6.15-py3-none-any.whl" - }, - { - "module": "chardet", - "input_file": "wheels/shared/chardet-3.0.4-py2.py3-none-any.whl" - }, - { - "module": "idna", - "input_file": "wheels/shared/idna-2.10-py2.py3-none-any.whl" - }, { "module": "python_magic", "input_file": "wheels/shared/python_magic-0.4.18-py2.py3-none-any.whl" }, { "module": "pytz", - "input_file": "wheels/shared/pytz-2022.2.1-py2.py3-none-any.whl" - }, - { - "module": "requests", - "input_file": "wheels/shared/requests-2.25.0-py2.py3-none-any.whl" + "input_file": "wheels/shared/pytz-2023.3-py2.py3-none-any.whl" }, { "module": "soupsieve", @@ -6304,15 +7122,11 @@ }, { "module": "sqlparse", - "input_file": "wheels/py3/sqlparse-0.4.2-py3-none-any.whl" + "input_file": "wheels/py3/sqlparse-0.4.4-py3-none-any.whl" }, { "module": "typing_extensions", "input_file": "wheels/py3/typing_extensions-4.1.1-py3-none-any.whl" - }, - { - "module": "urllib3", - "input_file": "wheels/shared/urllib3-1.26.12-py2.py3-none-any.whl" } ] }, @@ -6320,51 +7134,31 @@ "wheel": [ { "module": "Django", - "input_file": "wheels/py3/Django-3.2.15-py3-none-any.whl" + "input_file": "wheels/py3/Django-3.2.19-py3-none-any.whl" }, { "module": "asgiref", - "input_file": "wheels/py3/asgiref-3.5.2-py3-none-any.whl" + "input_file": "wheels/py3/asgiref-3.7.2-py3-none-any.whl" }, { "module": "beautifulsoup4", "input_file": "wheels/py3/beautifulsoup4-4.9.1-py3-none-any.whl" }, - { - "module": "certifi", - "input_file": "wheels/py3/certifi-2022.6.15-py3-none-any.whl" - }, - { - "module": "chardet", - "input_file": "wheels/shared/chardet-3.0.4-py2.py3-none-any.whl" - }, - { - "module": "idna", - "input_file": "wheels/shared/idna-2.10-py2.py3-none-any.whl" - }, { "module": "python_magic", "input_file": "wheels/shared/python_magic-0.4.18-py2.py3-none-any.whl" }, { "module": "pytz", - "input_file": "wheels/shared/pytz-2022.2.1-py2.py3-none-any.whl" - }, - { - "module": "requests", - "input_file": "wheels/shared/requests-2.25.0-py2.py3-none-any.whl" + "input_file": "wheels/shared/pytz-2023.3-py2.py3-none-any.whl" }, { "module": "soupsieve", - "input_file": "wheels/py3/soupsieve-2.3.2.post1-py3-none-any.whl" + "input_file": "wheels/py3/soupsieve-2.4.1-py3-none-any.whl" }, { "module": "sqlparse", - "input_file": "wheels/py3/sqlparse-0.4.2-py3-none-any.whl" - }, - { - "module": "urllib3", - "input_file": "wheels/shared/urllib3-1.26.12-py2.py3-none-any.whl" + "input_file": "wheels/py3/sqlparse-0.4.4-py3-none-any.whl" } ] } diff --git a/office365_connector.py b/office365_connector.py index 63a8f40..1e7d656 100644 --- a/office365_connector.py +++ b/office365_connector.py @@ -1,6 +1,6 @@ # File: office365_connector.py # -# Copyright (c) 2017-2022 Splunk Inc. +# Copyright (c) 2017-2023 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import json import os import pwd +import re import sys import tempfile import time @@ -27,6 +28,7 @@ import encryption_helper import phantom.app as phantom import phantom.rules as ph_rules +import phantom.vault as phantom_vault import requests from bs4 import BeautifulSoup, UnicodeDammit from django.http import HttpResponse @@ -53,7 +55,7 @@ def __new__(cls, val1, val2): def _load_app_state(asset_id, app_connector=None): - """ This function is used to load the current state file. + """This function is used to load the current state file. :param asset_id: asset_id :param app_connector: Object of app_connector class @@ -63,42 +65,42 @@ def _load_app_state(asset_id, app_connector=None): asset_id = str(asset_id) if not asset_id or not asset_id.isalnum(): if app_connector: - app_connector.debug_print('In _load_app_state: Invalid asset_id') + app_connector.debug_print("In _load_app_state: Invalid asset_id") return {} app_dir = os.path.dirname(os.path.abspath(__file__)) - state_file = '{0}/{1}_state.json'.format(app_dir, asset_id) + state_file = "{0}/{1}_state.json".format(app_dir, asset_id) real_state_file_path = os.path.abspath(state_file) if not os.path.dirname(real_state_file_path) == app_dir: if app_connector: - app_connector.debug_print('In _load_app_state: Invalid asset_id') + app_connector.debug_print("In _load_app_state: Invalid asset_id") return {} state = {} try: - with open(real_state_file_path, 'r') as state_file_obj: + with open(real_state_file_path, "r") as state_file_obj: state_file_data = state_file_obj.read() state = json.loads(state_file_data) except Exception as e: if app_connector: - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e) app_connector.debug_print('In _load_app_state: {0}'.format(error_msg)) if app_connector: - app_connector.debug_print('Loaded state: ', state) + app_connector.debug_print("Loaded state: ", state) try: state = _decrypt_state(state, asset_id) except Exception as e: if app_connector: - app_connector.debug_print("{}: {}".format(MSGOFFICE365_DECRYPTION_ERR, str(e))) + app_connector.debug_print("{}: {}".format(MSGOFFICE365_DECRYPTION_ERROR, str(e))) state = {} return state def _save_app_state(state, asset_id, app_connector): - """ This function is used to save current state in file. + """This function is used to save current state in file. :param state: Dictionary which contains data to write in state file :param asset_id: asset_id @@ -109,49 +111,54 @@ def _save_app_state(state, asset_id, app_connector): asset_id = str(asset_id) if not asset_id or not asset_id.isalnum(): if app_connector: - app_connector.debug_print('In _save_app_state: Invalid asset_id') + app_connector.debug_print("In _save_app_state: Invalid asset_id") return {} app_dir = os.path.split(__file__)[0] - state_file = '{0}/{1}_state.json'.format(app_dir, asset_id) + state_file = "{0}/{1}_state.json".format(app_dir, asset_id) real_state_file_path = os.path.abspath(state_file) if not os.path.dirname(real_state_file_path) == app_dir: if app_connector: - app_connector.debug_print('In _save_app_state: Invalid asset_id') + app_connector.debug_print("In _save_app_state: Invalid asset_id") return {} try: state = _encrypt_state(state, asset_id) except Exception as e: if app_connector: - app_connector.debug_print("{}: {}".format(MSGOFFICE365_ENCRYPTION_ERR, str(e))) + app_connector.debug_print("{}: {}".format(MSGOFFICE365_ENCRYPTION_ERROR, str(e))) + return phantom.APP_ERROR if app_connector: - app_connector.debug_print('Saving state: ', state) + app_connector.debug_print("Saving state: ", state) try: - with open(real_state_file_path, 'w+') as state_file_obj: + with open(real_state_file_path, "w+") as state_file_obj: state_file_obj.write(json.dumps(state)) except Exception as e: - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e) if app_connector: - app_connector.debug_print('Unable to save state file: {0}'.format(error_msg)) - print('Unable to save state file: {0}'.format(error_msg)) + app_connector.debug_print( + "Unable to save state file: {0}".format(error_msg) + ) + print("Unable to save state file: {0}".format(error_msg)) return phantom.APP_ERROR return phantom.APP_SUCCESS -def _get_error_message_from_exception(e): +def _get_error_msg_from_exception(e, app_connector=None): """ Get appropriate error message from the exception. :param e: Exception object :return: error message """ error_code = None - error_msg = ERR_MSG_UNAVAILABLE + error_msg = ERROR_MSG_UNAVAILABLE + if app_connector: + app_connector.error_print("Error occurred:", e) try: if hasattr(e, "args"): @@ -167,7 +174,8 @@ def _get_error_message_from_exception(e): error_text = "Error Message: {}".format(error_msg) else: error_text = "Error Code: {}. Error Message: {}".format(error_code, error_msg) - + if app_connector: + app_connector.error_print("{}".format(error_text)) return error_text @@ -184,17 +192,34 @@ def _validate_integer(action_result, parameter, key, allow_zero=False): if parameter is not None: try: if not float(parameter).is_integer(): - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_VALID_INT_MSG.format(param=key)), None + return ( + action_result.set_status( + phantom.APP_ERROR, MSGOFFICE365_VALID_INT_MSG.format(param=key) + ), + None, + ) parameter = int(parameter) except Exception: - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_VALID_INT_MSG.format(param=key)), None + return ( + action_result.set_status( + phantom.APP_ERROR, MSGOFFICE365_VALID_INT_MSG.format(param=key) + ), + None, + ) if parameter < 0: - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_NON_NEG_INT_MSG.format(param=key)), None - if not allow_zero and parameter == 0: return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_NON_NEG_NON_ZERO_INT_MSG.format(param=key)), None + if not allow_zero and parameter == 0: + return ( + action_result.set_status( + phantom.APP_ERROR, + MSGOFFICE365_NON_NEG_NON_ZERO_INT_MSG.format(param=key), + ), + None, + ) + return phantom.APP_SUCCESS, parameter @@ -202,74 +227,101 @@ def _handle_oauth_result(request, path_parts): """ ?admin_consent=True&tenant=a417c578-c7ee-480d-a225-d48057e74df5&state=13 """ - asset_id = request.GET.get('state') + asset_id = request.GET.get("state") if not asset_id: - return HttpResponse("ERROR: Asset ID not found in URL\n{0}".format(json.dumps(request.GET)), content_type="text/plain", status=400) + return HttpResponse( + "ERROR: Asset ID not found in URL\n{0}".format(json.dumps(request.GET)), + content_type="text/plain", + status=400, + ) # first check for error info - error = request.GET.get('error') - error_description = request.GET.get('error_description') + error = request.GET.get("error") + error_description = request.GET.get("error_description") if error: - message = "Error: {0}".format(error) + msg = "Error: {0}".format(error) if error_description: - message += " Details: {0}".format(error_description) - return HttpResponse("Server returned {0}".format(message), content_type="text/plain", status=400) + msg += " Details: {0}".format(error_description) + return HttpResponse("Server returned {0}".format(msg), content_type="text/plain", status=400) - admin_consent = request.GET.get('admin_consent') - code = request.GET.get('code') + admin_consent = request.GET.get("admin_consent") + code = request.GET.get("code") if not admin_consent and not code: - return HttpResponse("ERROR: admin_consent or authorization code not found in URL\n{0}".format( - json.dumps(request.GET)), content_type="text/plain", status=400) + return HttpResponse( + "ERROR: admin_consent or authorization code not found in URL\n{0}".format( + json.dumps(request.GET) + ), + content_type="text/plain", + status=400, + ) # Load the data state = _load_app_state(asset_id) if admin_consent: - if admin_consent == 'True': + if admin_consent == "True": admin_consent = True else: admin_consent = False - state['admin_consent'] = admin_consent + state["admin_consent"] = admin_consent _save_app_state(state, asset_id, None) # If admin_consent is True if admin_consent: - return HttpResponse('Admin Consent received. Please close this window.', content_type="text/plain") - return HttpResponse('Admin Consent declined. Please close this window and try again later.', content_type="text/plain", status=400) + return HttpResponse( + "Admin Consent received. Please close this window.", + content_type="text/plain", + ) + return HttpResponse( + "Admin Consent declined. Please close this window and try again later.", + content_type="text/plain", + status=400, + ) # If value of admin_consent is not available, value of code is available - state['code'] = code + state["code"] = code _save_app_state(state, asset_id, None) - return HttpResponse('Code received. Please close this window, the action will continue to get new token.', content_type="text/plain") + return HttpResponse( + "Code received. Please close this window, the action will continue to get new token.", + content_type="text/plain", + ) def _handle_oauth_start(request, path_parts): # get the asset id, the state file is created for each asset - asset_id = request.GET.get('asset_id') + asset_id = request.GET.get("asset_id") if not asset_id: - return HttpResponse("ERROR: Asset ID not found in URL", content_type="text/plain", status=404) + return HttpResponse( + "ERROR: Asset ID not found in URL", content_type="text/plain", status=404 + ) # Load the state that was created for the asset state = _load_app_state(asset_id) if not state: return HttpResponse( - 'ERROR: The asset ID is invalid or an error occurred while reading the state file', content_type="text/plain", status=400 + "ERROR: The asset ID is invalid or an error occurred while reading the state file", + content_type="text/plain", + status=400, ) # get the url to point to the authorize url of OAuth - admin_consent_url = state.get('admin_consent_url') + admin_consent_url = state.get("admin_consent_url") if not admin_consent_url: - return HttpResponse("App state is invalid, admin_consent_url key not found", content_type="text/plain", status=400) + return HttpResponse( + "App state is invalid, admin_consent_url key not found", + content_type="text/plain", + status=400, + ) # Redirect to this link, the user will then require to enter credentials interactively response = HttpResponse(status=302) - response['Location'] = admin_consent_url + response["Location"] = admin_consent_url return response @@ -282,26 +334,32 @@ def handle_request(request, path_parts): # get the type of data requested, it's the last part of the URL used to post to the REST endpoint if len(path_parts) < 2: - return HttpResponse('error: True, message: Invalid REST endpoint request', content_type="text/plain", status=404) + return HttpResponse( + "error: True, message: Invalid REST endpoint request", + content_type="text/plain", + status=404, + ) call_type = path_parts[1] - if call_type == 'start_oauth': + if call_type == "start_oauth": # start the authentication process return _handle_oauth_start(request, path_parts) - if call_type == 'result': + if call_type == "result": # process the 'code' ret_val = _handle_oauth_result(request, path_parts) - asset_id = request.GET.get('state') + asset_id = request.GET.get("state") # nosemgrep if asset_id and asset_id.isalnum(): app_dir = os.path.dirname(os.path.abspath(__file__)) - auth_status_file_path = '{0}/{1}_{2}'.format(app_dir, asset_id, TC_FILE) + auth_status_file_path = "{0}/{1}_{2}".format(app_dir, asset_id, TC_FILE) real_auth_status_file_path = os.path.abspath(auth_status_file_path) if not os.path.dirname(real_auth_status_file_path) == app_dir: - return HttpResponse("Error: Invalid asset_id", content_type="text/plain", status=400) - open(auth_status_file_path, 'w').close() + return HttpResponse( + "Error: Invalid asset_id", content_type="text/plain", status=400 + ) + open(auth_status_file_path, "w").close() try: uid = pwd.getpwnam("apache").pw_uid gid = grp.getgrnam("phantom").gr_gid @@ -312,12 +370,14 @@ def handle_request(request, path_parts): return ret_val - return HttpResponse('error: Invalid endpoint', content_type="text/plain", status=404) + return HttpResponse( + "error: Invalid endpoint", content_type="text/plain", status=404 + ) def _get_dir_name_from_app_name(app_name): - app_name = ''.join([x for x in app_name if x.isalnum()]) + app_name = "".join([x for x in app_name if x.isalnum()]) app_name = app_name.lower() if not app_name: @@ -340,14 +400,20 @@ def _decrypt_state(state, salt): if "non_admin_auth" in state: if state.get("non_admin_auth").get("access_token"): - state["non_admin_auth"]["access_token"] = encryption_helper.decrypt(state["non_admin_auth"]["access_token"], salt) + state["non_admin_auth"]["access_token"] = encryption_helper.decrypt( + state["non_admin_auth"]["access_token"], salt + ) if state.get("non_admin_auth").get("refresh_token"): - state["non_admin_auth"]["refresh_token"] = encryption_helper.decrypt(state["non_admin_auth"]["refresh_token"], salt) + state["non_admin_auth"]["refresh_token"] = encryption_helper.decrypt( + state["non_admin_auth"]["refresh_token"], salt + ) if "admin_auth" in state: if state.get("admin_auth").get("access_token"): - state["admin_auth"]["access_token"] = encryption_helper.decrypt(state["admin_auth"]["access_token"], salt) + state["admin_auth"]["access_token"] = encryption_helper.decrypt( + state["admin_auth"]["access_token"], salt + ) if "code" in state: state["code"] = encryption_helper.decrypt(state["code"], salt) @@ -365,14 +431,20 @@ def _encrypt_state(state, salt): """ if "non_admin_auth" in state: if state.get("non_admin_auth").get("access_token"): - state["non_admin_auth"]["access_token"] = encryption_helper.encrypt(state["non_admin_auth"]["access_token"], salt) + state["non_admin_auth"]["access_token"] = encryption_helper.encrypt( + state["non_admin_auth"]["access_token"], salt + ) if state.get("non_admin_auth").get("refresh_token"): - state["non_admin_auth"]["refresh_token"] = encryption_helper.encrypt(state["non_admin_auth"]["refresh_token"], salt) + state["non_admin_auth"]["refresh_token"] = encryption_helper.encrypt( + state["non_admin_auth"]["refresh_token"], salt + ) if "admin_auth" in state: if state.get("admin_auth").get("access_token"): - state["admin_auth"]["access_token"] = encryption_helper.encrypt(state["admin_auth"]["access_token"], salt) + state["admin_auth"]["access_token"] = encryption_helper.encrypt( + state["admin_auth"]["access_token"], salt + ) if "code" in state: state["code"] = encryption_helper.encrypt(state["code"], salt) @@ -383,7 +455,6 @@ def _encrypt_state(state, salt): class Office365Connector(BaseConnector): - def __init__(self): # Call the BaseConnectors init first @@ -402,7 +473,9 @@ def __init__(self): self._scope = None self._access_token = None self._refresh_token = None - self._REPLACE_CONST = "C53CEA8298BD401BA695F247633D0542" # pragma: allowlist secret + self._REPLACE_CONST = ( + "C53CEA8298BD401BA695F247633D0542" # pragma: allowlist secret + ) self._duplicate_count = 0 self._asset_id = None @@ -416,7 +489,8 @@ def load_state(self): try: state = _decrypt_state(state, self._asset_id) except Exception as e: - self.debug_print("{}: {}".format(MSGOFFICE365_DECRYPTION_ERR, str(e))) + self._dump_error_log(e) + self.debug_print("{}: {}".format(MSGOFFICE365_DECRYPTION_ERROR, str(e))) state = None return state @@ -431,17 +505,20 @@ def save_state(self, state): try: state = _encrypt_state(state, self._asset_id) except Exception as e: - self.debug_print("{}: {}".format(MSGOFFICE365_ENCRYPTION_ERR, str(e))) + self._dump_error_log(e) + self.debug_print("{}: {}".format(MSGOFFICE365_ENCRYPTION_ERROR, str(e))) return phantom.APP_ERROR return super().save_state(state) + def _dump_error_log(self, error, msg="Exception occurred."): + self.error_print(msg, dump_object=error) + def _process_empty_response(self, response, action_result): if response.status_code == 200: return RetVal(phantom.APP_SUCCESS, {}) - - return RetVal(action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_ERR_EMPTY_RESPONSE.format(code=response.status_code)), None) + return RetVal(action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_ERROR_EMPTY_RESPONSE.format(code=response.status_code)), None) def _process_html_response(self, response, action_result): @@ -454,18 +531,17 @@ def _process_html_response(self, response, action_result): for element in soup(["script", "style", "footer", "nav"]): element.extract() error_text = soup.text - split_lines = error_text.split('\n') + split_lines = error_text.split("\n") split_lines = [x.strip() for x in split_lines if x.strip()] - error_text = '\n'.join(split_lines) + error_text = "\n".join(split_lines) except Exception: error_text = "Cannot parse error details" - message = "Status Code: {0}. Data from server:\n{1}\n".format(status_code, - error_text) + msg = "Status Code: {0}. Data from server:\n{1}\n".format(status_code, error_text) - message = message.replace('{', '{{').replace('}', '}}') + msg = msg.replace('{', '{{').replace('}', '}}') - return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + return RetVal(action_result.set_status(phantom.APP_ERROR, msg), None) def _process_json_response(self, r, action_result): @@ -473,7 +549,7 @@ def _process_json_response(self, r, action_result): try: resp_json = r.json() except Exception as e: - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e, self) return RetVal(action_result.set_status(phantom.APP_ERROR, "Unable to parse JSON response. {0}".format(error_msg)), None) # Please specify the status codes here @@ -483,25 +559,28 @@ def _process_json_response(self, r, action_result): try: error_code = "" error_text = "" - error_message = "" + + error_msg = "" error = resp_json.get('error', '') error_desc = resp_json.get('error_description', '') if isinstance(error, dict): error_code = error.get('code') - error_message = error.get('message') + error_msg = error.get('message') - if error_message: + if error_msg: try: - soup = BeautifulSoup(resp_json.get('error', {}).get('message'), "html.parser") + soup = BeautifulSoup( + resp_json.get("error", {}).get("message"), "html.parser" + ) # Remove the script, style, footer and navigation part from the HTML message for element in soup(["script", "style", "footer", "nav"]): element.extract() error_text = soup.text - split_lines = error_text.split('\n') + split_lines = error_text.split("\n") split_lines = [x.strip() for x in split_lines if x.strip()] - error_text = '\n'.join(split_lines) + error_text = "\n".join(split_lines) if len(error_text) > 500: - error_text = 'Error while connecting to a server (Please check input parameters or asset configuration parameters)' + error_text = "Error while connecting to a server (Please check input parameters or asset configuration parameters)" except Exception: error_text = "Cannot parse error details" @@ -512,40 +591,43 @@ def _process_json_response(self, r, action_result): error_text = "{}. {}".format(error_desc, error_text) if not error_text: - error_text = r.text.replace('{', '{{').replace('}', '}}') + error_text = r.text.replace("{", "{{").replace("}", "}}") except Exception: - error_text = r.text.replace('{', '{{').replace('}', '}}') + error_text = r.text.replace("{", "{{").replace("}", "}}") # You should process the error returned in the json - message = "Error from server. Status Code: {0} Data from server: {1}".format( + + msg = "Error: Status Code: {0} Data from server: {1}".format( r.status_code, error_text) - return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + return RetVal(action_result.set_status(phantom.APP_ERROR, msg), None) def _process_response(self, r, action_result): # store the r_text in debug data, it will get dumped in the logs if the action fails - if hasattr(action_result, 'add_debug_data'): - action_result.add_debug_data({'r_status_code': r.status_code}) - action_result.add_debug_data({'r_text': r.text}) - action_result.add_debug_data({'r_headers': r.headers}) + if hasattr(action_result, "add_debug_data"): + action_result.add_debug_data({"r_status_code": r.status_code}) + action_result.add_debug_data({"r_text": r.text}) + action_result.add_debug_data({"r_headers": r.headers}) # Process each 'Content-Type' of response separately # Process a json response - content_type = r.headers.get('Content-Type', '') - if 'json' in content_type or 'javascript' in content_type: + content_type = r.headers.get("Content-Type", "") + if "json" in content_type or "javascript" in content_type: return self._process_json_response(r, action_result) # Process an HTML response, Do this no matter what the api talks. # There is a high chance of a PROXY in between Splunk SOAR and the rest of # world, in case of errors, PROXY's return HTML, this function parses # the error and adds it to the action_result. - if 'html' in r.headers.get('Content-Type', ''): + if "html" in r.headers.get("Content-Type", ""): return self._process_html_response(r, action_result) if r.status_code == 404: - return RetVal(action_result.set_status(phantom.APP_ERROR, "Email not found"), None) + return RetVal( + action_result.set_status(phantom.APP_ERROR, "Email not found"), None + ) if 200 <= r.status_code <= 204: return RetVal(phantom.APP_SUCCESS, None) @@ -555,32 +637,53 @@ def _process_response(self, r, action_result): return self._process_empty_response(r, action_result) # everything else is actually an error at this point - message = "Can't process response from server. Status Code: {0} Data from server: {1}".format( + + msg = "Can't process response from server. Status Code: {0} Data from server: {1}".format( r.status_code, r.text.replace('{', '{{').replace('}', '}}')) - return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + return RetVal(action_result.set_status(phantom.APP_ERROR, msg), None) - def _make_rest_call(self, action_result, url, verify=True, headers={}, params=None, data=None, method="get", download=False): + def _make_rest_call( + self, + action_result, + url, + verify=True, + headers={}, + params=None, + data=None, + method="get", + download=False, + ): resp_json = None try: request_func = getattr(requests, method) except AttributeError: - return RetVal(action_result.set_status(phantom.APP_ERROR, "Invalid method: {0}".format(method)), resp_json) + return RetVal( + action_result.set_status( + phantom.APP_ERROR, "Invalid method: {0}".format(method) + ), + resp_json, + ) for _ in range(self._number_of_retries): try: r = request_func( - url, - data=data, - headers=headers, - verify=verify, - params=params, - timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT) + url, + data=data, + headers=headers, + verify=verify, + params=params, + timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT, + ) except Exception as e: - error_msg = _get_error_message_from_exception(e) + + error_msg = _get_error_msg_from_exception(e, self) + + self._dump_error_log(e) return RetVal(action_result.set_status(phantom.APP_ERROR, "Error connecting to server. {0}".format(error_msg)), resp_json) + if r.status_code != 502: break self.debug_print("Received 502 status code from the server") @@ -596,17 +699,23 @@ def _make_rest_call(self, action_result, url, verify=True, headers={}, params=No def _get_asset_name(self, action_result): - rest_endpoint = SPLUNK_SOAR_ASSET_INFO_URL.format(url=self.get_phantom_base_url(), asset_id=self._asset_id) + rest_endpoint = SPLUNK_SOAR_ASSET_INFO_URL.format( + url=self.get_phantom_base_url(), asset_id=self._asset_id + ) ret_val, resp_json = self._make_rest_call(action_result, rest_endpoint, False) if phantom.is_fail(ret_val): return (ret_val, None) - asset_name = resp_json.get('name') + asset_name = resp_json.get("name") if not asset_name: - return (action_result.set_status(phantom.APP_ERROR, "Asset Name for ID: {0} not found".format(self._asset_id), None)) + return action_result.set_status( + phantom.APP_ERROR, + "Asset Name for ID: {0} not found".format(self._asset_id), + None, + ) return (phantom.APP_SUCCESS, asset_name) @@ -619,20 +728,24 @@ def _update_container(self, action_result, container_id, container): :param container: container's payload to update :return: status phantom.APP_ERROR/phantom.APP_SUCCESS with status message """ - rest_endpoint = SPLUNK_SOAR_CONTAINER_INFO_URL.format(url=self.get_phantom_base_url(), container_id=container_id) + rest_endpoint = SPLUNK_SOAR_CONTAINER_INFO_URL.format( + url=self.get_phantom_base_url(), container_id=container_id + ) try: data = json.dumps(container) except Exception as e: - error_msg = _get_error_message_from_exception(e) - message = ( + error_msg = _get_error_msg_from_exception(e, self) + msg = ( "json.dumps failed while updating the container: {}. " - "Possibly a value in the container dictionary is not encoded properly. " + "Possibly a value in the container dictionary is not encoded properly." "Exception: {}" ).format(container_id, error_msg) - return action_result.set_status(phantom.APP_ERROR, message) + return action_result.set_status(phantom.APP_ERROR, msg) - ret_val, _ = self._make_rest_call(action_result, rest_endpoint, False, data=data, method="post") + ret_val, _ = self._make_rest_call( + action_result, rest_endpoint, False, data=data, method="post" + ) if phantom.is_fail(ret_val): return action_result.get_status() @@ -640,16 +753,25 @@ def _update_container(self, action_result, container_id, container): def _get_phantom_base_url(self, action_result): - ret_val, resp_json = self._make_rest_call(action_result, SPLUNK_SOAR_SYS_INFO_URL.format(url=self.get_phantom_base_url()), False) + ret_val, resp_json = self._make_rest_call( + action_result, + SPLUNK_SOAR_SYS_INFO_URL.format(url=self.get_phantom_base_url()), + False, + ) if phantom.is_fail(ret_val): return (ret_val, None) - phantom_base_url = resp_json.get('base_url').rstrip("/") + phantom_base_url = resp_json.get("base_url").rstrip("/") if not phantom_base_url: - return (action_result.set_status(phantom.APP_ERROR, - "Splunk SOAR Base URL not found in System Settings. Please specify this value in System Settings"), None) + return ( + action_result.set_status( + phantom.APP_ERROR, + "Splunk SOAR Base URL not found in System Settings. Please specify this value in System Settings", + ), + None, + ) return (phantom.APP_SUCCESS, phantom_base_url) @@ -670,20 +792,34 @@ def _get_url_to_app_rest(self, action_result=None): if phantom.is_fail(ret_val): return (action_result.get_status(), None) - self.save_progress('Using Splunk SOAR base URL as: {0}'.format(phantom_base_url)) + self.save_progress( + "Using Splunk SOAR base URL as: {0}".format(phantom_base_url) + ) app_json = self.get_app_json() - app_name = app_json['name'] + app_name = app_json["name"] app_dir_name = _get_dir_name_from_app_name(app_name) - url_to_app_rest = "{0}/rest/handler/{1}_{2}/{3}".format(phantom_base_url, app_dir_name, app_json['appid'], asset_name) + url_to_app_rest = "{0}/rest/handler/{1}_{2}/{3}".format( + phantom_base_url, app_dir_name, app_json["appid"], asset_name + ) return (phantom.APP_SUCCESS, url_to_app_rest) - def _make_rest_call_helper(self, action_result, endpoint, verify=True, headers=None, - params=None, data=None, method="get", nextLink=None, download=False): + def _make_rest_call_helper( + self, + action_result, + endpoint, + verify=True, + headers=None, + params=None, + data=None, + method="get", + nextLink=None, + download=False, + ): if nextLink: url = nextLink @@ -696,48 +832,59 @@ def _make_rest_call_helper(self, action_result, endpoint, verify=True, headers=N headers.update({ 'Authorization': 'Bearer {0}'.format(self._access_token), 'Accept': 'application/json', - 'Content-Type': 'application/json'}) + 'Content-Type': 'application/json' + }) ret_val, resp_json = self._make_rest_call(action_result, url, verify, headers, params, data, method, download=download) # If token is expired, generate a new token msg = action_result.get_message() - - if msg and 'token is invalid' in msg or ('Access token has expired' in - msg) or ('ExpiredAuthenticationToken' in msg) or ('AuthenticationFailed' in msg) or ('TokenExpired' in - msg) or ('InvalidAuthenticationToken' in msg): - + if msg and any(failure_msg in msg for failure_msg in AUTH_FAILURE_MSG): self.debug_print("Token is invalid/expired. Hence, generating a new token.") ret_val = self._get_token(action_result) if phantom.is_fail(ret_val): return action_result.get_status(), None - headers.update({'Authorization': 'Bearer {0}'.format(self._access_token)}) - - ret_val, resp_json = self._make_rest_call(action_result, url, verify, headers, params, data, method, download=download) + headers.update({"Authorization": "Bearer {0}".format(self._access_token)}) + + ret_val, resp_json = self._make_rest_call( + action_result, + url, + verify, + headers, + params, + data, + method, + download=download, + ) if phantom.is_fail(ret_val): return action_result.get_status(), None return phantom.APP_SUCCESS, resp_json + def _sanitize_file_name(self, file_name): + return re.sub('[,"\']', '', file_name) + def _add_attachment_to_vault(self, attachment, container_id, file_data): - if hasattr(Vault, 'get_vault_tmp_dir'): + if hasattr(Vault, "get_vault_tmp_dir"): fd, tmp_file_path = tempfile.mkstemp(dir=Vault.get_vault_tmp_dir()) else: - fd, tmp_file_path = tempfile.mkstemp(dir='/opt/phantom/vault/tmp') + fd, tmp_file_path = tempfile.mkstemp(dir="/opt/phantom/vault/tmp") os.close(fd) file_mode = "wb" if isinstance(file_data, bytes) else "w" with open(tmp_file_path, file_mode) as f: f.write(file_data) - success, message, vault_id = ph_rules.vault_add( + file_name = self._sanitize_file_name(attachment["name"]) + + success, msg, vault_id = ph_rules.vault_add( container=container_id, file_location=tmp_file_path, - file_name=attachment['name'] + file_name=file_name, ) if not success: - self.debug_print("Error adding file to vault: {}".format(message)) + self.debug_print("Error adding file to vault: {}".format(msg)) return RetVal(phantom.APP_ERROR, None) else: return RetVal(phantom.APP_SUCCESS, vault_id) @@ -747,70 +894,92 @@ def _handle_attachment(self, attachment, container_id, artifact_json=None): vault_id = None try: - if 'contentBytes' in attachment: # Check whether the attachment contains the data - file_data = base64.b64decode(attachment.pop('contentBytes')) - ret_val, vault_id = self._add_attachment_to_vault(attachment, container_id, file_data) + if ( + "contentBytes" in attachment + ): # Check whether the attachment contains the data + file_data = base64.b64decode(attachment.pop("contentBytes")) + ret_val, vault_id = self._add_attachment_to_vault( + attachment, container_id, file_data + ) if phantom.is_fail(ret_val): return phantom.APP_ERROR else: - self.debug_print("No content found in the attachment. Hence, skipping the vault file creation.") + self.debug_print( + "No content found in the attachment. Hence, skipping the vault file creation." + ) except Exception as e: - error_msg = _get_error_message_from_exception(e) + self._dump_error_log(e) + error_msg = _get_error_msg_from_exception(e, self) self.debug_print("Error saving file to vault: {0}".format(error_msg)) return phantom.APP_ERROR if artifact_json is None: - attachment['vaultId'] = vault_id + attachment["vaultId"] = vault_id return phantom.APP_SUCCESS - artifact_json['name'] = 'Vault Artifact' - artifact_json['label'] = 'attachment' - artifact_json['container_id'] = container_id - artifact_json['source_data_identifier'] = attachment['id'] + artifact_json["name"] = "Vault Artifact" + artifact_json["label"] = "attachment" + artifact_json["container_id"] = container_id + artifact_json["source_data_identifier"] = attachment["id"] artifact_cef = {} - artifact_cef['size'] = attachment['size'] - artifact_cef['lastModified'] = attachment['lastModifiedDateTime'] - artifact_cef['filename'] = attachment['name'] - artifact_cef['mimeType'] = attachment['contentType'] + artifact_cef["size"] = attachment["size"] + artifact_cef["lastModified"] = attachment["lastModifiedDateTime"] + artifact_cef["filename"] = attachment["name"] + artifact_cef["mimeType"] = attachment["contentType"] if vault_id: - artifact_cef['vault_id'] = vault_id + artifact_cef["vault_id"] = vault_id - artifact_json['cef'] = artifact_cef + artifact_json["cef"] = artifact_cef return phantom.APP_SUCCESS - def _handle_item_attachment(self, attachment, container_id, endpoint, action_result): + def _handle_item_attachment( + self, attachment, container_id, endpoint, action_result + ): vault_id = None try: - attach_endpoint = "{}/{}/$value".format(endpoint, attachment['id']) - ret_val, rfc822_email = self._make_rest_call_helper(action_result, attach_endpoint, download=True) + attach_endpoint = "{}/{}/$value".format(endpoint, attachment["id"]) + ret_val, rfc822_email = self._make_rest_call_helper( + action_result, attach_endpoint, download=True + ) if phantom.is_fail(ret_val): - self.debug_print("Error while downloading the file content, for attachment id: {}".format(attachment['id'])) + self.debug_print( + "Error while downloading the file content, for attachment id: {}".format( + attachment["id"] + ) + ) return phantom.APP_ERROR - attachment['name'] = "{}.eml".format(attachment['name']) + attachment["name"] = "{}.eml".format(attachment["name"]) if rfc822_email: # Check whether the API returned any data - ret_val, vault_id = self._add_attachment_to_vault(attachment, container_id, rfc822_email) + ret_val, vault_id = self._add_attachment_to_vault( + attachment, container_id, rfc822_email + ) if phantom.is_fail(ret_val): return phantom.APP_ERROR else: - self.debug_print("No content found for the item attachment. Hence, skipping the vault file creation.") + self.debug_print( + "No content found for the item attachment. Hence, skipping the vault file creation." + ) except Exception as e: - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e, self) + self._dump_error_log(e) self.debug_print("Error saving file to vault: {0}".format(error_msg)) return phantom.APP_ERROR - attachment['vaultId'] = vault_id + attachment["vaultId"] = vault_id return phantom.APP_SUCCESS - def _create_reference_attachment_artifact(self, container_id, attachment, artifact_json): + def _create_reference_attachment_artifact( + self, container_id, attachment, artifact_json + ): """ Create reference attachment artifact. @@ -819,22 +988,22 @@ def _create_reference_attachment_artifact(self, container_id, attachment, artifa :param artifact_json: artifact dict to add the data :return: phantom.APP_SUCCESS """ - artifact_json['name'] = 'Reference Attachment Artifact' - artifact_json['container_id'] = container_id - artifact_json['source_data_identifier'] = attachment['id'] + artifact_json["name"] = "Reference Attachment Artifact" + artifact_json["container_id"] = container_id + artifact_json["source_data_identifier"] = attachment["id"] artifact_cef = {} - artifact_cef['size'] = attachment.get('size') - artifact_cef['lastModified'] = attachment.get('lastModifiedDateTime') - artifact_cef['filename'] = attachment.get('name') - artifact_cef['mimeType'] = attachment.get('contentType') + artifact_cef["size"] = attachment.get("size") + artifact_cef["lastModified"] = attachment.get("lastModifiedDateTime") + artifact_cef["filename"] = attachment.get("name") + artifact_cef["mimeType"] = attachment.get("contentType") - artifact_json['cef'] = artifact_cef + artifact_json["cef"] = artifact_cef return phantom.APP_SUCCESS - def _create_email_artifacts(self, container_id, email, artifact_id=None): + def _create_email_artifacts(self, container_id, email, artifact_id=None, create_iocs=True): """ Create email artifacts. @@ -846,64 +1015,75 @@ def _create_email_artifacts(self, container_id, email, artifact_id=None): artifacts = [] email_artifact = {} - email_artifact['label'] = 'email' - email_artifact['name'] = 'Email Artifact' - email_artifact['container_id'] = container_id + email_artifact["label"] = "email" + email_artifact["name"] = "Email Artifact" + email_artifact["container_id"] = container_id - if email.get('id'): - artifact_id = email['id'] + if email.get("id"): + artifact_id = email["id"] # Set email ID contains - self._process_email._set_email_id_contains(email['id']) - email_artifact['cef_types'] = {'messageId': self._process_email._email_id_contains} + self._process_email._set_email_id_contains(email["id"]) + email_artifact["cef_types"] = { + "messageId": self._process_email._email_id_contains + } - email_artifact['source_data_identifier'] = artifact_id + email_artifact["source_data_identifier"] = artifact_id cef = {} - email_artifact['cef'] = cef + email_artifact["cef"] = cef for k, v in email.items(): if v is not None: - if k == 'from': - from_obj = v.get('emailAddress', {}) + if k == "from": + from_obj = v.get("emailAddress", {}) cef[k] = from_obj - cef['fromEmail'] = from_obj.get('address', '') - elif k == 'toRecipients': + cef["fromEmail"] = from_obj.get("address", "") + elif k == "toRecipients": cef[k] = v # add first email to To recipients = v if len(recipients): - cef['toEmail'] = recipients[0].get('emailAddress', {}).get('address', '') - elif k == 'id': - cef['messageId'] = v - elif k == 'internetMessageHeaders': - cef['internetMessageHeaders'] = {} + cef["toEmail"] = ( + recipients[0].get("emailAddress", {}).get("address", "") + ) + elif k == "id": + cef["messageId"] = v + elif k == "internetMessageHeaders": + cef["internetMessageHeaders"] = {} if isinstance(v, list): for header in v: - key_name = header.get('name') - key_value = header.get('value') + key_name = header.get("name") + key_value = header.get("value") if key_name and key_value: - cef['internetMessageHeaders'][key_name] = key_value + cef["internetMessageHeaders"][key_name] = key_value + elif k == "attachments": + continue else: cef[k] = v - if cef.get('body', {}).get('content') and (cef.get('body', {}).get('contentType') == 'html'): - html_body = cef['body']['content'] + if cef.get("body", {}).get("content") and ( + cef.get("body", {}).get("contentType") == "html" + ): + html_body = cef["body"]["content"] try: soup = BeautifulSoup(html_body, "html.parser") # Remove the script, style, footer, title and navigation part from the HTML message for element in soup(["script", "style", "footer", "title", "nav"]): element.extract() - body_text = soup.get_text(separator=' ') - split_lines = body_text.split('\n') + body_text = soup.get_text(separator=" ") + split_lines = body_text.split("\n") split_lines = [x.strip() for x in split_lines if x.strip()] - body_text = '\n'.join(split_lines) + body_text = "\n".join(split_lines) if body_text: - cef['bodyText'] = body_text + cef["bodyText"] = body_text except Exception: self.debug_print("Cannot parse email body text details") + if not create_iocs: + return [email_artifact] + body = email['body']['content'] ips = [] @@ -912,11 +1092,11 @@ def _create_email_artifacts(self, container_id, email, artifact_id=None): for ip in ips: ip_artifact = {} artifacts.append(ip_artifact) - ip_artifact['name'] = 'IP Artifact' - ip_artifact['label'] = 'artifact' - ip_artifact['cef'] = ip - ip_artifact['container_id'] = container_id - ip_artifact['source_data_identifier'] = artifact_id + ip_artifact["name"] = "IP Artifact" + ip_artifact["label"] = "artifact" + ip_artifact["cef"] = ip + ip_artifact["container_id"] = container_id + ip_artifact["source_data_identifier"] = artifact_id urls = [] domains = [] @@ -925,20 +1105,20 @@ def _create_email_artifacts(self, container_id, email, artifact_id=None): for url in urls: url_artifact = {} artifacts.append(url_artifact) - url_artifact['name'] = 'URL Artifact' - url_artifact['label'] = 'artifact' - url_artifact['cef'] = url - url_artifact['container_id'] = container_id - url_artifact['source_data_identifier'] = artifact_id + url_artifact["name"] = "URL Artifact" + url_artifact["label"] = "artifact" + url_artifact["cef"] = url + url_artifact["container_id"] = container_id + url_artifact["source_data_identifier"] = artifact_id for domain in domains: domain_artifact = {} artifacts.append(domain_artifact) - domain_artifact['name'] = 'Domain Artifact' - domain_artifact['label'] = 'artifact' - domain_artifact['cef'] = domain - domain_artifact['container_id'] = container_id - domain_artifact['source_data_identifier'] = artifact_id + domain_artifact["name"] = "Domain Artifact" + domain_artifact["label"] = "artifact" + domain_artifact["cef"] = domain + domain_artifact["container_id"] = container_id + domain_artifact["source_data_identifier"] = artifact_id hashes = [] self._process_email._extract_hashes(body, hashes) @@ -946,17 +1126,26 @@ def _create_email_artifacts(self, container_id, email, artifact_id=None): for hash in hashes: hash_artifact = {} artifacts.append(hash_artifact) - hash_artifact['name'] = 'Hash Artifact' - hash_artifact['label'] = 'artifact' - hash_artifact['cef'] = hash - hash_artifact['container_id'] = container_id - hash_artifact['source_data_identifier'] = artifact_id + hash_artifact["name"] = "Hash Artifact" + hash_artifact["label"] = "artifact" + hash_artifact["cef"] = hash + hash_artifact["container_id"] = container_id + hash_artifact["source_data_identifier"] = artifact_id artifacts.append(email_artifact) return artifacts - def _extract_attachments(self, config, attach_endpoint, artifacts, action_result, attachments, container_id, first_time=False): + def _extract_attachments( + self, + config, + attach_endpoint, + artifacts, + action_result, + attachments, + container_id, + first_time=False, + ): """ Extract attachments. @@ -971,100 +1160,155 @@ def _extract_attachments(self, config, attach_endpoint, artifacts, action_result """ for attachment in attachments: - if attachment.get('@odata.type') == '#microsoft.graph.itemAttachment': + if attachment.get("@odata.type") == "#microsoft.graph.itemAttachment": # We need to expand the item attachment only once if first_time: - sub_email_endpoint = attach_endpoint + '/{0}?$expand=microsoft.graph.itemattachment/item'.format(attachment['id']) - ret_val, sub_email_resp = self._make_rest_call_helper(action_result, sub_email_endpoint) + sub_email_endpoint = ( + attach_endpoint + "/{0}?$expand=microsoft.graph.itemattachment/item".format(attachment["id"]) + ) + ret_val, sub_email_resp = self._make_rest_call_helper( + action_result, sub_email_endpoint + ) if phantom.is_fail(ret_val): return action_result.get_status() - sub_email = sub_email_resp.get('item', {}) + sub_email = sub_email_resp.get("item", {}) else: - sub_email = attachment.get('item', {}) + sub_email = attachment.get("item", {}) + + if sub_email: + sub_artifacts = self._create_email_artifacts(container_id, sub_email, attachment['id'], create_iocs=False) + artifacts += sub_artifacts # Use recursive approach to extract the reference attachment - item_attachments = sub_email.pop('attachments', []) + item_attachments = sub_email.pop("attachments", []) if item_attachments: - ret_val = self._extract_attachments(config, attach_endpoint, artifacts, action_result, item_attachments, container_id) + ret_val = self._extract_attachments( + config, + attach_endpoint, + artifacts, + action_result, + item_attachments, + container_id, + ) if phantom.is_fail(ret_val): - self.debug_print("Error while processing nested attachments, for attachment id: {}".format(attachment['id'])) + self.debug_print( + "Error while processing nested attachments, for attachment id: {}".format( + attachment["id"] + ) + ) if first_time: # Fetch the rfc822 content for the item attachment - sub_email_endpoint = '{0}/{1}/$value'.format(attach_endpoint, attachment['id']) - attachment['name'] = "{}.eml".format(attachment['name']) - ret_val, rfc822_email = self._make_rest_call_helper(action_result, sub_email_endpoint, download=True) + sub_email_endpoint = "{0}/{1}/$value".format( + attach_endpoint, attachment["id"] + ) + attachment["name"] = "{}.eml".format(attachment["name"]) + ret_val, rfc822_email = self._make_rest_call_helper( + action_result, sub_email_endpoint, download=True + ) if phantom.is_fail(ret_val): - self.debug_print("Error while downloading the email content, for attachment id: {}".format(attachment['id'])) + self.debug_print( + "Error while downloading the email content, for attachment id: {}".format( + attachment["id"] + ) + ) if rfc822_email: # Create ProcessEmail Object for email item attachment process_email_obj = ProcessEmail(self, config) process_email_obj._trigger_automation = False - ret_val, message = process_email_obj.process_email(rfc822_email, attachment['id'], epoch=None, container_id=container_id) + + ret_val, msg = process_email_obj.process_email( + rfc822_email, attachment['id'], epoch=None, + container_id=container_id, ingest_email=False) + if phantom.is_fail(ret_val): - self.debug_print("Error while processing the email content, for attachment id: {}".format(attachment['id'])) + self.debug_print( + "Error while processing the email content, for attachment id: {}".format( + attachment["id"] + ) + ) - if config.get('ingest_eml', False): + if config.get("ingest_eml", False): # Add eml file into the vault if ingest_email is checked - ret_val, vault_id = self._add_attachment_to_vault(attachment, container_id, rfc822_email) + ret_val, vault_id = self._add_attachment_to_vault( + attachment, container_id, rfc822_email + ) if phantom.is_fail(ret_val): - self.debug_print('Could not process item attachment. See logs for details') + self.debug_print( + "Could not process item attachment. See logs for details" + ) else: # If success, create vault artifact artifact_json = { - 'name': 'Vault Artifact', - 'label': 'attachment', - 'container_id': container_id, - 'source_data_identifier': attachment['id'] + "name": "Vault Artifact", + "label": "attachment", + "container_id": container_id, + "source_data_identifier": attachment["id"], } artifact_cef = { - 'size': attachment['size'], - 'lastModified': attachment['lastModifiedDateTime'], - 'filename': attachment['name'], - 'mimeType': attachment['contentType'] + "size": attachment["size"], + "lastModified": attachment["lastModifiedDateTime"], + "filename": attachment["name"], + "mimeType": attachment["contentType"], } if vault_id: - artifact_cef['vault_id'] = vault_id - artifact_json['cef'] = artifact_cef + artifact_cef["vault_id"] = vault_id + artifact_json["cef"] = artifact_cef artifacts.append(artifact_json) else: - self.debug_print("No content found for the item attachment. Hence, skipping the email file processing.") + self.debug_print( + "No content found for the item attachment. Hence, skipping the email file processing." + ) - elif attachment.get('@odata.type') == "#microsoft.graph.referenceAttachment": + elif ( + attachment.get("@odata.type") == "#microsoft.graph.referenceAttachment" + ): attach_artifact = {} artifacts.append(attach_artifact) - self._create_reference_attachment_artifact(container_id, attachment, attach_artifact) + self._create_reference_attachment_artifact( + container_id, attachment, attach_artifact + ) - elif attachment.get('name', '').endswith('.eml'): - if 'contentBytes' in attachment: + elif attachment.get("name", "").endswith(".eml"): + if "contentBytes" in attachment: try: - rfc822_email = base64.b64decode(attachment['contentBytes']) + rfc822_email = base64.b64decode(attachment["contentBytes"]) rfc822_email = UnicodeDammit(rfc822_email).unicode_markup except Exception as e: - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e, self) + self._dump_error_log(e) self.debug_print("Unable to decode Email Mime Content. {0}".format(error_msg)) return action_result.set_status(phantom.APP_ERROR, "Unable to decode Email Mime Content") # Create ProcessEmail Object for email file attachment process_email_obj = ProcessEmail(self, config) process_email_obj._trigger_automation = False - ret_val, message = process_email_obj.process_email(rfc822_email, attachment['id'], epoch=None, container_id=container_id) + + ret_val, msg = process_email_obj.process_email(rfc822_email, attachment['id'], epoch=None, container_id=container_id) + if phantom.is_fail(ret_val): - return action_result.set_status(phantom.APP_ERROR, message) + return action_result.set_status(phantom.APP_ERROR, msg) else: - self.debug_print("No content found in the .eml file attachment. Hence, skipping the email file processing.") + self.debug_print( + "No content found in the .eml file attachment. Hence, skipping the email file processing." + ) elif first_time: attach_artifact = {} artifacts.append(attach_artifact) - if not self._handle_attachment(attachment, container_id, artifact_json=attach_artifact): - return action_result.set_status(phantom.APP_ERROR, "Could not process attachment. See logs for details.") + if not self._handle_attachment( + attachment, container_id, artifact_json=attach_artifact + ): + return action_result.set_status( + phantom.APP_ERROR, + "Could not process attachment. See logs for details.", + ) return phantom.APP_SUCCESS @@ -1084,26 +1328,33 @@ def _process_email_data(self, config, action_result, endpoint, email): container_description = MSGOFFICE365_CONTAINER_DESCRIPTION.format(last_modified_time=email['lastModifiedDateTime']) container['description'] = container_description container['source_data_identifier'] = email['id'] + container['data'] = {'raw_email': email} - ret_val, message, container_id = self.save_container(container) + ret_val, msg, container_id = self.save_container(container) if phantom.is_fail(ret_val) or not container_id: - return action_result.set_status(phantom.APP_ERROR, message) + return action_result.set_status(phantom.APP_ERROR, msg) - if MSGOFFICE365_DUPLICATE_CONTAINER_FOUND_MSG in message.lower(): + if MSGOFFICE365_DUPLICATE_CONTAINER_FOUND_MSG in msg.lower(): self.debug_print("Duplicate container found") self._duplicate_count += 1 # Prevent further processing if the email is not modified - ret_val, container_info, status_code = self.get_container_info(container_id=container_id) + ret_val, container_info, status_code = self.get_container_info( + container_id=container_id + ) if phantom.is_fail(ret_val): return action_result.set_status( phantom.APP_ERROR, - "Status Code: {}. Error occurred while fetching the container info for container ID: {}".format(status_code, container_id) + "Status Code: {}. Error occurred while fetching the container info for container ID: {}".format( + status_code, container_id + ), ) - if container_info.get('description', '') == container_description: - msg = "Email ID: {} has not been modified. Hence, skipping the artifact ingestion.".format(email['id']) + if container_info.get("description", "") == container_description: + msg = "Email ID: {} has not been modified. Hence, skipping the artifact ingestion.".format( + email["id"] + ) self.debug_print(msg) return action_result.set_status(phantom.APP_SUCCESS, msg) else: @@ -1117,41 +1368,86 @@ def _process_email_data(self, config, action_result, endpoint, email): email_artifacts = self._create_email_artifacts(container_id, email) attachment_artifacts = [] - if email['hasAttachments'] and config.get('extract_attachments', False): + if config.get("extract_eml", True): + subject = email.get("subject") + email_message = { + "id": email['id'], + "name": subject if subject else "email_message_{}".format(email['id']), + } + if not self._handle_item_attachment( + email_message, + container_id, + "/users/{0}/messages".format(config.get("email_address")), + action_result, + ): + return action_result.set_status( + phantom.APP_ERROR, + "Could not download the email. See logs for details", + ) + email["vaultId"] = email_message["vaultId"] - attach_endpoint = endpoint + '/{0}/attachments'.format(email['id']) - ret_val, attach_resp = self._make_rest_call_helper(action_result, attach_endpoint) + artifact_json = { + "name": "Vault Artifact", + "label": "Email Attachment", + "container_id": container_id, + "source_data_identifier": email["id"], + } + + artifact_cef = { + "filename": "{}.eml".format(email_message["name"]), + } + + if email_message["vaultId"]: + artifact_cef.update({ + "vaultId": email_message["vaultId"] + }) + artifact_json["cef"] = artifact_cef + attachment_artifacts.append(artifact_json) + + if email["hasAttachments"] and config.get("extract_attachments", False): + + attach_endpoint = endpoint + "/{0}/attachments".format(email["id"]) + ret_val, attach_resp = self._make_rest_call_helper( + action_result, attach_endpoint + ) if phantom.is_fail(ret_val): return action_result.get_status() ret_val = self._extract_attachments( - config, attach_endpoint, attachment_artifacts, - action_result, attach_resp.get('value', []), container_id, first_time=True + config, + attach_endpoint, + attachment_artifacts, + action_result, + attach_resp.get("value", []), + container_id, + first_time=True, ) if phantom.is_fail(ret_val): return action_result.get_status() artifacts = attachment_artifacts + email_artifacts - ret_val, message, container_id = self.save_artifacts(artifacts) + ret_val, msg, container_id = self.save_artifacts(artifacts) if phantom.is_fail(ret_val): - return action_result.set_status(phantom.APP_ERROR, message) + return action_result.set_status(phantom.APP_ERROR, msg) return phantom.APP_SUCCESS def _remove_tokens(self, action_result): # checks whether the message includes any of the known error codes - if len(list(filter(lambda x: x in action_result.get_message(), MSGOFFICE365_ASSET_PARAM_CHECK_LIST_ERRORS))) > 0: + + if len(list(filter(lambda x: x in action_result.get_message(), MSGOFFICE365_ASSET_PARAM_CHECK_LIST_ERROR))) > 0: + if not self._admin_access: - if self._state.get('non_admin_auth', {}).get('access_token'): - self._state['non_admin_auth'].pop('access_token') - if self._state.get('non_admin_auth', {}).get('refresh_token'): - self._state['non_admin_auth'].pop('refresh_token') + if self._state.get("non_admin_auth", {}).get("access_token"): + self._state["non_admin_auth"].pop("access_token") + if self._state.get("non_admin_auth", {}).get("refresh_token"): + self._state["non_admin_auth"].pop("refresh_token") else: - if self._state.get('admin_auth', {}).get('access_token'): - self._state['admin_auth'].pop('access_token') + if self._state.get("admin_auth", {}).get("access_token"): + self._state["admin_auth"].pop("access_token") def _handle_test_connectivity(self, param): - """ Function that handles the test connectivity action, it is much simpler than other action handlers.""" + """Function that handles the test connectivity action, it is much simpler than other action handlers.""" action_result = self.add_action_result(ActionResult(param)) @@ -1164,47 +1460,63 @@ def _handle_test_connectivity(self, param): ret_val, app_rest_url = self._get_url_to_app_rest(action_result) app_state = {} if phantom.is_fail(ret_val): - self.save_progress("Unable to get the URL to the app's REST Endpoint. Error: {0}".format( - action_result.get_message())) + self.save_progress( + "Unable to get the URL to the app's REST Endpoint. Error: {0}".format( + action_result.get_message() + ) + ) return action_result.set_status(phantom.APP_ERROR) # create the url that the oauth server should re-direct to after the auth is completed # (success and failure), this is added to the state so that the request handler will access # it later on redirect_uri = "{0}/result".format(app_rest_url) - app_state['redirect_uri'] = redirect_uri + app_state["redirect_uri"] = redirect_uri self.save_progress("Using OAuth Redirect URL as:") self.save_progress(redirect_uri) if self._admin_access: # Create the url for fetching administrator consent - admin_consent_url = "https://login.microsoftonline.com/{0}/adminconsent".format(self._tenant) + admin_consent_url = ( + "https://login.microsoftonline.com/{0}/adminconsent".format( + self._tenant + ) + ) admin_consent_url += "?client_id={0}".format(self._client_id) admin_consent_url += "&redirect_uri={0}".format(redirect_uri) admin_consent_url += "&state={0}".format(self._asset_id) else: # Scope is required for non-admin access if not self._scope: - return action_result.set_status(phantom.APP_ERROR, "Please provide scope for non-admin access in the asset configuration") + return action_result.set_status( + phantom.APP_ERROR, + "Please provide scope for non-admin access in the asset configuration", + ) # Create the url authorization, this is the one pointing to the oauth server side - admin_consent_url = "https://login.microsoftonline.com/{0}/oauth2/v2.0/authorize".format(self._tenant) + admin_consent_url = "https://login.microsoftonline.com/{0}/oauth2/v2.0/authorize".format( + self._tenant + ) admin_consent_url += "?client_id={0}".format(self._client_id) admin_consent_url += "&redirect_uri={0}".format(redirect_uri) admin_consent_url += "&state={0}".format(self._asset_id) admin_consent_url += "&scope={0}".format(self._scope) admin_consent_url += "&response_type=code" - app_state['admin_consent_url'] = admin_consent_url + app_state["admin_consent_url"] = admin_consent_url # The URL that the user should open in a different tab. # This is pointing to a REST endpoint that points to the app - url_to_show = "{0}/start_oauth?asset_id={1}&".format(app_rest_url, self._asset_id) + url_to_show = "{0}/start_oauth?asset_id={1}&".format( + app_rest_url, self._asset_id + ) # Save the state, will be used by the request handler _save_app_state(app_state, self._asset_id, self) - self.save_progress('Please connect to the following URL from a different tab to continue the connectivity process') + self.save_progress( + "Please connect to the following URL from a different tab to continue the connectivity process" + ) self.save_progress(url_to_show) self.save_progress(MSGOFFICE365_AUTHORIZE_TROUBLESHOOT_MSG) @@ -1213,16 +1525,18 @@ def _handle_test_connectivity(self, param): completed = False app_dir = os.path.dirname(os.path.abspath(__file__)) - auth_status_file_path = "{0}/{1}_{2}".format(app_dir, self._asset_id, TC_FILE) + auth_status_file_path = "{0}/{1}_{2}".format( + app_dir, self._asset_id, TC_FILE + ) if self._admin_access: - self.save_progress('Waiting for Admin Consent to complete') + self.save_progress("Waiting for Admin Consent to complete") else: - self.save_progress('Waiting for Authorization to complete') + self.save_progress("Waiting for Authorization to complete") for i in range(0, 40): - self.send_progress('{0}'.format('.' * (i % 10))) + self.send_progress("{0}".format("." * (i % 10))) if os.path.isfile(auth_status_file_path): completed = True @@ -1232,7 +1546,9 @@ def _handle_test_connectivity(self, param): time.sleep(TC_STATUS_SLEEP) if not completed: - self.save_progress("Authentication process does not seem to be completed. Timing out") + self.save_progress( + "Authentication process does not seem to be completed. Timing out" + ) return action_result.set_status(phantom.APP_ERROR) self.send_progress("") @@ -1246,13 +1562,15 @@ def _handle_test_connectivity(self, param): return action_result.set_status(phantom.APP_ERROR) else: if self._admin_access: - if not self._state.get('admin_consent'): + if not self._state.get("admin_consent"): self.save_progress("Admin Consent not received or not given") self.save_progress("Test Connectivity Failed") return action_result.set_status(phantom.APP_ERROR) else: - if not self._state.get('code'): - self.save_progress("Authorization code not received or not given") + if not self._state.get("code"): + self.save_progress( + "Authorization code not received or not given" + ) self.save_progress("Test Connectivity Failed") return action_result.set_status(phantom.APP_ERROR) @@ -1264,22 +1582,27 @@ def _handle_test_connectivity(self, param): return action_result.get_status() params = {'$top': '1'} - msg_failed = "" + message_failed = "" + if self._admin_access: - msg_failed = "API to fetch details of all the users failed" + message_failed = "API to fetch details of all the users failed" self.save_progress("Getting info about all users to verify token") - ret_val, response = self._make_rest_call_helper(action_result, "/users", params=params) + ret_val, response = self._make_rest_call_helper( + action_result, "/users", params=params + ) else: - msg_failed = "API to get user details failed" + message_failed = "API to get user details failed" self.save_progress("Getting info about a single user to verify token") - ret_val, response = self._make_rest_call_helper(action_result, "/me", params=params) + ret_val, response = self._make_rest_call_helper( + action_result, "/me", params=params + ) if phantom.is_fail(ret_val): - self.save_progress(msg_failed) + self.save_progress(message_failed) self.save_progress("Test Connectivity Failed") return action_result.set_status(phantom.APP_ERROR) - value = response.get('value') + value = response.get("value") if value: self.save_progress("Got user info") @@ -1290,66 +1613,82 @@ def _handle_test_connectivity(self, param): def _handle_copy_email(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] + email_addr = param["email_address"] folder = param["folder"] - message_id = param['id'] - endpoint = '/users/{0}'.format(email_addr) + message_id = param["id"] + endpoint = "/users/{0}".format(email_addr) - endpoint += '/messages/{0}/copy'.format(message_id) + endpoint += "/messages/{0}/copy".format(message_id) - body = {'DestinationId': folder} + body = {"DestinationId": folder} - if param.get('get_folder_id', True): + if param.get("get_folder_id", True): try: + dir_id, error, _ = self._get_folder_id(action_result, folder, email_addr) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) + return action_result.get_status() if dir_id: - body['DestinationId'] = dir_id + body["DestinationId"] = dir_id else: self.save_progress(error) return action_result.set_status(phantom.APP_ERROR, error) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, data=json.dumps(body), method='post') + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, data=json.dumps(body), method="post" + ) if phantom.is_fail(ret_val): return action_result.get_status() action_result.add_data(response) - return action_result.set_status(phantom.APP_SUCCESS, "Successfully copied email") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully copied email" + ) def _handle_move_email(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] + email_addr = param["email_address"] folder = param["folder"] - message_id = param['id'] - endpoint = '/users/{0}'.format(email_addr) + message_id = param["id"] + endpoint = "/users/{0}".format(email_addr) - endpoint += '/messages/{0}/move'.format(message_id) + endpoint += "/messages/{0}/move".format(message_id) - body = {'DestinationId': folder} - if param.get('get_folder_id', True): + body = {"DestinationId": folder} + if param.get("get_folder_id", True): try: - dir_id, error, _ = self._get_folder_id(action_result, folder, email_addr) + dir_id, error, _ = self._get_folder_id( + action_result, folder, email_addr + ) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) return action_result.get_status() if dir_id: - body['DestinationId'] = dir_id + body["DestinationId"] = dir_id else: self.save_progress(error) return action_result.set_status(phantom.APP_ERROR, error) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, data=json.dumps(body), method='post') + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, data=json.dumps(body), method="post" + ) if phantom.is_fail(ret_val): return action_result.get_status() @@ -1359,69 +1698,89 @@ def _handle_move_email(self, param): def _handle_delete_email(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] - message_id = param['id'] + email_addr = param["email_address"] + message_id = param["id"] endpoint = "/users/{0}".format(email_addr) - endpoint += '/messages/{0}'.format(message_id) + endpoint += "/messages/{0}".format(message_id) - ret_val, _ = self._make_rest_call_helper(action_result, endpoint, method='delete') + ret_val, _ = self._make_rest_call_helper( + action_result, endpoint, method="delete" + ) if phantom.is_fail(ret_val): return action_result.get_status() - return action_result.set_status(phantom.APP_SUCCESS, "Successfully deleted email") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully deleted email" + ) def _handle_delete_event(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] - message_id = param['id'] - send_decline_response = param.get('send_decline_response') + email_addr = param["email_address"] + message_id = param["id"] + send_decline_response = param.get("send_decline_response") endpoint = "/users/{0}/events/{1}".format(email_addr, message_id) method = "delete" data = None if send_decline_response: method = "post" - endpoint += '/decline' - data = json.dumps({'sendResponse': True}) + endpoint += "/decline" + data = json.dumps({"sendResponse": True}) - ret_val, _ = self._make_rest_call_helper(action_result, endpoint, method=method, data=data) + ret_val, _ = self._make_rest_call_helper( + action_result, endpoint, method=method, data=data + ) if phantom.is_fail(ret_val): return action_result.get_status() - return action_result.set_status(phantom.APP_SUCCESS, "Successfully deleted event") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully deleted event" + ) def _handle_oof_check(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - user_id = param['user_id'] + user_id = param["user_id"] - endpoint = '/users/{0}/mailboxSettings/automaticRepliesSetting'.format(user_id) + endpoint = "/users/{0}/mailboxSettings/automaticRepliesSetting".format(user_id) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, method='get') + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, method="get" + ) if phantom.is_fail(ret_val): return action_result.get_status() action_result.add_data(response) - action_result.update_summary({'events_matched': action_result.get_data_size()}) + action_result.update_summary({"events_matched": action_result.get_data_size()}) - return action_result.set_status(phantom.APP_SUCCESS, "Successfully retrieved out of office status") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully retrieved out of office status" + ) def _handle_list_events(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - user_id = param.get('user_id') if param.get('user_id') else None - group_id = param.get('group_id') if param.get('group_id') else None - query = param.get('filter') if param.get('filter') else None - limit = param.get('limit') + user_id = param.get("user_id") if param.get("user_id") else None + group_id = param.get("group_id") if param.get("group_id") else None + query = param.get("filter") if param.get("filter") else None + limit = param.get("limit") # Integer validation for 'limit' action parameter ret_val, limit = _validate_integer(action_result, limit, "'limit' action") @@ -1429,18 +1788,23 @@ def _handle_list_events(self, param): return action_result.get_status() if user_id is None and group_id is None: - return action_result.set_status(phantom.APP_ERROR, 'Either a "user_id" or "group_id" must be supplied to the "list_events" action') + return action_result.set_status( + phantom.APP_ERROR, + 'Either a "user_id" or "group_id" must be supplied to the "list_events" action', + ) if user_id and group_id and user_id != "" and group_id != "": - return action_result.set_status(phantom.APP_ERROR, - 'Either a user_id or group_id can be supplied to the "list_events" action - not both') + return action_result.set_status( + phantom.APP_ERROR, + 'Either a user_id or group_id can be supplied to the "list_events" action - not both', + ) - endpoint = '' + endpoint = "" if user_id: - endpoint = '/users/{0}/calendar/events'.format(user_id) + endpoint = "/users/{0}/calendar/events".format(user_id) else: - endpoint = '/groups/{0}/calendar/events'.format(group_id) + endpoint = "/groups/{0}/calendar/events".format(group_id) if query: endpoint = "{0}?{1}".format(endpoint, query) @@ -1449,7 +1813,7 @@ def _handle_list_events(self, param): if phantom.is_fail(ret_val): msg = action_result.get_message() - if '$top' in msg or '$top/top' in msg: + if "$top" in msg or "$top/top" in msg: msg += "The '$top' parameter is already used internally to handle pagination logic. " msg += "If you want to restrict results in terms of number of output results, you can use the 'limit' parameter." return action_result.set_status(phantom.APP_ERROR, msg) @@ -1458,34 +1822,45 @@ def _handle_list_events(self, param): if not events: # No events found is a valid scenario that there can be 0 events returned # even if the API call is a success for the correct given inputs and hence, returning APP_SUCCESS. - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) for event in events: - attendees = [attendee.get("emailAddress", {}).get("name") for attendee in event.get("attendees", [])] + attendees = [ + attendee.get("emailAddress", {}).get("name") + for attendee in event.get("attendees", []) + ] event["attendee_list"] = ", ".join(attendees) action_result.add_data(event) num_events = len(events) - action_result.update_summary({'events_matched': action_result.get_data_size()}) + action_result.update_summary({"events_matched": action_result.get_data_size()}) - return action_result.set_status(phantom.APP_SUCCESS, 'Successfully retrieved {} event{}'.format( - num_events, '' if num_events == 1 else 's')) + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} event{}".format( + num_events, "" if num_events == 1 else "s" + ), + ) def _handle_list_groups(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - limit = param.get('limit') + limit = param.get("limit") # Integer validation for 'limit' action parameter ret_val, limit = _validate_integer(action_result, limit, "'limit' action") if phantom.is_fail(ret_val): return action_result.get_status() - query = param.get('filter') if param.get('filter') else None + query = param.get("filter") if param.get("filter") else None - endpoint = '/groups' + endpoint = "/groups" ret_val, groups = self._paginator(action_result, endpoint, limit, query=query) @@ -1493,36 +1868,44 @@ def _handle_list_groups(self, param): return action_result.get_status() if not groups: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) for group in groups: action_result.add_data(group) num_groups = len(groups) - action_result.update_summary({'total_groups_returned': num_groups}) + action_result.update_summary({"total_groups_returned": num_groups}) - return action_result.set_status(phantom.APP_SUCCESS, 'Successfully retrieved {} group{}'.format( - num_groups, '' if num_groups == 1 else 's')) + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} group{}".format( + num_groups, "" if num_groups == 1 else "s" + ), + ) def _handle_list_group_members(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - limit = param.get('limit') + limit = param.get("limit") # Integer validation for 'limit' action parameter ret_val, limit = _validate_integer(action_result, limit, "'limit' action") if phantom.is_fail(ret_val): return action_result.get_status() - query = param.get('filter') if param.get('filter') else None - group_id = param['group_id'] - transitive_members = param.get('get_transitive_members', True) + query = param.get("filter") if param.get("filter") else None + group_id = param["group_id"] + transitive_members = param.get("get_transitive_members", True) - endpoint = '/groups/{0}/members'.format(group_id) + endpoint = "/groups/{0}/members".format(group_id) if transitive_members: - endpoint = '/groups/{0}/transitiveMembers'.format(group_id) + endpoint = "/groups/{0}/transitiveMembers".format(group_id) ret_val, members = self._paginator(action_result, endpoint, limit, query=query) @@ -1530,32 +1913,40 @@ def _handle_list_group_members(self, param): return action_result.get_status() if not members: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) for member in members: action_result.add_data(member) num_members = len(members) - action_result.update_summary({'total_members_returned': num_members}) + action_result.update_summary({"total_members_returned": num_members}) - return action_result.set_status(phantom.APP_SUCCESS, 'Successfully retrieved {} group member{}'.format( - num_members, '' if num_members == 1 else 's')) + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} group member{}".format( + num_members, "" if num_members == 1 else "s" + ), + ) def _handle_list_users(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - limit = param.get('limit') + limit = param.get("limit") # Integer validation for 'limit' action parameter ret_val, limit = _validate_integer(action_result, limit, "'limit' action") if phantom.is_fail(ret_val): return action_result.get_status() - query = param.get('filter') if param.get('filter') else None + query = param.get("filter") if param.get("filter") else None - endpoint = '/users' + endpoint = "/users" ret_val, users = self._paginator(action_result, endpoint, limit, query=query) @@ -1563,24 +1954,119 @@ def _handle_list_users(self, param): return action_result.get_status() if not users: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) for user in users: action_result.add_data(user) num_users = len(users) - action_result.update_summary({'total_users_returned': num_users}) + action_result.update_summary({"total_users_returned": num_users}) + + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} user{}".format( + num_users, "" if num_users == 1 else "s" + ), + ) + + def _handle_list_rules(self, param): + + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) + action_result = self.add_action_result(ActionResult(dict(param))) + + user_id = param["user_id"] + + endpoint = "/users/{user_id}/mailFolders/inbox/messageRules".format( + user_id=user_id + ) + + ret_val, rules = self._paginator(action_result, endpoint) + + if phantom.is_fail(ret_val): + return action_result.get_status() + + if not rules: + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) + + for rule in rules: + action_result.add_data(rule) + + num_rules = len(rules) + action_result.update_summary({"total_rules_returned": num_rules}) + + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} rule{}".format( + num_rules, "" if num_rules == 1 else "s" + ), + ) + + def flatten_json(self, y): + out = {} + + def flatten(x, name=""): + if type(x) is dict: + for a in x: + flatten(x[a], name + a + "_") + elif type(x) is list: + i = 0 + for a in x: + flatten(a, name + str(i) + "_") + i += 1 + else: + out[name[:-1]] = x + + flatten(y) + return out + + def _handle_get_rule(self, param): + + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) + action_result = self.add_action_result(ActionResult(dict(param))) + + user_id = param["user_id"] + rule_id = param["rule_id"] + + endpoint = "/users/{user_id}/mailFolders/inbox/messageRules/{rule_id}".format( + user_id=user_id, rule_id=rule_id + ) - return action_result.set_status(phantom.APP_SUCCESS, 'Successfully retrieved {} user{}'.format(num_users, '' if num_users == 1 else 's')) + ret_val, rule = self._make_rest_call_helper(action_result, endpoint) + + if phantom.is_fail(ret_val): + return action_result.get_status() + + if not rule: + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) + + rule = self.flatten_json(rule) + self.debug_print(rule) + action_result.add_data(rule) + + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully retrieved specified inbox rule" + ) def _handle_list_folders(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) list_folder = list() - user_id = param['user_id'] - folder_id = param.get('folder_id') + user_id = param["user_id"] + folder_id = param.get("folder_id") if not folder_id: # fetching root level folders @@ -1595,15 +2081,22 @@ def _handle_list_folders(self, param): # checking for child folder if have, add it in list of folders for root_folder in root_folders: - if root_folder.get('childFolderCount', 0) == 0: + if root_folder.get("childFolderCount", 0) == 0: continue else: - ret_val = self._list_child_folders(action_result, list_folder, user_id=user_id, parent_folder=root_folder) + ret_val = self._list_child_folders( + action_result, + list_folder, + user_id=user_id, + parent_folder=root_folder, + ) if phantom.is_fail(ret_val): return action_result.get_status() else: - ret_val = self._list_child_folders(action_result, list_folder, user_id=user_id, folder_id=folder_id) + ret_val = self._list_child_folders( + action_result, list_folder, user_id=user_id, folder_id=folder_id + ) if phantom.is_fail(ret_val): return action_result.get_status() @@ -1612,10 +2105,14 @@ def _handle_list_folders(self, param): action_result.add_data(folder) num_folders = len(list_folder) - action_result.update_summary({'total_folders_returned': num_folders}) + action_result.update_summary({"total_folders_returned": num_folders}) - return action_result.set_status(phantom.APP_SUCCESS, 'Successfully retrieved {} mail folder{}'.format( - num_folders, '' if num_folders == 1 else 's')) + return action_result.set_status( + phantom.APP_SUCCESS, + "Successfully retrieved {} mail folder{}".format( + num_folders, "" if num_folders == 1 else "s" + ), + ) def _fetch_root_folders(self, action_result, user_id): @@ -1627,17 +2124,28 @@ def _fetch_root_folders(self, action_result, user_id): return action_result.get_status(), None if not folders: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND), None + return ( + action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ), + None, + ) return phantom.APP_SUCCESS, folders - def _list_child_folders(self, action_result, list_folder, user_id, parent_folder=None, folder_id=None): + def _list_child_folders( + self, action_result, list_folder, user_id, parent_folder=None, folder_id=None + ): # fetching root level folders if not folder_id: - ret_val, child_folders = self._fetch_child_folders(action_result, user_id, parent_folder['id']) + ret_val, child_folders = self._fetch_child_folders( + action_result, user_id, parent_folder["id"] + ) else: - ret_val, child_folders = self._fetch_child_folders(action_result, user_id, folder_id) + ret_val, child_folders = self._fetch_child_folders( + action_result, user_id, folder_id + ) if phantom.is_fail(ret_val): return action_result.get_status() @@ -1645,10 +2153,15 @@ def _list_child_folders(self, action_result, list_folder, user_id, parent_folder # checking for child folder if have, add it in list of folders for child_folder in child_folders: - if child_folder.get('childFolderCount', 0) == 0: + if child_folder.get("childFolderCount", 0) == 0: list_folder.append(child_folder) else: - ret_val = self._list_child_folders(action_result, list_folder, user_id=user_id, parent_folder=child_folder) + ret_val = self._list_child_folders( + action_result, + list_folder, + user_id=user_id, + parent_folder=child_folder, + ) if phantom.is_fail(ret_val): return action_result.get_status() @@ -1659,7 +2172,9 @@ def _list_child_folders(self, action_result, list_folder, user_id, parent_folder def _fetch_child_folders(self, action_result, user_id, folder_id): - endpoint = '/users/{user_id}/mailFolders/{folder_id}/childFolders'.format(user_id=user_id, folder_id=folder_id) + endpoint = "/users/{user_id}/mailFolders/{folder_id}/childFolders".format( + user_id=user_id, folder_id=folder_id + ) ret_val, folders = self._paginator(action_result, endpoint) @@ -1676,133 +2191,185 @@ def _flatten_headers(self, headers): for field in headers: - if field['name'] == 'Received': - if 'Received' not in new_headers: - new_headers['Received'] = [] - new_headers['Received'].append(field['value']) + if field["name"] == "Received": + if "Received" not in new_headers: + new_headers["Received"] = [] + new_headers["Received"].append(field["value"]) continue - new_headers[field['name']] = field['value'] + new_headers[field["name"]] = field["value"] return new_headers def _handle_get_email(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] - message_id = param['id'] - endpoint = '/users/{0}'.format(email_addr) + email_addr = param["email_address"] + message_id = param["id"] + endpoint = "/users/{0}".format(email_addr) - endpoint += '/messages/{0}'.format(message_id) + endpoint += "/messages/{0}".format(message_id) ret_val, response = self._make_rest_call_helper(action_result, endpoint) if phantom.is_fail(ret_val): return action_result.get_status() - if param.get('extract_headers'): - header_endpoint = endpoint + '?$select=internetMessageHeaders' - ret_val, header_response = self._make_rest_call_helper(action_result, header_endpoint) + if param.get("extract_headers"): + header_endpoint = endpoint + "?$select=internetMessageHeaders" + ret_val, header_response = self._make_rest_call_helper( + action_result, header_endpoint + ) if phantom.is_fail(ret_val): return action_result.get_status() # For Drafts there might not be any internetMessageHeaders, # so we have to use get() fetching instead of directly fetching from dictionary - response['internetMessageHeaders'] = header_response.get('internetMessageHeaders') + response["internetMessageHeaders"] = header_response.get( + "internetMessageHeaders" + ) - if param.get('download_attachments', False) and response.get('hasAttachments'): - endpoint += '/attachments' - attachment_endpoint = '{}?$expand=microsoft.graph.itemattachment/item'.format(endpoint) - ret_val, attach_resp = self._make_rest_call_helper(action_result, attachment_endpoint) + if param.get("download_attachments", False) and response.get("hasAttachments"): + endpoint += "/attachments" + attachment_endpoint = ( + "{}?$expand=microsoft.graph.itemattachment/item".format(endpoint) + ) + ret_val, attach_resp = self._make_rest_call_helper( + action_result, attachment_endpoint + ) if phantom.is_fail(ret_val): return action_result.get_status() - for attachment in attach_resp.get('value', []): + for attachment in attach_resp.get("value", []): # If it is fileAttachment, then we have to ingest it if attachment.get("@odata.type") == "#microsoft.graph.fileAttachment": if not self._handle_attachment(attachment, self.get_container_id()): - return action_result.set_status(phantom.APP_ERROR, 'Could not process attachment. See logs for details') + return action_result.set_status( + phantom.APP_ERROR, + "Could not process attachment. See logs for details", + ) elif attachment.get("@odata.type") == "#microsoft.graph.itemAttachment": - if not self._handle_item_attachment(attachment, self.get_container_id(), endpoint, action_result): - return action_result.set_status(phantom.APP_ERROR, 'Could not process item attachment. See logs for details') - - response['attachments'] = attach_resp['value'] - - if response.get('@odata.type') in ["#microsoft.graph.eventMessage", "#microsoft.graph.eventMessageRequest", - "#microsoft.graph.eventMessageResponse"]: - - event_endpoint = '{}/?$expand=Microsoft.Graph.EventMessage/Event'.format(endpoint) - ret_val, event_resp = self._make_rest_call_helper(action_result, event_endpoint) + if not self._handle_item_attachment( + attachment, self.get_container_id(), endpoint, action_result + ): + return action_result.set_status( + phantom.APP_ERROR, + "Could not process item attachment. See logs for details", + ) + + response["attachments"] = attach_resp["value"] + + if response.get("@odata.type") in [ + "#microsoft.graph.eventMessage", + "#microsoft.graph.eventMessageRequest", + "#microsoft.graph.eventMessageResponse", + ]: + + event_endpoint = "{}/?$expand=Microsoft.Graph.EventMessage/Event".format( + endpoint + ) + ret_val, event_resp = self._make_rest_call_helper( + action_result, event_endpoint + ) if phantom.is_fail(ret_val): return action_result.get_status() - response['event'] = event_resp['event'] + response["event"] = event_resp["event"] - if 'internetMessageHeaders' in response: - response['internetMessageHeaders'] = self._flatten_headers(response['internetMessageHeaders']) + if "internetMessageHeaders" in response: + response["internetMessageHeaders"] = self._flatten_headers( + response["internetMessageHeaders"] + ) # If the response has attachments, update every attachment data with its type # 'attachmentType' key - indicates type of attachment # and if an email has any itemAttachment, then also add itemType in the response # 'itemType' key - indicates type of itemAttachment - if response.get('attachments', []): - for attachment in response['attachments']: - attachment_type = attachment.get('@odata.type', '') - attachment['attachmentType'] = attachment_type - if attachment_type == '#microsoft.graph.itemAttachment': - attachment['itemType'] = attachment.get('item', {}).get('@odata.type', '') - - if param.get('download_email'): - subject = response.get('subject') - email_message = {'id': message_id, 'name': subject if subject else "email_message_{}".format(message_id)} - if not self._handle_item_attachment(email_message, self.get_container_id(), '/users/{0}/messages'.format(email_addr), action_result): - return action_result.set_status(phantom.APP_ERROR, 'Could not download the email. See logs for details') - response['vaultId'] = email_message['vaultId'] + if response.get("attachments", []): + for attachment in response["attachments"]: + attachment_type = attachment.get("@odata.type", "") + attachment["attachmentType"] = attachment_type + if attachment_type == "#microsoft.graph.itemAttachment": + attachment["itemType"] = attachment.get("item", {}).get( + "@odata.type", "" + ) + + if param.get("download_email"): + subject = response.get("subject") + email_message = { + "id": message_id, + "name": subject if subject else "email_message_{}".format(message_id), + } + if not self._handle_item_attachment( + email_message, + self.get_container_id(), + "/users/{0}/messages".format(email_addr), + action_result, + ): + return action_result.set_status( + phantom.APP_ERROR, + "Could not download the email. See logs for details", + ) + response["vaultId"] = email_message["vaultId"] action_result.add_data(response) - return action_result.set_status(phantom.APP_SUCCESS, "Successfully fetched email") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully fetched email" + ) def _handle_get_email_properties(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - email_addr = param['email_address'] - message_id = param['id'] - endpoint = '/users/{0}'.format(email_addr) + email_addr = param["email_address"] + message_id = param["id"] + endpoint = "/users/{0}".format(email_addr) - endpoint += '/messages/{0}'.format(message_id) + endpoint += "/messages/{0}".format(message_id) select_list = [] - if param.get('get_headers'): - select_list.append('internetMessageHeaders') - if param.get('get_body'): - select_list.append('body') - if param.get('get_unique_body'): - select_list.append('uniqueBody') - if param.get('get_sender'): - select_list.append('sender') - if 'properties_list' in param: - properties_list = param['properties_list'] - properties_list = [property.strip() for property in properties_list.strip().split(',') if property.strip()] + if param.get("get_headers"): + select_list.append("internetMessageHeaders") + if param.get("get_body"): + select_list.append("body") + if param.get("get_unique_body"): + select_list.append("uniqueBody") + if param.get("get_sender"): + select_list.append("sender") + if "properties_list" in param: + properties_list = param["properties_list"] + properties_list = [ + property.strip() + for property in properties_list.strip().split(",") + if property.strip() + ] select_list += properties_list if select_list: - endpoint += '?$select={0}'.format(','.join(select_list)) + endpoint += "?$select={0}".format(",".join(select_list)) ret_val, response = self._make_rest_call_helper(action_result, endpoint) if phantom.is_fail(ret_val): return action_result.get_status() - if 'internetMessageHeaders' in response: - response['internetMessageHeaders'] = self._flatten_headers(response['internetMessageHeaders']) + if "internetMessageHeaders" in response: + response["internetMessageHeaders"] = self._flatten_headers( + response["internetMessageHeaders"] + ) action_result.add_data(response) - return action_result.set_status(phantom.APP_SUCCESS, "Successfully fetched email") + return action_result.set_status( + phantom.APP_SUCCESS, "Successfully fetched email" + ) def _manage_data_duplication(self, emails, total_ingested, limit, max_emails): """ @@ -1822,7 +2389,7 @@ def _manage_data_duplication(self, emails, total_ingested, limit, max_emails): return 0, total_ingested expected_duplicate_count_in_next_cycle = 0 - last_modified_time = emails[-1]['lastModifiedDateTime'] + last_modified_time = emails[-1]["lastModifiedDateTime"] # Calculate the duplicate emails count we can get in the next cycle for email in reversed(emails): @@ -1835,62 +2402,74 @@ def _manage_data_duplication(self, emails, total_ingested, limit, max_emails): def _handle_on_poll(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) config = self.get_config() - ingest_manner = config.get('ingest_manner', 'oldest first') + ingest_manner = config.get("ingest_manner", "oldest first") - start_time = '' + start_time = "" if self.is_poll_now(): max_emails = param[phantom.APP_JSON_CONTAINER_COUNT] - elif self._state.get('first_run', True): + elif self._state.get("first_run", True): # Integer validation for 'first_run_max_emails' config parameter ret_val, max_emails = _validate_integer( - action_result, config.get('first_run_max_emails', 1000), "'Maximum Containers for scheduled polling first time' config" + action_result, + config.get("first_run_max_emails", 1000), + "'Maximum Containers for scheduled polling first time' config", ) if phantom.is_fail(ret_val): return action_result.get_status() else: # Integer validation for 'max_containers' config parameter ret_val, max_emails = _validate_integer( - action_result, config.get('max_containers', 100), "'Maximum Containers for scheduled polling' config" + action_result, + config.get("max_containers", 100), + "'Maximum Containers for scheduled polling' config", ) if phantom.is_fail(ret_val): return action_result.get_status() - start_time = self._state['last_time'] + start_time = self._state["last_time"] - if not config.get('email_address'): - return action_result.set_status(phantom.APP_ERROR, "Email Address to ingest must be supplied in asset!") - elif not config.get('folder'): - return action_result.set_status(phantom.APP_ERROR, "Folder to ingest from must be supplied in asset!") + if not config.get("email_address"): + return action_result.set_status( + phantom.APP_ERROR, "Email Address to ingest must be supplied in asset!" + ) + elif not config.get("folder"): + return action_result.set_status( + phantom.APP_ERROR, "Folder to ingest from must be supplied in asset!" + ) - endpoint = "/users/{0}".format(config.get('email_address')) + endpoint = "/users/{0}".format(config.get("email_address")) - if 'folder' in config: - folder = config.get('folder', '') - if config.get('get_folder_id', True): + if "folder" in config: + folder = config.get("folder", "") + if config.get("get_folder_id", True): try: dir_id, error, _ = self._get_folder_id(action_result, folder, config.get('email_address')) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) + return action_result.get_status() if dir_id: folder = dir_id else: self.save_progress(error) return action_result.set_status(phantom.APP_ERROR, error) - endpoint += '/mailFolders/{0}'.format(folder) + endpoint += "/mailFolders/{0}".format(folder) - endpoint += '/messages' - order = 'asc' if ingest_manner == 'oldest first' else 'desc' + endpoint += "/messages" + order = "asc" if ingest_manner == "oldest first" else "desc" - params = { - '$orderBy': 'lastModifiedDateTime {}'.format(order) - } + params = {"$orderBy": "lastModifiedDateTime {}".format(order)} + + params['$select'] = ','.join(MSGOFFICE365_SELECT_PARAMETER_LIST) if start_time: - params['$filter'] = "lastModifiedDateTime ge {0}".format(start_time) + params["$filter"] = "lastModifiedDateTime ge {0}".format(start_time) cur_limit = max_emails total_ingested = 0 @@ -1902,46 +2481,67 @@ def _handle_on_poll(self, param): while True: self._duplicate_count = 0 - ret_val, emails = self._paginator(action_result, endpoint, limit=cur_limit, params=params) + ret_val, emails = self._paginator( + action_result, endpoint, limit=cur_limit, params=params + ) if phantom.is_fail(ret_val): return action_result.get_status() if not emails: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) failed_email_ids = 0 total_emails = len(emails) - self.save_progress(f"Total emails fetched: {total_emails}") + self.save_progress("Total emails fetched: {}".format(total_emails)) if self.is_poll_now(): - self.save_progress("Ingesting all possible artifacts (ignoring maximum artifacts value) for POLL NOW") + self.save_progress( + "Ingesting all possible artifacts (ignoring maximum artifacts value) for POLL NOW" + ) for index, email in enumerate(emails): try: - self.send_progress('Processing email # {} with ID ending in: {}'.format(index + 1, email['id'][-10:])) - ret_val = self._process_email_data(config, action_result, endpoint, email) + self.send_progress( + "Processing email # {} with ID ending in: {}".format( + index + 1, email["id"][-10:] + ) + ) + ret_val = self._process_email_data( + config, action_result, endpoint, email + ) if phantom.is_fail(ret_val): failed_email_ids += 1 - self.debug_print(f"Error occurred while processing email ID: {email.get('id')}. {action_result.get_message()}") + + self.debug_print("Error occurred while processing email ID: {}. {}".format(email.get('id'), action_result.get_message())) except Exception as e: failed_email_ids += 1 - error_msg = _get_error_message_from_exception(e) + error_msg = _get_error_msg_from_exception(e, self) + self._dump_error_log(e) self.debug_print(f"Exception occurred while processing email ID: {email.get('id')}. {error_msg}") if failed_email_ids == total_emails: - return action_result.set_status(phantom.APP_ERROR, "Error occurred while processing all the email IDs") + return action_result.set_status( + phantom.APP_ERROR, + "Error occurred while processing all the email IDs", + ) if not self.is_poll_now(): - last_time = datetime.strptime(emails[email_index]['lastModifiedDateTime'], O365_TIME_FORMAT).strftime(O365_TIME_FORMAT) - self._state['last_time'] = last_time + last_time = datetime.strptime( + emails[email_index]["lastModifiedDateTime"], O365_TIME_FORMAT + ).strftime(O365_TIME_FORMAT) + self._state["last_time"] = last_time self.save_state(deepcopy(self._state)) # Setting filter for next cycle - params['$filter'] = "lastModifiedDateTime ge {0}".format(last_time) + params["$filter"] = "lastModifiedDateTime ge {0}".format(last_time) # Duplication logic should only work for the oldest first order and if we have more data on the server. if total_emails >= cur_limit and email_index == -1: - cur_limit, total_ingested = self._manage_data_duplication(emails, total_ingested, cur_limit, max_emails) + cur_limit, total_ingested = self._manage_data_duplication( + emails, total_ingested, cur_limit, max_emails + ) if not cur_limit: break else: @@ -1950,114 +2550,139 @@ def _handle_on_poll(self, param): break # Update the 'first_run' value only if the ingestion gets successfully completed - if not self.is_poll_now() and self._state.get('first_run', True): - self._state['first_run'] = False + if not self.is_poll_now() and self._state.get("first_run", True): + self._state["first_run"] = False return action_result.set_status(phantom.APP_SUCCESS) def _validate_range(self, email_range, action_result): try: - mini, maxi = (int(x) for x in email_range.split('-')) + mini, maxi = (int(x) for x in email_range.split("-")) except Exception: - return action_result.set_status(phantom.APP_ERROR, "Unable to parse the range. Please specify the range as min_offset-max_offset") + return action_result.set_status( + phantom.APP_ERROR, + "Unable to parse the range. Please specify the range as min_offset-max_offset", + ) if mini < 0 or maxi < 0: - return action_result.set_status(phantom.APP_ERROR, "Invalid min or max offset value specified in range", ) + return action_result.set_status( + phantom.APP_ERROR, + "Invalid min or max offset value specified in range", + ) if mini > maxi: - return action_result.set_status(phantom.APP_ERROR, "Invalid range value, min_offset greater than max_offset") + return action_result.set_status( + phantom.APP_ERROR, + "Invalid range value, min_offset greater than max_offset", + ) if maxi > MAX_END_OFFSET_VAL: - return action_result.set_status(phantom.APP_ERROR, "Invalid range value. The max_offset value cannot be greater than {0}".format( - MAX_END_OFFSET_VAL)) + return action_result.set_status( + phantom.APP_ERROR, + "Invalid range value. The max_offset value cannot be greater than {0}".format( + MAX_END_OFFSET_VAL + ), + ) - return (phantom.APP_SUCCESS) + return phantom.APP_SUCCESS def _handle_generate_token(self, param): - self.save_progress('In action handler for: {0}'.format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) ret_val = self._get_token(action_result) if phantom.is_fail(ret_val): return action_result.get_status() - self._state['admin_consent'] = True + self._state["admin_consent"] = True return action_result.set_status(phantom.APP_SUCCESS, "Token generated") def _handle_run_query(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) - limit = param.get('limit') + limit = param.get("limit") # Integer validation for 'limit' action parameter ret_val, limit = _validate_integer(action_result, limit, "'limit' action") if phantom.is_fail(ret_val): return action_result.get_status() # user - email_addr = param['email_address'] + email_addr = param["email_address"] endpoint = "/users/{0}".format(email_addr) query = "" params = dict() - if 'internet_message_id' in param: + if "internet_message_id" in param: params = { - '$filter': "internetMessageId eq '{0}'".format(param['internet_message_id']) + "$filter": "internetMessageId eq '{0}'".format( + param["internet_message_id"] + ) } - elif 'query' in param: - query = "?{0}".format(param['query']) + elif "query" in param: + query = "?{0}".format(param["query"]) else: # search params - search_query = '' - if 'subject' in param: - search_query += "subject:{0} ".format(param['subject']) + search_query = "" + if "subject" in param: + search_query += "subject:{0} ".format(param["subject"]) - if 'body' in param: - search_query += "body:{0} ".format(param['body']) + if "body" in param: + search_query += "body:{0} ".format(param["body"]) - if 'sender' in param: - search_query += "from:{0} ".format(param['sender']) + if "sender" in param: + search_query += "from:{0} ".format(param["sender"]) if search_query: - params['$search'] = '"{0}"'.format(search_query[:-1]) + params["$search"] = '"{0}"'.format(search_query[:-1]) folder_ids = [] # searches through well known folders - if param.get('search_well_known_folders', False): + if param.get("search_well_known_folders", False): endpoint += "/mailFolders" folder_params = { - '$filter': "{}".format(MSGOFFICE365_WELL_KNOWN_FOLDERS_FILTER) + "$filter": "{}".format(MSGOFFICE365_WELL_KNOWN_FOLDERS_FILTER) } - ret_val, response = self._paginator(action_result, endpoint, params=folder_params) + ret_val, response = self._paginator( + action_result, endpoint, params=folder_params + ) if phantom.is_fail(ret_val): return action_result.set_status(phantom.APP_ERROR) if not response: - return action_result.set_status(phantom.APP_SUCCESS, "No well known folders found") + return action_result.set_status( + phantom.APP_SUCCESS, "No well known folders found" + ) folders = response for folder in folders: - folder_ids.append(folder.get('id')) + folder_ids.append(folder.get("id")) endpoint += "/{folder_id}" # folder - elif 'folder' in param: + elif "folder" in param: - folder = param['folder'] + folder = param["folder"] - if param.get('get_folder_id', True): + if param.get("get_folder_id", True): try: dir_id, error, _ = self._get_folder_id(action_result, folder, email_addr) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) + return action_result.get_status() if dir_id: folder = dir_id @@ -2065,17 +2690,21 @@ def _handle_run_query(self, param): self.save_progress(error) return action_result.set_status(phantom.APP_ERROR, error) folder_ids.append(folder) - endpoint += '/mailFolders/{folder_id}' + endpoint += "/mailFolders/{folder_id}" # that should be enough to create the endpoint - endpoint += '/messages' + endpoint += "/messages" if folder_ids: messages = [] ret_val = False for folder_id in folder_ids: - folder_ret_val, folder_messages = self._paginator(action_result, endpoint.format( - folder_id=folder_id) + query, limit, params=params) + folder_ret_val, folder_messages = self._paginator( + action_result, + endpoint.format(folder_id=folder_id) + query, + limit, + params=params, + ) if phantom.is_fail(folder_ret_val): continue @@ -2084,31 +2713,35 @@ def _handle_run_query(self, param): messages.extend(folder_messages) else: - ret_val, messages = self._paginator(action_result, endpoint, limit, params=params) + ret_val, messages = self._paginator( + action_result, endpoint, limit, params=params + ) if phantom.is_fail(ret_val): msg = action_result.get_message() - if '$top' in msg or '$top/top' in msg: + if "$top" in msg or "$top/top" in msg: msg += "The '$top' parameter is already used internally to handle pagination logic. " msg += "If you want to restrict results in terms of number of output results, you can use the 'limit' parameter." return action_result.set_status(phantom.APP_ERROR, msg) return action_result.get_status() if not messages: - return action_result.set_status(phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND) + return action_result.set_status( + phantom.APP_SUCCESS, MSGOFFICE365_NO_DATA_FOUND + ) action_result.update_data(messages) - action_result.update_summary({'emails_matched': action_result.get_data_size()}) + action_result.update_summary({"emails_matched": action_result.get_data_size()}) return action_result.set_status(phantom.APP_SUCCESS) def _get_folder_id(self, action_result, folder, email): # hindsight is always 20-20, set the folder path separator to be '/', thinking folder names allow '\' as a char. # turns out even '/' is supported by office365, so let the action escape the '/' char if it's part of the folder name - folder_path = folder.replace('\\/', self._REPLACE_CONST) - folder_names = folder_path.split('/') + folder_path = folder.replace("\\/", self._REPLACE_CONST) + folder_names = folder_path.split("/") for i, folder_name in enumerate(folder_names): - folder_names[i] = folder_name.replace(self._REPLACE_CONST, '/').strip() + folder_names[i] = folder_name.replace(self._REPLACE_CONST, "/").strip() # remove empty elements path = list(filter(None, folder_names)) @@ -2117,6 +2750,7 @@ def _get_folder_id(self, action_result, folder, email): try: dir_id = self._get_folder(action_result, path[0], email) except ReturnException as e: + self._dump_error_log(e) return None, "Error occurred while fetching folder {}. {}".format(path[0], e), None if not dir_id: @@ -2126,15 +2760,20 @@ def _get_folder_id(self, action_result, folder, email): try: for i, subf in enumerate(path[1:]): - subpath = "/".join(path[0:i + 2]) + subpath = "/".join(path[0: i + 2]) parent_id = dir_id dir_id = self._get_child_folder(action_result, subf, parent_id, email) if not dir_id: - return None, "Error: child folder not found; {}".format(subpath), ret + return ( + None, + "Error: child folder not found; {}".format(subpath), + ret, + ) ret.append({"path": subpath, "folder": subf, "folder_id": dir_id}) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) return None, action_result.get_message(), None return dir_id, None, ret @@ -2142,36 +2781,40 @@ def _get_folder_id(self, action_result, folder, email): def _get_folder(self, action_result, folder, email): params = {} - params['$filter'] = "displayName eq '{}'".format(folder) + params["$filter"] = "displayName eq '{}'".format(folder) endpoint = "/users/{}/mailFolders".format(email) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, params=params) + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, params=params + ) if phantom.is_fail(ret_val): raise ReturnException(action_result.get_message()) - value = response.get('value', []) + value = response.get("value", []) if len(value) > 0: self._currentdir = value[0] - return value[0]['id'] + return value[0]["id"] return None def _get_child_folder(self, action_result, folder, parent_id, email): params = {} - params['$filter'] = "displayName eq '{}'".format(folder) + params["$filter"] = "displayName eq '{}'".format(folder) endpoint = "/users/{}/mailFolders/{}/childFolders".format(email, parent_id) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, params=params) + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, params=params + ) if phantom.is_fail(ret_val): raise ReturnException() - value = response.get('value', []) + value = response.get("value", []) if len(value) > 0: self._currentdir = value[0] - return value[0]['id'] + return value[0]["id"] return None @@ -2180,14 +2823,16 @@ def _new_folder(self, action_result, folder, email): data = json.dumps({"displayName": folder}) endpoint = "/users/{}/mailFolders".format(email) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, data=data, method="post") + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, data=data, method="post" + ) if phantom.is_fail(ret_val): raise ReturnException() - if response.get('id', False): + if response.get("id", False): self._currentdir = response self.save_progress("Success({}): created folder in mailbox".format(folder)) - return response['id'] + return response["id"] msg = "Error({}): unable to create folder in mailbox".format(folder) self.save_progress(msg) @@ -2199,23 +2844,33 @@ def _new_child_folder(self, action_result, folder, parent_id, email, pathsofar): data = json.dumps({"displayName": folder}) endpoint = "/users/{}/mailFolders/{}/childFolders".format(email, parent_id) - ret_val, response = self._make_rest_call_helper(action_result, endpoint, data=data, method="post") + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, data=data, method="post" + ) if phantom.is_fail(ret_val): raise ReturnException() - if response.get('id', False): + if response.get("id", False): self._currentdir = response - self.save_progress("Success({}): created child folder in folder {}".format(folder, pathsofar)) - return response['id'] + self.save_progress( + "Success({}): created child folder in folder {}".format( + folder, pathsofar + ) + ) + return response["id"] - msg = "Error({}): unable to create child folder in folder {}".format(folder, pathsofar) + msg = "Error({}): unable to create child folder in folder {}".format( + folder, pathsofar + ) self.save_progress(msg) action_result.set_status(phantom.APP_ERROR, msg) raise ReturnException() def _handle_create_folder(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) email = param["email_address"] @@ -2225,10 +2880,10 @@ def _handle_create_folder(self, param): # hindsight is always 20-20, set the folder path separator to be '/', thinking folder names allow '\' as a char. # turns out even '/' is supported by office365, so let the action escape the '/' char if it's part of the folder name - folder_path = folder.replace('\\/', self._REPLACE_CONST) - folder_names = folder_path.split('/') + folder_path = folder.replace("\\/", self._REPLACE_CONST) + folder_names = folder_path.split("/") for i, folder_name in enumerate(folder_names): - folder_names[i] = folder_name.replace(self._REPLACE_CONST, '/').strip() + folder_names[i] = folder_name.replace(self._REPLACE_CONST, "/").strip() # remove empty elements path = list(filter(None, folder_names)) @@ -2265,7 +2920,9 @@ def _handle_create_folder(self, param): action_result.add_data(self._currentdir) else: - msg = "Error({}): folder doesn't exists in mailbox".format(path[0]) + msg = "Error({}): folder doesn't exists in mailbox".format( + path[0] + ) self.save_progress(msg) return action_result.set_status(phantom.APP_ERROR, msg) @@ -2279,15 +2936,21 @@ def _handle_create_folder(self, param): # next all the childFolders in between for subf in path: - dir_id = self._get_child_folder(action_result, subf, parent_id, email) + dir_id = self._get_child_folder( + action_result, subf, parent_id, email + ) if not dir_id: if minusp: - dir_id = self._new_child_folder(action_result, subf, parent_id, email, pathsofar) + dir_id = self._new_child_folder( + action_result, subf, parent_id, email, pathsofar + ) action_result.add_data(self._currentdir) else: - msg = "Error({}): child folder doesn't exists in folder {}".format(subf, pathsofar) + msg = "Error({}): child folder doesn't exists in folder {}".format( + subf, pathsofar + ) self.save_progress(msg) return action_result.set_status(phantom.APP_ERROR, msg) @@ -2297,22 +2960,34 @@ def _handle_create_folder(self, param): # finally, the actual folder dir_id = self._get_child_folder(action_result, final, parent_id, email) if dir_id: - msg = "Error: child folder {0} already exists in the folder {1}".format(final, pathsofar) + msg = "Error: child folder {0} already exists in the folder {1}".format( + final, pathsofar + ) self.save_progress(msg) return action_result.set_status(phantom.APP_ERROR, msg) - dir_id = self._new_child_folder(action_result, final, parent_id, email, pathsofar) + dir_id = self._new_child_folder( + action_result, final, parent_id, email, pathsofar + ) action_result.add_data(self._currentdir) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) return action_result.get_status() - action_result.update_summary({"folders created": len(action_result.get_data()), "folder": self._currentdir['id']}) + action_result.update_summary( + { + "folders created": len(action_result.get_data()), + "folder": self._currentdir["id"], + } + ) return action_result.set_status(phantom.APP_SUCCESS) def _handle_get_folder_id(self, param): - self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + self.save_progress( + "In action handler for: {0}".format(self.get_action_identifier()) + ) action_result = self.add_action_result(ActionResult(dict(param))) email = param["email_address"] @@ -2321,7 +2996,8 @@ def _handle_get_folder_id(self, param): try: dir_id, error, ret = self._get_folder_id(action_result, folder, email) - except ReturnException: + except ReturnException as e: + self._dump_error_log(e) return action_result.get_status() if ret and len(ret) > 0: @@ -2336,6 +3012,208 @@ def _handle_get_folder_id(self, param): self.save_progress(error) return action_result.set_status(phantom.APP_ERROR, error) + def _email_to_recipient(self, email: str): + recipient = { + "emailAddress": { + "address": email + } + } + return recipient + + def _create_draft_message(self, action_result, subject: str, body: str, from_email: str, + *, to_emails: list[str], cc_emails: list[str], bcc_emails: list[str], headers: dict[str, str]): + endpoint = '/users/{}/messages'.format(from_email) + req_headers = { + 'Prefer': 'IdType="ImmutableId"' + } + msg = { + "subject": subject, + "body": { + "contentType": "HTML", + "content": body + } + } + if to_emails: + msg['toRecipients'] = [self._email_to_recipient(email) for email in to_emails] + if cc_emails: + msg['ccRecipients'] = [self._email_to_recipient(email) for email in cc_emails] + if bcc_emails: + msg['bccRecipients'] = [self._email_to_recipient(email) for email in bcc_emails] + if headers: + msg['internetMessageHeaders'] = [ + {'name': key, 'value': value} for key, value in headers.items()] + + ret_val, response = self._make_rest_call_helper(action_result, endpoint, method='post', headers=req_headers, data=json.dumps(msg)) + + if phantom.is_fail(ret_val): + return action_result.get_status(), None + + message_id = response['id'] + return action_result, message_id + + def _send_draft_message(self, action_result, user_id, message_id): + endpoint = "/users/{}/messages/{}/send".format(user_id, message_id) + + ret_val, _ = self._make_rest_call_helper(action_result, endpoint, method='post') + if phantom.is_fail(ret_val): + return action_result.set_status(phantom.APP_ERROR, "Failed to send draft email with id: {}".format(message_id)), None + + return action_result, message_id + + def _get_vault_info(self, vault_id): + _, _, vault_infos = phantom_vault.vault_info(container_id=self.get_container_id(), vault_id=vault_id) + if not vault_infos: + _, _, vault_infos = phantom_vault.vault_info(vault_id=vault_id) + return vault_infos[0] if vault_infos else None + + def _add_attachment_to_message(self, action_result, vault_id, user_id, message_id): + vault_info = self._get_vault_info(vault_id) + if not vault_info: + return action_result.set_status(phantom.APP_ERROR, "Failed to find vault entry {}".format(vault_id)), None + + if vault_info['size'] > MSGOFFICE365_UPLOAD_SESSION_CUTOFF: + ret_val, attachment_id = self._upload_large_attachment(action_result, vault_info, user_id, message_id) + else: + ret_val, attachment_id = self._upload_small_attachment(action_result, vault_info, user_id, message_id) + + return ret_val, attachment_id + + def _upload_small_attachment(self, action_result, vault_info, user_id, message_id): + endpoint = "/users/{}/messages/{}/attachments".format(user_id, message_id) + with open(vault_info['path'], mode='rb') as file: + file_content = file.read() + data = { + '@odata.type': '#microsoft.graph.fileAttachment', + 'name': vault_info['name'], + 'contentType': vault_info['mime_type'], + 'contentBytes': base64.b64encode(file_content).decode('ascii'), + 'contentId': vault_info['vault_id'] + } + ret_val, response = self._make_rest_call_helper(action_result, endpoint, method='post', data=json.dumps(data)) + if phantom.is_fail(ret_val): + return action_result.set_status(phantom.APP_ERROR, "Failed to upload vault entry {}".format(vault_info["vault_id"])), None + attachment_id = response['id'] + return phantom.APP_SUCCESS, attachment_id + + def _upload_large_attachment(self, action_result, vault_info, user_id, message_id): + endpoint = "/users/{}/messages/{}/attachments/createUploadSession".format(user_id, message_id) + file_size = vault_info['size'] + data = { + 'AttachmentItem': { + 'attachmentType': 'file', + 'name': vault_info['name'], + 'contentType': vault_info['mime_type'], + 'contentId': vault_info['vault_id'], + 'size': file_size + } + } + ret_val, response = self._make_rest_call_helper(action_result, endpoint, method='post', data=json.dumps(data)) + if phantom.is_fail(ret_val): + return action_result.set_status(phantom.APP_ERROR, "Failed to upload vault entry {}".format(vault_info["vault_id"])), None + upload_url = response['uploadUrl'] + + with open(vault_info['path'], mode='rb') as file: + for start_position in range(0, file_size, MSGOFFICE365_UPLOAD_LARGE_FILE_CUTOFF): + file_content = file.read(MSGOFFICE365_UPLOAD_LARGE_FILE_CUTOFF) + end_position = start_position + len(file_content) - 1 + headers = { + 'Content-Type': 'application/octet-stream', + 'Content-Range': "bytes {}-{}/{}".format(start_position, end_position, file_size) + } + flag = True + while flag: + response = requests.put(upload_url, headers=headers, data=file_content) + + if response.status_code == 429 and response.headers['Retry-After']: + retry_time = int(response.headers['Retry-After']) + + if retry_time > 300: # throw error if wait time greater than 300 seconds + self.debug_print("Retry is canceled as retry time is greater than 300 seconds") + self._process_response(response, action_result) + return action_result.set_status( + phantom.APP_ERROR, "Failed to upload file, {} Please retry after \ + {} seconds".format(action_result.get_message(), retry_time ) + ), None + self.debug_print("Retrying after {} seconds".format(retry_time)) + time.sleep(retry_time + 1) + elif not response.ok: + return action_result.set_status( + phantom.APP_ERROR, "Failed to upload file, Error occurred : {}, {}".format(response.status_code, str(response.text)) + ), None + else: + flag = False + + result_location = response.headers.get('Location', 'no_location_found') + match = re.search(r"Attachments\('(?P[^']+)'\)", result_location) + if not match: + return action_result.set_status(phantom.APP_ERROR, "Unable to extract attachment id from url {}".format(result_location)), None + attachment_id = match.group('attachment_id') + return phantom.APP_SUCCESS, attachment_id + + def _get_message(self, action_result, user_id, message_id): + endpoint = "/users/{}/messages/{}".format(user_id, message_id) + + ret_val, response = self._make_rest_call_helper(action_result, endpoint, method='get') + if phantom.is_fail(ret_val): + return action_result.set_status(phantom.APP_ERROR, "Failed to get email with id: {}".format(message_id)), None + + return action_result, response + + def _handle_send_email(self, param): + self.save_progress("In action handler for: {}".format(self.get_action_identifier())) + action_result = self.add_action_result(ActionResult(dict(param))) + config = self.get_config() + + from_email = param.get('from') or config.get('email_address') + to_emails = [email for x in param.get('to', '').split(',') if (email := x.strip())] + cc_emails = [email for x in param.get('cc', '').split(',') if (email := x.strip())] + bcc_emails = [email for x in param.get('bcc', '').split(',') if (email := x.strip())] + + subject = param['subject'] + + try: + headers = json.loads(param.get('headers', '{}')) + except Exception: + return action_result.set_status(phantom.APP_ERROR, "Please enter headers in a valid JSON format") + + body = param['body'] + vault_ids = [vault_id for x in param.get('attachments', '').split(',') if (vault_id := x.strip())] + + self.save_progress("Creating draft message") + ret_val, message_id = self._create_draft_message(action_result, subject, body, from_email, headers=headers, + to_emails=to_emails, cc_emails=cc_emails, bcc_emails=bcc_emails) + if phantom.is_fail(ret_val): + return action_result + self.save_progress("Created draft message with id: {}".format(message_id)) + + attachments = [] + for vault_id in vault_ids: + self.save_progress("Creating attachment for vault id: {}".format(vault_id)) + ret_val, attachment_id = self._add_attachment_to_message(action_result, vault_id, from_email, message_id) + if phantom.is_fail(ret_val): + return action_result + self.save_progress("Created attachment with id: {}".format(attachment_id)) + attachment = { + 'vault_id': vault_id, + 'attachment_id': attachment_id + } + attachments.append(attachment) + + self.save_progress("Sending draft email with id: {}".format(message_id)) + ret_val, message_id = self._send_draft_message(action_result, from_email, message_id) + if phantom.is_fail(ret_val): + return action_result + self.save_progress("Successfully sent draft email.") + + self.save_progress("Getting sent email details with id: {}".format(message_id)) + ret_val, message_details = self._get_message(action_result, from_email, message_id) + if phantom.is_fail(ret_val): + return action_result + self.save_progress("Got sent email details.") + + action_result.add_data(message_details) + return action_result.set_status(phantom.APP_SUCCESS, "Successfully sent email") + def _paginator(self, action_result, endpoint, limit=None, params=None, query=None): """ This action is used to create an iterator that will paginate through responses from called methods. @@ -2364,9 +3242,13 @@ def _paginator(self, action_result, endpoint, limit=None, params=None, query=Non while True: if next_link: - ret_val, response = self._make_rest_call_helper(action_result, endpoint, nextLink=next_link, params=params) + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, nextLink=next_link, params=params + ) else: - ret_val, response = self._make_rest_call_helper(action_result, endpoint, params=params) + ret_val, response = self._make_rest_call_helper( + action_result, endpoint, params=params + ) if phantom.is_fail(ret_val): return action_result.get_status(), None @@ -2377,7 +3259,7 @@ def _paginator(self, action_result, endpoint, limit=None, params=None, query=Non if limit and len(list_items) >= limit: return phantom.APP_SUCCESS, list_items[:limit] - next_link = response.get('@odata.nextLink') + next_link = response.get("@odata.nextLink") if not next_link: break @@ -2394,115 +3276,128 @@ def handle_action(self, param): self.debug_print("action_id", self.get_action_identifier()) - if action_id == 'test_connectivity': + if action_id == "test_connectivity": ret_val = self._handle_test_connectivity(param) - elif action_id == 'copy_email': + elif action_id == "copy_email": ret_val = self._handle_copy_email(param) - elif action_id == 'move_email': + elif action_id == "move_email": ret_val = self._handle_move_email(param) - elif action_id == 'delete_email': + elif action_id == "delete_email": ret_val = self._handle_delete_email(param) - elif action_id == 'delete_event': + elif action_id == "delete_event": ret_val = self._handle_delete_event(param) - elif action_id == 'get_email': + elif action_id == "get_email": ret_val = self._handle_get_email(param) - elif action_id == 'get_email_properties': + elif action_id == "get_email_properties": ret_val = self._handle_get_email_properties(param) - elif action_id == 'on_poll': + elif action_id == "on_poll": ret_val = self._handle_on_poll(param) - elif action_id == 'run_query': + elif action_id == "run_query": ret_val = self._handle_run_query(param) - elif action_id == 'list_events': + elif action_id == "list_events": ret_val = self._handle_list_events(param) - elif action_id == 'list_groups': + elif action_id == "list_groups": ret_val = self._handle_list_groups(param) - elif action_id == 'list_group_members': + elif action_id == "list_group_members": ret_val = self._handle_list_group_members(param) - elif action_id == 'list_users': + elif action_id == "list_users": ret_val = self._handle_list_users(param) - elif action_id == 'list_folders': + elif action_id == "list_folders": ret_val = self._handle_list_folders(param) - elif action_id == 'oof_check': + elif action_id == "oof_check": ret_val = self._handle_oof_check(param) - elif action_id == 'generate_token': + elif action_id == "generate_token": ret_val = self._handle_generate_token(param) - elif action_id == 'create_folder': + elif action_id == "create_folder": ret_val = self._handle_create_folder(param) - elif action_id == 'get_folder_id': + elif action_id == "get_folder_id": ret_val = self._handle_get_folder_id(param) + elif action_id == "list_rules": + ret_val = self._handle_list_rules(param) + + elif action_id == "get_rule": + ret_val = self._handle_get_rule(param) + + elif action_id == 'send_email': + ret_val = self._handle_send_email(param) + return ret_val def _get_token(self, action_result): req_url = SERVER_TOKEN_URL.format(self._tenant) - headers = { - 'Content-Type': 'application/x-www-form-urlencoded' - } + headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { - 'client_id': self._client_id, - 'client_secret': self._client_secret, - 'grant_type': 'client_credentials' + "client_id": self._client_id, + "client_secret": self._client_secret, + "grant_type": "client_credentials", } if not self._admin_access: - data['scope'] = 'offline_access ' + self._scope + data["scope"] = "offline_access " + self._scope else: - data['scope'] = 'https://graph.microsoft.com/.default' + data["scope"] = "https://graph.microsoft.com/.default" if not self._admin_access: if self._refresh_token: - data['refresh_token'] = self._refresh_token - data['grant_type'] = 'refresh_token' - elif self._state.get('code'): - data['redirect_uri'] = self._state.get('redirect_uri') - data['code'] = self._state.get('code') - data['grant_type'] = 'authorization_code' + data["refresh_token"] = self._refresh_token + data["grant_type"] = "refresh_token" + elif self._state.get("code"): + data["redirect_uri"] = self._state.get("redirect_uri") + data["code"] = self._state.get("code") + data["grant_type"] = "authorization_code" else: - return action_result.set_status(phantom.APP_ERROR, "Unexpected details retrieved from the state file.") + return action_result.set_status( + phantom.APP_ERROR, + "Unexpected details retrieved from the state file.", + ) self.debug_print("Generating token...") - ret_val, resp_json = self._make_rest_call(action_result, req_url, headers=headers, data=data, method='post') + ret_val, resp_json = self._make_rest_call( + action_result, req_url, headers=headers, data=data, method="post" + ) if phantom.is_fail(ret_val): return action_result.get_status() # Save the response on the basis of admin_access if self._admin_access: # if admin consent already provided, save to state if self._admin_consent: - self._state['admin_consent'] = True - self._state['admin_auth'] = resp_json + self._state["admin_consent"] = True + self._state["admin_auth"] = resp_json else: - self._state['non_admin_auth'] = resp_json + self._state["non_admin_auth"] = resp_json # Fetching the access token and refresh token - self._access_token = resp_json.get('access_token') - self._refresh_token = resp_json.get('refresh_token') + self._access_token = resp_json.get("access_token") + self._refresh_token = resp_json.get("refresh_token") # Save state self.save_state(self._state) self._state = self.load_state() if not isinstance(self._state, dict): - self.debug_print(MSGOFFICE365_STATE_FILE_CORRUPT_ERR) + self.debug_print(MSGOFFICE365_STATE_FILE_CORRUPT_ERROR) self._reset_state_file() - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_STATE_FILE_CORRUPT_ERR) + + return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_STATE_FILE_CORRUPT_ERROR) # Scenario - # @@ -2512,11 +3407,13 @@ def _get_token(self, action_result): # after successful generation of new token are same or not. if self._admin_access: + if self._access_token != self._state.get('admin_auth', {}).get('access_token'): - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_INVALID_PERMISSION_ERR) + return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_INVALID_PERMISSION_ERROR) else: if self._access_token != self._state.get('non_admin_auth', {}).get('access_token'): - return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_INVALID_PERMISSION_ERR) + return action_result.set_status(phantom.APP_ERROR, MSGOFFICE365_INVALID_PERMISSION_ERROR) + self.debug_print("Token generated successfully") return action_result.set_status(phantom.APP_SUCCESS) @@ -2541,9 +3438,10 @@ def initialize(self): # Load all the asset configuration in global variables self._state = self.load_state() if not isinstance(self._state, dict): - self.debug_print(MSGOFFICE365_STATE_FILE_CORRUPT_ERR) + self.debug_print(MSGOFFICE365_STATE_FILE_CORRUPT_ERROR) self._reset_state_file() - return self.set_status(phantom.APP_ERROR, MSGOFFICE365_STATE_FILE_CORRUPT_ERR) + + return self.set_status(phantom.APP_ERROR, MSGOFFICE365_STATE_FILE_CORRUPT_ERROR) self._tenant = config['tenant'] self._client_id = config['client_id'] @@ -2555,41 +3453,63 @@ def initialize(self): self._number_of_retries = config.get("retry_count", MSGOFFICE365_DEFAULT_NUMBER_OF_RETRIES) ret_val, self._number_of_retries = _validate_integer(self, self._number_of_retries, "'Maximum attempts to retry the API call' asset configuration") + if phantom.is_fail(ret_val): return self.get_status() - self._retry_wait_time = config.get("retry_wait_time", MSGOFFICE365_DEFAULT_RETRY_WAIT_TIME) - ret_val, self._retry_wait_time = _validate_integer(self, self._retry_wait_time, - "'Delay in seconds between retries' asset configuration") + self._retry_wait_time = config.get( + "retry_wait_time", MSGOFFICE365_DEFAULT_RETRY_WAIT_TIME + ) + ret_val, self._retry_wait_time = _validate_integer( + self, + self._retry_wait_time, + "'Delay in seconds between retries' asset configuration", + ) if phantom.is_fail(ret_val): return self.get_status() if not self._admin_access: if not self._scope: - return self.set_status(phantom.APP_ERROR, "Please provide scope for non-admin access in the asset configuration") + return self.set_status( + phantom.APP_ERROR, + "Please provide scope for non-admin access in the asset configuration", + ) - self._access_token = self._state.get('non_admin_auth', {}).get('access_token', None) - self._refresh_token = self._state.get('non_admin_auth', {}).get('refresh_token', None) + self._access_token = self._state.get("non_admin_auth", {}).get( + "access_token", None + ) + self._refresh_token = self._state.get("non_admin_auth", {}).get( + "refresh_token", None + ) else: - self._access_token = self._state.get('admin_auth', {}).get('access_token', None) + self._access_token = self._state.get("admin_auth", {}).get( + "access_token", None + ) - if action_id == 'test_connectivity': + if action_id == "test_connectivity": # User is trying to complete the authentication flow, so just return True from here so that test connectivity continues return phantom.APP_SUCCESS - admin_consent = self._state.get('admin_consent') + admin_consent = self._state.get("admin_consent") # if it was not and the current action is not test connectivity then it's an error if self._admin_access: - if not admin_consent and action_id != 'test_connectivity': - return self.set_status(phantom.APP_ERROR, MSGOFFICE365_RUN_CONNECTIVITY_MSG) + if not admin_consent and action_id != "test_connectivity": + return self.set_status( + phantom.APP_ERROR, MSGOFFICE365_RUN_CONNECTIVITY_MSG + ) - if not self._admin_access and action_id != 'test_connectivity' and (not self._access_token or not self._refresh_token): + if (not self._admin_access and action_id != "test_connectivity" and (not self._access_token or not self._refresh_token)): ret_val = self._get_token(action_result) if phantom.is_fail(ret_val): - return self.set_status(phantom.APP_ERROR, "{0}. {1}".format(MSGOFFICE365_RUN_CONNECTIVITY_MSG, action_result.get_message())) + return self.set_status( + phantom.APP_ERROR, + "{0}. {1}".format( + MSGOFFICE365_RUN_CONNECTIVITY_MSG, action_result.get_message() + ), + ) # Create ProcessEmail Object for on_poll self._process_email = ProcessEmail(self, config) @@ -2604,9 +3524,9 @@ def _get_fips_enabled(self): fips_enabled = is_fips_enabled() if fips_enabled: - self.debug_print('FIPS is enabled') + self.debug_print("FIPS is enabled") else: - self.debug_print('FIPS is not enabled') + self.debug_print("FIPS is not enabled") return fips_enabled def finalize(self): @@ -2616,7 +3536,7 @@ def finalize(self): return phantom.APP_SUCCESS -if __name__ == '__main__': +if __name__ == "__main__": import argparse @@ -2626,30 +3546,54 @@ def finalize(self): argparser = argparse.ArgumentParser() - argparser.add_argument('input_test_json', help='Input Test JSON file') - argparser.add_argument('-u', '--username', help='username', required=False) - argparser.add_argument('-p', '--password', help='password', required=False) - argparser.add_argument('-v', '--verify', action='store_true', help='verify', required=False, default=False) + argparser.add_argument("input_test_json", help="Input Test JSON file") + argparser.add_argument("-u", "--username", help="username", required=False) + argparser.add_argument("-p", "--password", help="password", required=False) + argparser.add_argument( + "-v", + "--verify", + action="store_true", + help="verify", + required=False, + default=False, + ) args = argparser.parse_args() session_id = None verify = args.verify if args.username and args.password: - login_url = '{}login'.format(BaseConnector._get_phantom_base_url()) + login_url = "{}login".format(BaseConnector._get_phantom_base_url()) try: print("Accessing the Login page") - r = requests.get(login_url, verify=verify, timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT) - csrftoken = r.cookies['csrftoken'] - data = {'username': args.username, 'password': args.password, 'csrfmiddlewaretoken': csrftoken} - headers = {'Cookie': 'csrftoken={0}'.format(csrftoken), 'Referer': login_url} + r = requests.get( + login_url, verify=verify, timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT + ) + csrftoken = r.cookies["csrftoken"] + data = { + "username": args.username, + "password": args.password, + "csrfmiddlewaretoken": csrftoken, + } + headers = { + "Cookie": "csrftoken={0}".format(csrftoken), + "Referer": login_url, + } print("Logging into Platform to get the session id") - r2 = requests.post(login_url, verify=verify, data=data, headers=headers, timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT) - session_id = r2.cookies['sessionid'] + r2 = requests.post( + login_url, + verify=verify, + data=data, + headers=headers, + timeout=MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT, + ) + session_id = r2.cookies["sessionid"] except Exception as e: - print("Unable to get session id from the platform. Error: {0}".format(str(e))) + print( + "Unable to get session id from the platform. Error: {0}".format(str(e)) + ) sys.exit(1) if len(sys.argv) < 2: @@ -2665,7 +3609,7 @@ def finalize(self): connector.print_progress_message = True if session_id is not None: - in_json['user_session_token'] = session_id + in_json["user_session_token"] = session_id ret_val = connector._handle_action(json.dumps(in_json), None) print(json.dumps(json.loads(ret_val), indent=4)) diff --git a/office365_consts.py b/office365_consts.py index f80c8a4..f6a02f0 100644 --- a/office365_consts.py +++ b/office365_consts.py @@ -1,6 +1,6 @@ # File: office365_consts.py # -# Copyright (c) 2017-2022 Splunk Inc. +# Copyright (c) 2017-2023 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ # and limitations under the License. TC_STATUS_SLEEP = 2 MSGOFFICE365_PER_PAGE_COUNT = 999 +MSGOFFICE365_UPLOAD_SESSION_CUTOFF = 3145728 # 3MB +MSGOFFICE365_UPLOAD_LARGE_FILE_CUTOFF = 52428800 # 52MB SPLUNK_SOAR_SYS_INFO_URL = "{url}rest/system_info" SPLUNK_SOAR_ASSET_INFO_URL = "{url}rest/asset/{asset_id}" SPLUNK_SOAR_CONTAINER_INFO_URL = "{url}rest/container/{container_id}" @@ -26,19 +28,21 @@ " displayName eq 'msg folder root' or displayName eq 'outbox' or displayName eq 'recoverable items deletions' or "\ "displayName eq 'scheduled' or displayName eq 'search folders' or displayName eq 'sent items' or displayName eq 'server failures' or "\ "displayName eq 'sync issues'" -MSGOFFICE365_STATE_FILE_CORRUPT_ERR = "Error occurred while loading the state file. " \ +MSGOFFICE365_STATE_FILE_CORRUPT_ERROR = "Error occurred while loading the state file. " \ "Resetting the state file with the default format. Please test the connectivity." -MSGOFFICE365_AUTHORIZE_TROUBLESHOOT_MSG = 'If authorization URL fails to communicate with your Splunk SOAR instance, check whether you have: '\ + +MSGOFFICE365_AUTHORIZE_TROUBLESHOOT_MSG = 'If authorization URL fails to communicate with your '\ + 'Splunk SOAR instance, check whether you have: '\ ' 1. Specified the Web Redirect URL of your App -- The Redirect URL should be /result . '\ ' 2. Configured the base URL of your Splunk SOAR Instance at Administration -> Company Settings -> Info' -MSGOFFICE365_INVALID_PERMISSION_ERR = "Error occurred while saving the newly generated access token "\ +MSGOFFICE365_INVALID_PERMISSION_ERROR = "Error occurred while saving the newly generated access token "\ "(in place of the expired token) in the state file." -MSGOFFICE365_INVALID_PERMISSION_ERR += " Please check the owner, owner group, and the permissions of the state file. The Splunk SOAR " -MSGOFFICE365_INVALID_PERMISSION_ERR += "user should have the correct access rights and ownership for the corresponding state file "\ +MSGOFFICE365_INVALID_PERMISSION_ERROR += " Please check the owner, owner group, and the permissions of the state file. The Splunk SOAR " +MSGOFFICE365_INVALID_PERMISSION_ERROR += "user should have the correct access rights and ownership for the corresponding state file "\ "(refer to readme file for more information)." MSGOFFICE365_NO_DATA_FOUND = "No data found" MSGOFFICE365_DUPLICATE_CONTAINER_FOUND_MSG = "duplicate container found" -MSGOFFICE365_ERR_EMPTY_RESPONSE = "Status Code {code}. Empty response and no information in the header." +MSGOFFICE365_ERROR_EMPTY_RESPONSE = "Status Code {code}. Empty response and no information in the header." MSGOFFICE365_DEFAULT_REQUEST_TIMEOUT = 30 # in seconds MSGOFFICE365_DEFAULT_NUMBER_OF_RETRIES = 3 @@ -48,18 +52,61 @@ MSGOFFICE365_INVALID_CLIENT_ID_ERROR_CODE = 'AADSTS700016' MSGOFFICE365_INVALID_TENANT_ID_FORMAT_ERROR_CODE = 'AADSTS900023' MSGOFFICE365_INVALID_TENANT_ID_NOT_FOUND_ERROR_CODE = 'AADSTS90002' -MSGOFFICE365_ASSET_PARAM_CHECK_LIST_ERRORS = [MSGOFFICE365_HTTP_401_STATUS_CODE, MSGOFFICE365_INVALID_CLIENT_ID_ERROR_CODE, +MSGOFFICE365_ASSET_PARAM_CHECK_LIST_ERROR = [MSGOFFICE365_HTTP_401_STATUS_CODE, MSGOFFICE365_INVALID_CLIENT_ID_ERROR_CODE, MSGOFFICE365_INVALID_TENANT_ID_FORMAT_ERROR_CODE, MSGOFFICE365_INVALID_TENANT_ID_NOT_FOUND_ERROR_CODE] # Constants relating to '_get_error_message_from_exception' -ERR_MSG_UNAVAILABLE = "Error message unavailable. Please check the asset configuration and|or action parameters" + +ERROR_MSG_UNAVAILABLE = "Error msg unavailable. Please check the asset configuration and|or action parameters" # Constants relating to 'validate_integer' MSGOFFICE365_VALID_INT_MSG = "Please provide a valid integer value in the {param} parameter" MSGOFFICE365_NON_NEG_NON_ZERO_INT_MSG = ( "Please provide a valid non-zero positive integer value in the {param} parameter" ) +AUTH_FAILURE_MSG = [ + "token is invalid", + "Access token has expired", + "ExpiredAuthenticationToken", + "AuthenticationFailed", + "TokenExpired", + "InvalidAuthenticationToken" +] MSGOFFICE365_NON_NEG_INT_MSG = "Please provide a valid non-negative integer value in the {param} parameter" -MSGOFFICE365_ENCRYPTION_ERR = "Error occurred while encrypting the state file" -MSGOFFICE365_DECRYPTION_ERR = "Error occurred while decrypting the state file" -MSGOFFICE365_UNEXPECTED_ACCESS_TOKEN_ERR = "Found unexpected value of access token. Please run the test connectivity to generate a new token" +MSGOFFICE365_ENCRYPTION_ERROR = "Error occurred while encrypting the state file" +MSGOFFICE365_DECRYPTION_ERROR = "Error occurred while decrypting the state file" +MSGOFFICE365_UNEXPECTED_ACCESS_TOKEN_ERROR = "Found unexpected value of access token. Please run the test connectivity to generate a new token" + +MSGOFFICE365_SELECT_PARAMETER_LIST = [ + "bccRecipients", + "body", + "bodyPreview", + "categories", + "ccRecipients", + "changeKey", + "conversationId", + "conversationIndex", + "createdDateTime", + "flag", + "from", + "hasAttachments", + "id", + "importance", + "inferenceClassification", + "internetMessageHeaders", + "isDeliveryReceiptRequested", + "isDraft", + "isRead", + "isReadReceiptRequested", + "lastModifiedDateTime", + "parentFolderId", + "receivedDateTime", + "replyTo", + "sender", + "sentDateTime", + "subject", + "toRecipients", + "uniqueBody", + "webLink", + "internetMessageId" +] diff --git a/office365_get_email.html b/office365_get_email.html index e018b60..427eb28 100644 --- a/office365_get_email.html +++ b/office365_get_email.html @@ -10,7 +10,7 @@ {% block widget_content %} + + + + +
+ + + {% for result in results %} + {% if not result.data %} +

No data found

+ {% else %} +
+

Action Parameters

+ + + + + + + + + +
User ID + {{ result.param.user_id }} +   + +
Rule ID + {{ result.param.rule_id}} +   + +
+
+ +
+

Data

+ + + + + + + {% for data in result.data %} + + + + {% endfor %} +
RULE DISPLAY NAMERULE ACTIONSRULE CONDITIONS
{{ data.displayName }} + {% for key, value in data.items %} + {% if 'action' in key %} + + + + + {% endif %} + {% endfor %} +
{{ key }}{{ value }}
+
+ {% for key, value in data.items %} + {% if 'condition' in key %} + + + + + {% endif %} + {% endfor %} +
{{ key }}{{ value }}
+
+
+ {% endif %} + {% endfor %} +
+ + +{% endblock %} diff --git a/office365_list_events.html b/office365_list_events.html index 4e067f9..0ebd739 100644 --- a/office365_list_events.html +++ b/office365_list_events.html @@ -10,7 +10,7 @@ {% block widget_content %} + + + + +
+ + + {% for result in results %} + {% if not result.data %} +

No data found

+ {% else %} +
+

Rules List

+ + + + + + + + {% for data in result.data %} + + + + {% if data.actions.delete %} + + {% else %} + + {% endif %} + + + {% endfor %} +
RULE IDRULE NAMEDELETE EMAIL ENABLEDACTION
+ + {{ data.id }} +   + + + + {{ data.displayName }} + + {{ data.actions.delete }} + + None + + {{ data.actions }} +
+
+ {% endif %} + {% endfor %} +
+ +{% endblock %} diff --git a/office365_run_query.html b/office365_run_query.html index e14db19..3a4e254 100644 --- a/office365_run_query.html +++ b/office365_run_query.html @@ -10,7 +10,7 @@ {% block widget_content %}