Working with Services
- Working with Services
- Get Calendars
- Get Calendar Events
- Initial Synchronization
- Using SyncState for Subsequent Runs
- Event Processing
- Error Ignore Mode
- Using the Microsoft Exchange Package
- Send email
- Send request
- Running a Script via GraphQL Request
- Execute Code
- Running a Script with JS Code
- Getting a File from Jira
Use the following blocks to work with various services:
Get Calendars
Use this block to retrieve the list of employee calendars.
- To use this block, configure a connection to Microsoft Exchange. This provides access to the Microsoft Exchange Server and allows retrieving calendar data for reporting and event analysis.
- Two connection options are available:
- Using Microsoft — suitable for accessing Microsoft 365 calendars through user and application accounts configured in the organization
- Username and password — manual configuration for connecting to Exchange Server. You must provide the server URL, login, password, and upload a root certificate (if the server URL uses HTTPS)
- In the connection settings, you can enable impersonation mode so that calendar and event data is retrieved on behalf of the user whose email address is specified in the block parameters.
In the block parameters, enter the user’s email address manually or via mapping in the Domain/username field.
After execution, the block returns a list of the user’s calendars, which can be used in the Get Calendar Events block.
The block returns the following fields:
| Field | Description |
|---|---|
address | Address |
display_name | Calendar display name |
routing_type | Routing type of the address used to access the user’s mailbox |
unique_id | Unique calendar identifier |
Get Calendar Events
This block retrieves a list of events from a calendar obtained with the Get Calendars block.
Parameters of the block:
- Calendar identifier (mandatory field, filled in manually or with the help of mapping)
- Email address
- Event collection start date
If the Event collection start date field is:
- Filled with a timestamp in milliseconds, only events starting from that date are displayed. The date value is based on the event start time. In this case, non-recurring events appear as usual, while recurring events are broken down into individual meetings. Canceled events are not displayed
- Filled with a SyncState value, the output includes all recurring, non-recurring, and canceled events created or updated since the last script run. SyncState is unique to each event and refers to the last modification date. You do not need to manually merge new and old data — using SyncState ensures automatic event synchronization
Detailed instructions for initial synchronization and SyncState usage are provided below.
The block outputs event data from the specified calendar. Based on the retrieved data, you can build tables and workflows.
The block returns the following fields:
| Field | Description |
|---|---|
busy | Indicates the busy status for the time slot associated with the calendar event, helping the system and users determine availability |
categories | Collection of custom categories assigned to the event, represented as strings |
end | Meeting end time |
i_cal_uid | Global unique calendar identifier |
id_meeting | Meeting ID |
is_all_day_event | Indicates if the event lasts all day |
is_cancelled | Indicates if the meeting was canceled |
is_meeting | Indicates if the event is a meeting |
is_recurring | Indicates if the event is recurring |
last_modified_name | Name of the user who last modified the item |
last_modified_time | Date and time of the last modification |
location | Meeting location |
mailbox_type | Represents the mailbox type of the email address |
meeting_time_zone | Name of the time zone where the meeting is scheduled |
moment_data_processing | The moment when Operavix retrieved the data |
optional_attendees | Collection of optional attendees with fields: name, last_response_time, mailbox_type, address, routing_type |
organizer_address | Organizer’s email address |
organizer_name | Organizer’s name |
request_was_sent | Indicates whether a meeting request was sent |
required_attendees | Collection of required attendees with fields: name, last_response_time, mailbox_type, address, routing_type |
response | Indicates the recipient’s response to the invitation |
routing_type | Mailbox routing type |
start | Meeting start time |
subject | Event subject |
sync_state | Timestamp for event synchronization |
Initial Synchronization
Initial synchronization occurs the first time the Get Calendar Events block runs, when no SyncState is yet available:
- In the Start date for event collection field, specify the start date in Unix time (milliseconds). Example:
1609459200000(January 1, 2021). The system will retrieve all events from this date until the request execution moment. This step initializes SyncState, which is used for further synchronization. Choosing a short range (e.g., one day) minimizes load during initial sync. - After a successful request, the system returns a SyncState value — a unique synchronization state ID that can be stored in a separate table. Save the calendar ID (
unique_id), event ID (id_meeting), and the corresponding SyncState.
Using SyncState for Subsequent Runs
SyncState is a timestamp automatically generated by Microsoft Exchange when querying a calendar. It ensures only new or updated events since the last sync are retrieved.
For subsequent script runs, insert SyncState into the Start date for event collection field.
- If SyncState is found, only new or updated events since the recorded time are returned
- If no SyncState is found, the block execution for that calendar stops, and the script proceeds to the next one. If no SyncState values are stored for any calendars, the script stops entirely
SyncState updates only after successful processing of all calendars.
If an error occurs during synchronization, the new SyncState is not generated, and the previous one is reused, ensuring no data is missed.
If error ignore mode is enabled, the block continues execution even if some calendars fail. In this case:
- Successfully processed calendars update their events and SyncState
- Calendars with errors retain the previous SyncState, and error details are logged
During the next run, calendars with errors will be retried.
Benefits of using SyncState:
- Processes only new or updated events, reducing system load
- Excludes unchanged events, avoiding duplicates
- Ensures continuous and up-to-date event collection without manual tracking
Event Processing
When using a timestamp in milliseconds:
- Non-recurring events are returned as usual, starting from the specified date
- Recurring events are broken into separate instances for detailed analysis
- Canceled events are excluded from the output
When using SyncState:
- If a meeting has not changed (i.e., its
last_modified_timeremains the same) since the previous export, it will not be included in the response when the SyncState parameter is used. This prevents reprocessing of unchanged events. The SyncState value itself remains unchanged - If changes occurred in a recurring event between exports (e.g., meeting details were updated), the response will include the updated data for that event
- If multiple changes occurred to a meeting between exports, only the event with the latest
last_modified_timewill be returned in the output. Intermediate changes do not result in multiple exports—only the final state of the event is considered
Error Ignore Mode
The Get calendar events block can operate in error-ignoring mode, which allows the script to continue executing even if individual calendars trigger errors. If an error is not included in the list of retryable or ignorable errors, the calendar where the error occurred will be skipped. This information is recorded in the automation agent logs and can be analyzed later. All other calendars continue to be processed normally.
Enable/disable error ignore mode in com.operavix.subsystem.automation.json via the parameter exchange_ignore_exceptions:
true— error ignore mode enabledfalse— error ignore mode disabled (default)
After changing the configuration, restart the central server.
If an error occurs repeatedly, it is recommended to run the script in error-ignoring mode. The automation agent logs will record the errors along with the identifiers of the calendars where they occurred. This information can be used for detailed analysis. After resolving the root cause of the error, it is recommended to disable error-ignoring mode and restart the central server to return to standard operation mode.
Example log entry:
2025-04-07 12:48:50.885+0300 [00000002] [X] DEBUG c.i.s.a.b.e.e.g.AppointmentIteratorItem:64 - Exchange ignoreExceptions mode enabled. All records skipped for id:AAMkAGQ4ZGFlMTU1LWYxYzEtNGQ4Ni1iMDFjLTNmZjAxMTk2YzI4ZgAuAAAAAADfJqMIbKSgS5+alO5Y+noFAQCU/9Lman9lR5EXIo0RRpHGAAAAAAENAAA=
com.operavix.platform.exception.PlatformException: The folder to be synchronized could not be found
Explanation:
id— skipped calendar IDPlatformException— error that caused the calendar to be skipped
Using the Microsoft Exchange Package
To retrieve a list of calendars and store them in a database, build the following script:
- Use the Scheduler block as the trigger and configure the schedule for fetching the list of calendars and their events.
- Configure the Select rows by SQL query block for the target database to retrieve the list of user email addresses (logins) whose calendars need to be fetched.
- Set up the Get calendars block. In the User's email address field, use mapping to insert the column containing the user email addresses obtained from the previous Select rows by SQL query block.
- To retrieve calendar events, configure the Get calendar events block. In the Calendar ID field, use mapping to insert the
unique_idtag. If you need to fetch events for a specific calendar only, enter the ID manually: go to the output data of the previous block and copy theunique_idvalue of the desired calendar. For the initial event collection, fill in the Event collection start date field with a timestamp in milliseconds. - To store the updated SyncState values (obtained in the previous step) in the database, add an Insert rows block from the appropriate package. In the Table field, select the target table. If you need to add a new column, click Add column.
- Test the entire script by clicking Run test in the top right corner. If the test succeeds, publish and activate the script.
Send email
Use this block to Send emails to a specified email address.
Parameters:
- Connection — choose existing or add new
- Recipient address
- Letter subject
- Message — format Text or HTML
- Attachment
- Copy
- Hidden copy
All block parameters except connection can be mapped.
Emails can be sent either using the SMTP connection configured or via the System mail package by selecting the Send email block.
For standalone setups, configure the outgoing mail server for the System mail package.
Block specifics:
- The block can use values only from one source block. If values from multiple sources are mapped, an error occurs
- Another block must precede it. The number of emails sent depends on the number of records returned by the previous block. For example, if 5 records are returned, 5 emails will be sent
- Multiple recipients can be specified in the Recipient address field, separated by commas
Example:
- Add the Send email block to the script and enter the recipient's address. For multiple recipients, list them separated by commas. Fill in other fields and click Test.
- After the test, the email is sent to the specified addresses.
Send request
Use this block to send an HTTP request to a specified address.
Parameters:
- Connection — choose existing or add new
- URL
- Method — GET, POST
- Headers — key-value pairs
- Request body — for POST
- Batch processing — for POST, enables faster sending of multiple data packets
The method is selected from the dropdown list. All other parameters can be entered manually or mapped.
Output is always returned in JSON format.
If authentication is required:
- Go to the Connection tab.
- Click + New connection and fill in:
- Name
- Username
- Password
- Click Create.
Connections can also be configured in the Control Panel.
This block only supports basic HTTP authentication.
Example:
- Enter the URL, remove headers, and click Run test to test the block.
- When the test is completed, you get the output data in the Test tab.
Running a Script via GraphQL Request
- Retrieve the script GUID and workspace ID with this query in GraphiQL:
You can also obtain the workspace ID from the workspace system table if you have the System Tables privilege enabled.
query{ automation{ script{ script_general(id: <script_id>){ id guid workspace{ id } } } } } - In the Send request block, enter your GraphQL server URL with the API key: https://{server_address}/graphql?api_key=key.
- Select the POST method.
- In the Body field, enter:
{"query":"mutation{ automation{ script{ execute_by_guid(guid:\"<obtained_script_GUID>\", workspace_id:<obtained_workspace_id>){ guid } } } }"} - Click Run test.
- When the test is complete, you get the output data in the Test tab.
Execute Code
This block processes data using JavaScript.
Use this block to:
- Perform multiple/related HTTP requests
- Upload/download files using HTTP requests
- Perform mathematical operations on variables
- Parse JSON strings and filter values
To execute an action, enter the JS code in the JavaScript field in the block parameters. You can use mapping to insert variables into the code.
The block can contain z-method for hashing and error handling. The following methods can be used for execution in the JS environment:
z.base64Encode()— performs base64 encoding of the input string. Example:const auth = z.base64Encode(login + ':' + password);z.base64Decode()— performs base64 decoding of the input string. Example:const originalText = z.base64Decode(encodedText);z.request()— performs an HTTP request. Expects an object with the request configuration as input. Parameters:url— address to which the request will be sentmethod— defaults to GET. Possible values: GET, POST, DELETE, PUTheaders— list of HTTP request headersjsonBody/multipartBody— request body. Required for POST and PUT methodstimeout— individual server response timeout in milliseconds
Running a Script with JS Code
- Enter the code in the JavaScript field:
const apiKey = 'key'; const scriptGuid = 'script_GUID'; const workspaceId = 1; var resp1 = z.request({ url: 'https://server_address/graphql?api_key=' + apiKey, method: 'POST', jsonBody: '{"query":"mutation{automation{script{execute_by_guid(guid:\\"' + scriptGuid + '\\", workspace_id:' + workspaceId + '){guid}}}}"}' }); const app = { output: () => ({ resp_1_body: JSON.stringify(resp1.response), resp_1_header: JSON.stringify(resp1.headers), resp_1_status: resp1.status, ["var-with-hard-name-1"]: resp1.headers.date, ["var-with-hard-name-2"]: resp1.headers["cache-control"], content_type: resp1.headers["content-type"], content_length: resp1.headers["content-length"] } ) } - Click Run test.
- When the test is complete, you can see the output data in the Test tab.
Getting a File from Jira
- Enter the code in the JavaScript field:
const login = 'login';
const password = 'password';
const auth = z.base64Encode(login + ':' + password);
var resp1 = z.request({
url: 'https://jira.office.operavix.com/secure/attachment/76158/Screenshot_1.jpg',
method: 'GET',
headers: {
Authorization: 'Basic ' + auth
}
});
const app = {
output: () => ({
resp_1_body: JSON.stringify(resp1.response),
resp_1_header: JSON.stringify(resp1.headers),
resp_1_status: resp1.status,
file_content: resp1.response,
["var-with-hard-name-1"]: resp1.headers.date,
["var-with-hard-name-2"]: resp1.headers["cache-control"],
content_type: resp1.headers["content-type"],
content_length: resp1.headers["content-length"]
}
)
}
- Click Run test.
- When the test is complete, you can see the output data in the Test tab.
Was the article helpful?