MS Office
Overview
The io.Connect Teams Adapter offers several approaches for utilizing and customizing its functionalities:
The Service App configuration enables you to define rules that determine the response behavior of the Teams Adapter to specific events (e.g., receiving a chat message). Each rule accepts a list of actions to execute in the specified order as a response to the event. Different types of actions are available: invoking Interop methods, raising Intents, updating a shared context, publishing to a Channel, raising a notification, and more. You can also specify any of the default functionalities provided by the Teams Adapter to be invoked as Interop methods or raised as Intents.
The default Teams UI actions provided by the Platform App can be modified or removed. It's possible to create your own custom actions by using the Platform App configuration and define their behavior via the corresponding rule in the Service App configuration. You can also specify any of the default functionalities provided by the Teams Adapter to be invoked as Interop methods or raised as Intents when the user initiates a Platform App action from the Teams UI.
The default functionalities provided by the Teams Adapter can be used directly by your interop-enabled apps as Interop methods and Intents.
Service App Rules
The "rules"
object in the Service App configuration enables you to define rules that will determine the behavior of the Teams Adapter in response to various events from Teams, such as receiving a message, or when the user invokes a Platform App action from the Teams UI.
⚠️ Note that there are certain expected subscription latencies when receiving change notifications from the Microsoft Graph API. This may affect the time it takes for the Teams Adapter to respond to the respective Teams event. For more details, see the latency guide in the official Microsoft Graph API documentation.
To define the behavior of the Teams Adapter when a message is received, use the "onMessage"
rule.
To define the behavior of the Teams Adapter when the user invokes a Platform App action from the Teams UI, use the "onSyncMessage"
, "onSyncConversation"
, "onRecordingStart"
, and "onRecording"
rules.
Each object in the rule array has the following properties:
Property | Type | Description |
---|---|---|
"actions" |
object[] |
List objects describing actions to be executed in the specified order if all filters specified in the "filter" property of the current object are matched. |
"stopProcessing" |
boolean |
If true , the Service App will stop processing the message if all filters specified in the "filter" property of the current object are matched, and the rest of the objects in the rule array won't be taken into account. This is useful if you have multiple objects in the rule array with different filters and you want the Service App to stop processing the message if a certain filter is matched. Defaults to false . |
"filter" |
object |
Use to specify filters that will be matched against the message. If all specified filters match, the Service App will execute the actions defined in the "actions" array and will take into consideration the value of the "stopProcessing" property. Otherwise, the Service App will continue to the next object in the rule array. |
The Service App extracts from the processed message variables containing message data (such as current user ID, message sender ID, message importance, mentions, reactions, and more). These variables can be used in the definitions of actions in the rule object to provide message data dynamically.
The following is an example configuration for the "onMessage"
rule. The rule will be activated when a message is received and the user reacts with a "like" to a it. The message text will be processed with a regular expression and the extracted variables (both from the message and from the regular expression matches in the "text"
filter) will be used as values in the object that will be passed as an argument for the custom Interop method defined in the "actions"
array. If the filter is matched, the Service App will stop processing any other objects in the "onMessage"
rule array:
{
"webService": {
"resource": ["/me/chats/getAllMessages"]
},
"rules": {
"onMessage": [
{
// If the message matches all defined filters, the Service App will stop processing it
// and won't take into consideration any other objects in the `"onMessage"` array.
"stopProcessing": true,
// Defining message filters.
"filter": {
// Regular expression with numbered capturing groups that can be used as extracted variables.
"text": "Contact (.*) regarding their (.*). Their email is (.*).",
"reactions": [
{
"type": "like",
"from": "$me"
}
]
},
// Actions to be executed if the message matches all filters.
"actions": [
{
"type": "method",
"name": "MyCustomInteropMethod",
"arguments": {
// Using extracted variables (including numbered capturing groups)
// as arguments for the Interop method invocation.
"from": "$fromName",
"contactName": "$1",
"topic": "$2",
"contactEmail": "$3"
}
}
]
}
]
}
}
The following sections describe the variables extracted by the Service App, the available filters, and the types of actions you can define.
Extracted Variables
The Service Apps extracts from the processed message variables containing message data (such as current user ID, message sender ID, message importance, mentions, reactions, and more). Some variables are extracted for all rules, and others are extracted only for specific rules. You can use these variables in the definitions of actions in the rule object to provide message data dynamically. Each variable is in the format $<variable-name>
- e.g., $chatName
.
The following variables are extracted for all rules (some exceptions are noted in the variable descriptions):
Variable | Type | Description |
---|---|---|
$chatId |
string |
Teams chat ID. |
$chatMembers |
object[] |
List of object describing Teams chat members as received from the Microsoft Graph API. Currently, not supported for Teams channels. If you want to use this variable, you must set the "requestChatMembers" property in the Service App configuration to true . |
$chatName |
string |
Teams chat name. If you want to use this variable, you must set the "requestChatName" property in the Service App configuration to true . |
$commandId |
string |
ID of a Platform App command. Not extracted for the "onMessage" rule. Valid only for the rules used for defining the behavior of Platform App actions. |
$myEmail |
string |
Email of the current Teams user |
$myId |
string |
ID of the current Teams user. |
$myName |
string |
Name of the current Teams user. |
$teamName |
string | null |
Team name. |
$time |
string |
Timestamp of the processed rule in "yyyy/mm/dd hh:mm" format. |
$timeISO |
string |
Timestamp of the processed rule in ISO format. |
$timeJS |
number |
Timestamp of the processed rule in milliseconds since Unix epoch. |
The following variables are extracted for the "onMessage"
and "onSyncMessage"
rules:
Variable | Type | Description |
---|---|---|
$<match-index> |
string | null |
The "text" filter accepts a regular expression as a value. Each capturing group in the expression can be used as an extracted variable (e.g., the $1 variable will hold the value of the first capturing group from the left and so on) in the actions defined in the same rule object. |
$color |
string | null |
Holds the name of a Teams color reaction to a message only if the reaction is one of the following: 🟥, 🟧, 🟨, 🟩, 🟦, 🟪, ⬛, ⬜. The respective string values are the following: "Red" , "Orange" , "Yellow" , "Green" , "Blue" , "Purple" , "Black" , or null . If the Teams Adapter is currently joined to an io.Connect Channel and no user has reacted to a message with on of the color reactions listed here, then this variable will hold a string value representing the current io.Connect Channel. In either case, you can use this variable in an action for a rule to specify the name of the io.Connect Channel to which to publish the message data of interest to you. |
$colorString |
string |
Same as $color , but the value will always be a string (null for the white square reaction will be an empty string). |
$createdDateTime |
string |
Timestamp of when the message was created. |
$fromId |
string |
ID of the message sender. |
$fromName |
string |
Name of the message sender. |
$importance |
string |
Message importance. Can be one of "normal" , "high" or "urgent" . |
$mentions |
object[] |
List of mentioned entities in the message. |
$messageId |
string |
Message ID. |
$reactions |
object[] |
List of reactions to the message. |
$text |
string | null |
Message text. |
The following variables are extracted for the "onRecording"
rule:
Variable | Type | Description |
---|---|---|
$textEntries |
object[] |
List of message entries. |
$textHtml |
string |
Message text in HTML format. |
$textPlain |
string |
Message text in plaintext format. |
The following variables are extracted for the "onSyncConversation"
rule:
Variable | Type | Description |
---|---|---|
$conversationType |
"personal" | "groupChat" | "channel" |
Type of the conversation. |
$time |
string |
Overrides the value of the $time variable extracted for all rules (current time when the rule is processed) with a timestamp from the local user machine. |
Filters
The "filter"
property in the rule object enables you to specify filters against which the Service App will match all messages. The message will be processed and the actions defined in the "actions"
array of each rule object will be processed only if the message matches all filters.
You can define multiple rule objects with different filter criteria and use the "stopProcessing"
property in the rule object to instruct the Service App to stop processing the message further and ignore the rest of the objects in the rule array if all filters in the current object are matched.
All filters (or their properties if the filter is an object or an array of objects) except "text"
accept as a value a regular expression string as a value. The expression must be in the #<flag>#<expression>
format where <flag>
represents any valid flag for a regular expression in JavaScript, and <expression>
represents a valid JavaScript regular expression. You can provide an expression without a flag in the #<expression>
format. You can also provide a string literal that will be matched against the respective message data.
The "text"
filter accepts as a value a valid JavaScript regular expression string without flags.
For all filter properties that accepts as values a user ID, name, or email, you can use $me
to denote the current Teams user ID, name, or email.
The following example demonstrates using regular expressions for the "text"
and the "chatMembers"
filters:
{
"rules": {
"onMessage": [
{
"filter": {
// Regular expression with numbered capturing groups that can be used as extracted variables.
"text": "Contact (.*) regarding their (.*). Their email is (.*).",
"chatMembers": [
{
// Case-insensitive regular expression that will match all members whose names start with "j".
"displayName": "#i#^j"
},
{
"userId": "$me"
}
]
}
}
]
}
}
The following sections describe the available filters:
Chat ID
To filter messages based on the chat ID, use the "chatId"
property of the "filter"
object. It accepts as a value a chat ID, a regular expression, or an array of chat IDs and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted chat ID. The "chatId"
filter is valid for all rules.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"chatId": "#^7"
}
},
{
"filter": {
"chatId": ["#^42", "19:253f5895-9a62-4362-8d38-43f0205c702c"]
}
}
]
}
}
Chat Name
To filter messages based on the chat name, use the "chatName"
property of the "filter"
object. It accepts as a value a chat name, a regular expression, or an array of chat names and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted chat name. The "chatName"
filter is valid for all rules.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"chatName": "My Chat"
}
},
{
"filter": {
"chatName": ["#i#^trade", "Breaking News"]
}
}
]
}
}
Chat Members
To filter messages based on the participating chat members, use the "chatMembers"
property of the "filter"
object. It accepts as a value an array of objects, each with the following optional properties:
Property | Type | Description |
---|---|---|
"displayName" |
string |
The chat member name or a regular expression. |
"email" |
string |
The chat member email or a regular expression. |
"userId" |
string |
The Teams user ID or a regular expression. |
The filter will pass only if all specified users are members of the targeted chat. The "chatMembers"
filter is valid for all rules.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"chatMembers": [
{
"displayName": "John Doe"
},
{
"displayName": "#i#^j",
"email": "#my-org"
},
{
"userId": "$me"
}
]
}
}
]
}
}
Text
⚠️ Note that this filter is valid for the
"onMessage"
,"onSyncMessage"
,"onRecordingStart"
, and"onRecording"
rules.
To filter messages based on their text, use the "text"
property of the "filter"
object. It accepts as a value a valid JavaScript regular expression without flags. Each numbered capturing group in the regular expression can be used as an extracted variable in the actions defined in the same rule object.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"text": "Contact (.*) regarding their (.*). Their email is (.*)."
}
}
]
}
}
From ID
⚠️ Note that this filter is valid for the
"onMessage"
and"onSyncMessage"
rules.
To filter messages based on the sender ID, use the "fromId"
property of the "filter"
object. It accepts as a value a user ID, a regular expression, or an array of user IDs and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted user ID.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"fromId": "#^7"
}
},
{
"filter": {
"fromId": ["#^42", "74562e847-7356-5893-3367-d39d943a4fb6", "$me"]
}
}
]
}
}
From Name
⚠️ Note that this filter is valid for the
"onMessage"
and"onSyncMessage"
rules.
To filter messages based on the sender name, use the "fromName"
property of the "filter"
object. It accepts as a value a user display name, a regular expression, or an array of user display names and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted user display name.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"fromName": "John Doe"
}
},
{
"filter": {
"fromName": ["#i#^john", "Jane Doe", "$me"]
}
}
]
}
}
Importance
⚠️ Note that this filter is valid for the
"onMessage"
and"onSyncMessage"
rules.
To filter messages based on their importance, use the "importance"
property of the "filter"
object. It accepts as a value a string representing the message importance (one of "normal"
, "high"
, or "urgent"
), a regular expression, or an array of strings representing the message importance and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted user display name.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"importance": "high"
}
},
{
"filter": {
"importance": ["#^u", "normal"]
}
}
]
}
}
Reactions
⚠️ Note that this filter is valid for the
"onMessage"
and"onSyncMessage"
rules.
To filter messages based on user reactions, use the "reactions"
property of the "filter"
object. It accepts as a value an array of objects, each with the following properties:
Property | Type | Description |
---|---|---|
"color" |
boolean |
If true , the filter will match if a user reacts with one of the following reactions: 🟥, 🟧, 🟨, 🟩, 🟦, 🟪, ⬛, ⬜. In this case, the $color extracted variable will hold the name of the color reaction as a string (null for the white square reaction). The $colorString extracted variable will hold the name of the color reaction as a string (empty string for the white square reaction). |
"from" |
string |
ID of the user that reacted to the message. Accepts as a value only a specific user ID or "*" which will match a reaction from any user. If not specified, defaults to "$me" . |
"type" |
string |
Type of the reaction, such as "like" , "heart" , emoji Unicode character. |
It's required to specify either "type"
or "color"
. The filter will pass if the message includes all specified reactions.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"reactions": [
{
"from": "*",
"type": "like"
}
]
}
},
{
"filter": {
"reactions": [
{
"from": "74562e847-7356-5893-3367-d39d943a4fb6",
"color": true
}
]
}
}
]
}
}
Mentions
⚠️ Note that this filter is valid for the
"onMessage"
and"onSyncMessage"
rules.
To filter messages based on the mentions in a message, use the "mentions"
property of the "filter"
object. It accepts as a value a string representing the mention, a regular expression, or an array of strings representing the message mentions and regular expressions. If an array is provided, the filter will pass only if all provided values match the targeted mentions.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"mentions": "John Doe"
}
},
{
"filter": {
"mentions": ["#i#^v", "#Jane"]
}
}
]
}
}
Command ID
⚠️ Note that this filter is valid for the
"onSyncMessage"
,"onSyncConversation"
,"onRecordingStart"
, and"onRecording"
rules.
To filter messages based on the command ID for a Platform App action, use the "commandId"
property of the "filter"
object. It accepts as a value the command ID, a regular expression, or an array of command IDs and regular expressions. If an array is provided, the filter will pass if any of the provided values matches the targeted command ID.
Example configuration:
{
"rules": {
"onMessage": [
{
"filter": {
"commandId": "stopRecording"
}
},
{
"filter": {
"commandId": ["#i#sync", "startRecording"]
}
}
]
}
}
Actions
The "actions"
property in the rule object enables you to specify one or more actions to be executed if the processed message matches all specified filters in the current rule object. The shape of the action object depends on the type of action you want to execute. You can use extracted variables to pass dynamically message data to the action.
The following types of actions are available:
- Interop Methods;
- Interop Streams;
- Intents;
- Shared Contexts;
- Channels;
- Notifications;
- Evaluating Code;
- Interactive Cards;
The following sections describe the available actions.
Interop Methods
This type of action allows you to invoke an Interop method.
The object for defining an action that invokes an Interop method has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
object |
Arguments for the Interop method invocation. |
"name" |
string |
Required. Name of the Interop method to invoke. |
"options" |
object |
Accepts as a value an InvokeOptions object describing the options for the method invocation. |
"target" |
"best" | "all" | "skipMine" | object | object[] |
Determines which Interop servers offering the specified Interop method to target. To target the first server that has registered the Interop method, use "best" . To target all servers offering the method, use "all" . To prevent invoking the method on the current server (in this case, the Teams Adapter), use "skipMine" . You can also provide an object or an array of objects of type Instance describing the targeted Interop servers. |
"type" |
string |
Required. Type of the action to execute. Must be set to "method" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "method",
"name": "MyInteropMethod",
"arguments": {
"contactName": "$fromName",
"message": "$text"
}
}
]
}
]
}
}
Interop Streams
This type of action allows you to create or subscribe to Interop streams.
The object for defining an action that creates an Interop stream or subscribes for one has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
object[] |
Required. Use the array to provide the necessary arguments for creating or subscribing to an Interop stream. The order and shape of the arguments in the array must correspond to the signatures of the createStream() or subscribe() methods of the Interop API respectively. Keep in mind that it isn't possible to provide callbacks as arguments via the JSON configuration. |
"name" |
string |
Required. Name of the Interop stream to which to publish the data. |
"type" |
string |
Required. Type of the action to execute. Must be set to "method" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "method",
"name": "MyInteropStream",
"arguments": {
"contactName": "$fromName",
"message": "$text"
}
}
]
}
]
}
}
Intents
This type of action allows you to raise an Intent.
The object for defining an action that raises an Intent has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
object |
Required. Accepts as a value an IntentRequest object describing the Intent to raise. |
"method" |
string |
Required. Name of the Intents API method to invoke. Must be set to "raise" . |
"type" |
string |
Required. Type of the action to execute. Must be set to "intents" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "intents",
"method": "raise",
"arguments": {
"intent": "MyIntent",
"context": {
"data": {
"contact": "$fromName"
}
}
}
}
]
}
]
}
}
Shared Contexts
This type of action allows you to invoke any of the methods available in the Shared Contexts API by their name.
⚠️ Note that while you'll be able to invoke all available API methods, if the method requires you to pass a callback in addition to the arguments for the method invocation (as is the case with event handling methods), you won't be able to provide one via the JSON configuration.
The object for defining an action that invokes a method of the Shared Contexts API has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
(string | object)[] |
Arguments for the method invocation (e.g., for updating a Shared Context, you must pass an array containing the context name and a data object with which the update the context). |
"method" |
string |
Required. Name of the Shared Contexts API method to invoke (e.g., to invoke the update() method of the Shared Contexts API, you must set this to "update" ). |
"type" |
string |
Required. Type of the action to execute. Must be set to "contexts" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "contexts",
"method": "update",
"arguments": ["MyContext", { "contact": "$fromName" }]
}
]
}
]
}
}
Channels
This type of action allows you to invoke any of the methods available in the Channels API by their name.
⚠️ Note that while you'll be able to invoke all available API methods, if the method requires you to pass a callback in addition to the arguments for the method invocation (as is the case with event handling methods), you won't be able to provide one via the JSON configuration.
The object for defining an action that invokes a method of the Channels API has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
(string | object)[] |
Arguments for the method invocation (e.g., for publishing to a specific Channel, you must pass an array containing a data object with which to update the Channel and the Channel name). |
"method" |
string |
Required. Name of the Channels API method to invoke (e.g., to invoke the publish() method of the Channels API, you must set this to "publish" ). |
"type" |
string |
Required. Type of the action to execute. Must be set to "channels" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "channels",
"method": "publish",
"arguments": [{ "contact": "$fromName" }, "Red"]
}
]
}
]
}
}
Layouts
This type of action allows you to invoke any of the methods available in the Layouts API by their name.
⚠️ Note that while you'll be able to invoke all available API methods, if the method requires you to pass a callback in addition to the arguments for the method invocation (as is the case with event handling methods), you won't be able to provide one via the JSON configuration.
The object for defining an action that invokes a method of the Layouts API has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
(string | object)[] |
Arguments for the method invocation (e.g., for restoring a Layout, you must pass an array containing a RestoreOptions ). |
"method" |
string |
Required. Name of the Layouts API method to invoke (e.g., to invoke the restore() method of the Layouts API, you must set this to "restore" ). |
"type" |
string |
Required. Type of the action to execute. Must be set to "layouts" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "layouts",
"method": "restore",
"arguments": [{ "name": "Client $fromName" }]
}
]
}
]
}
}
Notifications
This type of action allows you to raise a notification.
The object for defining an action that raises a notification has the following properties:
Property | Type | Description |
---|---|---|
"arguments" |
object |
Required. Accepts as a value an IOConnectNotificationOptions object describing the notification to raise. |
"type" |
string |
Required. Type of the action to execute. Must be set to "notification" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "notification",
"arguments": {
"title": "Trade",
"body": "$text",
"actions": [
{
"action": "openClientPortfolio",
"title": "Open Portfolio"
}
]
}
}
]
}
]
}
}
Evaluating Code
This type of action allows you to pass code as a string that will be evaluated and executed by the io.Connect framework with the initialized io.Connect API object in the scope. For io.Connect Desktop projects, this will be the initialized @interopio/desktop
library, and for io.Connect Browser projects, this will be the initialized @interopio/browser
library.
⚠️ Note that you must explicitly enable this type of action in the Service App configuration in order to be able to use it. For more details, see the Configuration > Service App > Permissions section.
The object for defining an action that evaluates code has the following properties:
Property | Type | Description |
---|---|---|
"code" |
string |
Required. Code to evaluate and execute with the initialized io.Connect API object in scope. |
"type" |
string |
Required. Type of the action to execute. Must be set to "eval" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "eval",
"code": "io.channels.publish({ contact: '$fromName'}, 'Red')"
}
]
}
]
}
}
Interactive Cards
This type of action allows you to send interactive cards in Teams chats and channels.
The object for defining an action that sends an interactive card has the following properties:
Property | Type | Description |
---|---|---|
"content" |
object |
Required. Describes the content of the interactive card. |
"destination" |
string |
Required. Specifies where to send the interactive card. Accepts as a value a Teams chat or channel ID. |
"type" |
string |
Required. Type of the action to execute. Must be set to "card" . |
Example configuration:
{
"rules": {
"onMessage": [
{
"actions": [
{
"type": "card",
"content": {
"title": "Instrument Actions",
"subtitle": "Instrument in message: AAPL (Apple Inc)",
"buttons": [
{
"type": "openUrl",
"title": "Google",
"value": "https://www.google.com/search?q=AAPL",
"tooltip": "Search in Google"
},
{
"type": "openUrl",
"title": "Yahoo",
"value": "https://finance.yahoo.com/quote/AAPL?p=AAPL&.tsrc=fin-srch",
"tooltip": "Open in Yahoo Finance"
}
]
},
"destination": "19:eb19d757f56b4e23bbb402ff38fd7821"
}
]
}
]
}
}
For details on how to send interactive cards programmatically by using the default functionalities provided by the Teams Adapter, see the Default Implementations > Chats > io.Teams.SendChatCard and Default Implementations > Channels > io.Teams.SendChannelCard sections.
Platform App Actions
The default UI actions provided by the Platform App are defined in the "commands"
array under the "composeExtensions"
top-level key of the Platform App configuration. You can customize the texts for the existing actions by using the "description"
and "title"
properties, you can remove an action, or you can define your own custom actions.
Default Actions
The following demonstrates the default configuration for the UI actions provided by the Platform App:
{
"composeExtensions": [
{
"commands": [
{
"id": "startRecording",
"context": ["message"],
"description": "Start recording chat from here",
"title": "Start chat recording ${{TEAMS_APP_CONTEXT_ACTION_SUFFIX}}",
"type": "action"
},
{
"id": "stopRecording",
"context": ["message"],
"description": "Stop recording chat up to here and send to io.Connect",
"title": "Stop chat recording ${{TEAMS_APP_CONTEXT_ACTION_SUFFIX}}",
"type": "action"
},
{
"id": "syncConversation",
"context": ["compose"],
"description": "Send current conversation to io.Connect",
"title": "Sync conversation ${{TEAMS_APP_CONTEXT_ACTION_SUFFIX}}",
"type": "action"
},
{
"id": "syncMessage",
"context": ["message"],
"description": "Send message to io.Connect",
"title": "Send to io.Connect ${{TEAMS_APP_CONTEXT_ACTION_SUFFIX}}",
"type": "action"
}
]
}
]
}
⚠️ Note that as seen in the example, you can use the environment variables specified in the
.env.<my-env>
file of your Platform App as described in the Deployment > Deployment Guide > Platform App section.
Custom Actions
To create a custom action that will be displayed in the Teams UI, you must provide a definition for it in the manifest.json
configuration file of the Platform App and configure its behavior as a rule in the the Service App configuration.
To add a custom UI action, use the "commands"
array under the "composeExtensions"
top-level key in the manifest.json
file. The value for the "id"
property must start with one of the existing action IDs - "syncMessage"
, "syncConversation"
, "startRecording"
or "stopRecording"
(e.g., the ID of your custom action may be "syncMessage-MyCustomAction"
).
⚠️ Note that the IDs of your custom actions can start with any of the default IDs. You can use the names semantically - e.g., for actions displayed in the message context menu, your IDs may start with
"syncMessage"
; for actions displayed in the message compose area, your IDs may start with"syncConversation"
. The"startRecording"
and"stopRecording"
IDs can be used for coupled actions related to chat messages - e.g., if you want to process all messages between your starting and ending actions.
Use the "context"
array to define the location of your action - the possible values are "message"
and "compose"
. If you use "message"
, the action will be displayed in the context menu of each message in Teams. If you use "compose"
, the action will be displayed among the other buttons in the compose message area of the Teams chats. The "type"
property must be set to "action"
. Use "title"
and "description"
to provide a title and description for your custom action.
The following is an example definition of a custom action that will be displayed in the message context menu:
{
"composeExtensions": [
{
"commands": [
{
"id": "syncMessage-MyCustomAction",
"context": ["message"],
"description": "My custom action.",
"title": "My Custom Action",
"type": "action"
}
]
}
]
}
Each default action ID corresponds to a rule in the Service App configuration:
Action ID | Corresponding Rule |
---|---|
"startRecording" |
"onRecordingStart" |
"stopRecording" |
"onRecording" |
"syncConversation" |
"onSyncConversation" |
"syncMessage" |
"onSyncMessage" |
To define the behavior of your custom action, use the corresponding rule in the "rules"
top-level key of the Service App configuration. Use the "commandId"
property of the "filter"
object to provide the ID of your custom action. Use the "actions"
array to define the behavior of the action.
The following example demonstrates configuring the behavior of a custom action with ID "syncMessage-MyCustomAction"
. When the action is triggered, a custom Interop method will be invoked and it will receive as arguments the message details:
// Service App configuration.
{
"rules": {
"onSyncMessage": [
{
"filter": {
"commandId": "syncMessage-MyCustomAction"
},
"actions": [
{
"type": "method",
"name": "My.Custom.Interop.Method",
"arguments": {
"id": "$fromId",
"name": "$fromName",
"email": "$fromEmail"
}
}
]
}
]
}
}
Interop Methods & Intents
The default functionalities provided by the Teams Adapter can be invoked as Interop methods or raised as Intents.
The following example demonstrates using the "io.Teams.OpenChat"
functionality as an Interop method:
const methodName = "io.Teams.OpenChat";
const args = {
chatMembers: ["john.doe@my-org.com", "jane.doe@my-org.com"],
createIfNotExists: true
};
await io.interop.invoke(methodName, args);
The following example demonstrates using the "io.Teams.OpenChat"
functionality as an Intent:
const intentRequest = {
intent: "io.Teams.OpenChat",
context: {
chatMembers: ["john.doe@my-org.com", "jane.doe@my-org.com"],
createIfNotExists: true
}
};
await io.intents.raise(intentRequest);