# Default Implementations

Source: https://docs.interop.io/adapters/ms-office/teams/default-implementations/index.html

## Overview

The io.Connect Teams Adapter provides out-of-the-box implementations for the most common use cases when working with Teams chats, channels, events, files, and more. These functionalities can be used as [Interop methods](https://docs.interop.io/desktop/capabilities/data-sharing/interop/overview/index.md) and [Intents](https://docs.interop.io/desktop/capabilities/data-sharing/intents/overview/index.md) in the following ways:

- as actions for the [rules](https://docs.interop.io/adapters/ms-office/teams/functionalities/index.md#service_app_rules) defined in the [Service App configuration](https://docs.interop.io/adapters/ms-office/teams/configuration/index.md#service_app);
- as [Teams UI actions](https://docs.interop.io/adapters/ms-office/teams/functionalities/index.md#platform_app_actions) provided by the Platform App;
- directly by your interop-enabled apps;

Each functionality can be used as an Interop method or as an Intent. For instance, you can use [`"io.Teams.OpenChat"`](#chats-ioteamsopenchat) in the configuration of the Service App both as a name of an Interop method to invoke, or as a name of an Intent to raise. No matter which approach you choose, when this functionality is triggered, a chat in Teams will be opened. This allows you to choose which interoperability concept to employ depending on your preferences or on your existing implementation strategies.

Some functionalities accept as an argument an object with one or more properties that may be necessary for the execution of the underlying operation. If you decide to use such functionality as an Interop method, you must pass this object as an argument for the method invocation. If you decide to use the functionality as an Intent, you must pass the object as context for the raised Intent. In either case, the shape of the object containing the operation arguments is the same.

The following sections describe all available functionalities. The provided examples demonstrate invoking the functionalities as Interop methods, but you can use them in any of the ways described in the [Functionalities](https://docs.interop.io/adapters/ms-office/teams/functionalities/index.md) section.

> ⚠️ *Note that the Teams Adapter uses the [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0) internally. This means that the default Interop methods and Intents registered by the Teams Adapter use as arguments and return as values objects from the Microsoft Graph API (e.g., objects describing chats, chat messages, channels, and other resources). You can find more detailed information about these objects in the official Microsoft Graph API [reference documentation](https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0).*

## General

### io.Teams.UserInfo

Returns an object containing information about the user currently logged in Teams.

The returned object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `email` | `string` | Email of the currently logged in user. |
| `id` | `string` | Teams ID of the currently logged in user. |
| `username` | `string` | Teams username of the currently logged in user. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.UserInfo";

const result = await io.interop.invoke(methodName);

console.log(result.returned);
```

### io.Teams.UpdateConfig

Updates dynamically the Service App [configuration](https://docs.interop.io/adapters/ms-office/teams/configuration/index.md).

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `customConfig` | `object` | Custom configuration with which to update the existing one. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.UpdateConfig";
const args = {
    customConfig: {
        // Provide your custom configuration.
    }
};

await io.interop.invoke(methodName, args);
```

## Chats

The following functionalities use similar patterns for identifying which chat to manipulate based on one or more of the following arguments: `chatId`, `chatMembers`, and `chatName`. The `createIfNotExists` argument is used to specify whether a new chat is to be created in case an already existing chat isn't found based on the provided arguments.

Consider the following when using methods for manipulating chats:

- Only chats in which the current user participates are considered.

- If `chatId` is specified, `chatMembers` or `chatName` must not be specified, otherwise an error will be thrown. The current user must be a member of the specified chat, otherwise an error will be thrown. If a chat isn't found, an error will be thrown and the `createIfNotExists` property will be ignored.

- If one or both of `chatMembers` and `chatName` are specified, the Teams Adapter will search for an exact match based on the provided arguments. If more than one chat matching the criteria is found, an error will be thrown. If a matching chat isn't found, a new one will be created if `createIfNotExists` is set to `true` and `chatMembers` is provided. If `createIfNotExists` is set to `false` or the provided properties are invalid (e.g. `chatName` is rejected or `chatMembers` is missing or invalid), an error will be thrown.

- If none of `chatId`, `chatMembers`, or `chatName` is specified, an error will be thrown.

- If `chatMembers` is an empty array or contains only the current user, an error will be thrown.

If you need a more complex logic for finding a chat (such as matching the chat name based on a pattern, checking the chat type, selecting one of several chats with the same set of users without knowing their names), use [`"io.Teams.SearchChats"`](#search-ioteamssearchchats) to filter the list of chats and then use the retrieved chat ID as a value for the `chatId` property.

### io.Teams.OpenChat

**Required permissions**:

- `"Chat.Read"`
- `"Chat.ReadBasic"`
- `"Chat.ReadWrite"`
- `"ChatMessage.Read"`

Opens a chat in which the current user participates or optionally creates one if it doesn't exist. Returns information about the [chat](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0) in the following format:

```javascript
{
    chat: {
        // Chat details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. This means that if a user specified in this list isn't already part of the found chat, they will be automatically added to it. |
| `chatName` | `string` | Teams chat name. |
| `createIfNotExists` | `boolean` | If `true`, will create a new chat in case an already existing chat isn't found based on the provided arguments. |
| `directDl` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. |
| `directMode` | `boolean` | If `true`, the specified Teams protocol handler will be used for retrieving the desired chat instead of using the Microsoft Graph API. Defaults to `false`. |
| `directModeMessage` | `string` | Pre-populated message. Can be used when `directMode` is set to `true`. |
| `enableMobilePage` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `true`. |
| `focusMessageId` | `string` | ID of a chat message to focus. |
| `fqdn` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `teams.microsoft.com`. |
| `launchAgent` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `"join_launcher"`. |
| `msLaunch` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `true`.  |
| `protocol` | `"ms-teams" \| "msteams"` | Teams protocol handler to use. This protocol handler is automatically registered when the Teams app is installed. Defaults to the Teams protocol handler specified in the configuration of the Service App under the `"defaultTeamsProtocol"` property. |
| `type` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `"chat"`. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.OpenChat";
const args = {
    chatMembers: ["john.doe@my-org.com", "jane.doe@my-org.com"],
    createIfNotExists: true
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendChatCard

**Required permissions**:

- `"Chat.ReadWrite"`
- `"ChatMessage.Send"`

Sends an [interactive card](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/what-are-cards) to an existing chat in which the user participates or optionally creates one if it doesn't exist and sends the card in it. Returns information about the [chat](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0) and the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    chat: {
        // Chat details.
    },
    message: {
        // Message details.
    }
}
```

| Property | Type | Description |
|----------|------|-------------|
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. This means that if a user specified in this list isn't already part of the found chat, they will be automatically added to it. |
| `chatName` | `string` | Teams chat name. |
| `content` | `object` | Describes the content of the [interactive card](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/what-are-cards). |
| `createIfNotExists` | `boolean` | If `true`, will create a new chat in case an already existing chat isn't found based on the provided arguments. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendChatCard";
const args = {
    chatId: "teams-chat-id",
    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 instrument page in Yahoo Finance"
            }
        ]
    }
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendChatMessage

**Required permissions**:

- `"Chat.ReadWrite"`
- `"ChatMessage.Send"`

Sends a message to an existing chat in which the current user participates or optionally creates one if it doesn't exist and sends the message in it. Returns information about the [chat](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0) and the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    chat: {
        // Chat details.
    },
    message: {
        // Message details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `body` | `object` | Defines the message content and content type. Use this instead of `message` if you want to include mentions in the message. |
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. This means that if a user specified in this list isn't already part of the found chat, they will be automatically added to it. |
| `chatName` | `string` | Teams chat name. |
| `createIfNotExists` | `boolean` | If `true`, will create a new chat in case an already existing chat isn't found based on the provided arguments. |
| `format` | `"text" \| "html" \| "markdown"` | Text format. |
| `importance` | `"normal" \| "high" \| "urgent"` | Message importance. |
| `mentions` | `object[]` | List of objects defining mentions to include in the message. The attributes of each mention can be used in the message content specified in the `body` property. |
| `message` | `string` | Message to send. Use this if you are sending a simple message without mentions. |

The `body` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `content` | `string` | Message content. |
| `contentType` | `"text" \| "html"` | Type of the message content. Set to `"html"` when using mentions. |

Each object in the `mentions` array has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `id` | `string` | Unique ID of the mentioned resource. Can be used as a mention identifier in the message content specified in the `body` property. |
| `mentioned` | `object[]` | Describes the [mentioned resource](https://learn.microsoft.com/en-us/graph/api/resources/chatmessagementionedidentityset?view=graph-rest-1.0). |
| `mentionText` | `string` | Text for the mention specified in the `body` property. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendChatMessage";
const args = {
    chatId: "teams-chat-id",
    importance: "high",
    body: {
        // Mentioning a user in the message content.
        content: `Hi, <at id="0">${mention.mentionText}</at>!`,
        contentType: "html"
    },
    mentions: [
        // Defining a user to mention.
        {
            id: 0,
            mentionText: "John",
            mentioned: {
                user: {
                    displayName: "John Doe",
                    id: "teams-user-id",
                    userIdentityType: "aadUser"
                }
            }
        }
    ]
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendFileToChat

**Required permissions**:

- `"Chat.ReadWrite"`
- `"ChatMessage.Send"`
- `"Files.ReadWrite"`

Sends a [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) to an existing chat in which the user participates or optionally creates one if it doesn't exist and sends the the file in it. Returns information about the [chat](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0), the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0), and the sent [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) in the following format:

```javascript
{
    chat: {
        // Chat details.
    },
    message: {
        // Message details.
    },
    driveItem: {
        // File details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `allowUploadToDrive` | `boolean` | Must be set to `true` if you want to send a file that isn't in located in Microsoft OneDrive. |
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. This means that if a user specified in this list isn't already part of the found chat, they will be automatically added to it. |
| `chatName` | `string` | Teams chat name. |
| `conflictBehavior` | `"fail" \| "rename" \| "replace"` | Conflict resolution behavior in case a file with the same name already exists. Defaults to `"replace"`. |
| `createIfNotExists` | `boolean` | If `true`, will create a new chat in case an already existing chat isn't found based on the provided arguments. |
| `data` | `File \| Blob \| string` | Data to upload. Required if `url` isn't specified. |
| `dataIsBase64` | `boolean` | Must be set to `true` if the uploaded data is in Base64 format. |
| `driveItemETag` | `string` | The `eTag` of the already uploaded [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0). Required if `url` is specified. |
| `name` | `string` | Valid name for the uploaded file. |
| `parentPath` | `string` | Name of the parent directory that will contain the file. |
| `url` | `string` | The `webUrl` of the already uploaded [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0). Required if `data` isn't specified. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendFileToChat";
const args = {
    chatId: "teams-chat-id",
    url: "https://example-my.sharepoint.com/personal/file=my-uploaded-document.docx",
    name: "my-uploaded-document.docx",
    driveItemETag: "drive-item-eTag"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.PlaceChatCall

**Required permissions**:

- `"Chat.Read"`
- `"Chat.ReadBasic"`
- `"Chat.ReadWrite"`

Starts a [call](https://learn.microsoft.com/en-us/graph/api/resources/call?view=graph-rest-1.0) on the user machine with an existing chat in which the current member participates or optionally creates one if it doesn't exist and starts the call with it. Returns information about the [chat](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0) in the following format:

```javascript
{
    chat: {
        // Chat details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `callType` | `"audio" \| "video"` | Type of the [call](https://learn.microsoft.com/en-us/graph/api/resources/call?view=graph-rest-1.0) to initiate. |
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. This means that if a user specified in this list isn't already part of the found chat, they will be automatically added to it. |
| `chatName` | `string` | Teams chat name. |
| `createIfNotExists` | `boolean` | If `true`, will create a new chat in case an already existing chat isn't found based on the provided arguments. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.PlaceChatCall";
const args = {
    chatId: "teams-chat-id",
    callType: "audio"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

## Channels

The following functionalities use similar patterns for identifying which chat to manipulate based on one or more of the following arguments: `channelName`, `channelId`, `teamName`, and `groupId`.

Consider the following when using methods for manipulating chats:

- Only channels in which the current user participates are considered.

- If `channelId` is specified, `channelName`, `teamName`, or `groupId` must not be specified, otherwise an error will be thrown. The current user must be a member of the specified channel, otherwise an error will be thrown. If a channel isn't found.

- If `channelId` isn't available, `channelName` and one of `groupId` or `teamName` must be provided, otherwise an error will be thrown. The Teams Adapter will search for a matching channel and if one isn't found, an error will be thrown.

If you need a more complex logic for choosing a channel, use [`"io.Teams.SearchChannels"`](#search-ioteamssearchchannels) to filter the list of channels and then use the retrieved channel ID as a value for the `channelId` property.

### io.Teams.OpenChannel

**Required permissions**:

- `"Channel.ReadBasic.All"`
- `"ChannelMessage.Read.All"`
- `"ChannelSettings.Read.All"`
- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Opens an existing channel in which the current user participates. Returns information about the [channel](https://learn.microsoft.com/en-us/graph/api/resources/channel?view=graph-rest-1.0) in the following format:

```javascript
{
    channel: {
        // Channel details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `channelId` | `string` | Teams channel ID. If this is provided, you must not specify `channelName`, `groupId`, or `teamName`. |
| `channelName` | `string` | Teams channel name. |
| `directDl` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. |
| `directMode` | `boolean` | If `true`, the specified Teams protocol handler will be used for retrieving the desired channel instead of using the Microsoft Graph API. Defaults to `false`. |
| `directModeMessage` | `string` | Pre-populated message. Can be used when `directMode` is set to `true`. |
| `enableMobilePage` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `true`. |
| `focusMessageId` | `string` | ID of a channel message to focus. |
| `fqdn` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `teams.microsoft.com`. |
| `groupId` | `string` | Teams team group ID. |
| `launchAgent` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `"join_launcher"`. |
| `msLaunch` | `boolean` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `true`.  |
| `protocol` | `"ms-teams" \| "msteams"` | Teams protocol handler to use. This protocol handler is automatically registered when the Teams app is installed. Defaults to the Teams protocol handler specified in the configuration of the Service App under the `"defaultTeamsProtocol"` property. |
| `teamName` | `string` | Teams team name. |
| `type` | `string` | URL parameter for the Teams protocol handler. Can be used when `directMode` is set to `true`. Defaults to `"channel"`. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.OpenChannel";
const args = {
    channelId: "teams-channel-id"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendChannelCard

**Required permissions**:

- `"Channel.ReadBasic.All"`
- `"ChannelMessage.Read.All"`
- `"ChannelSettings.Read.All"`
- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Sends an [interactive card](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/what-are-cards) to an existing channel in which the user participates. Returns information about the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    message: {
        // Message details.
    }
}
```

| Property | Type | Description |
|----------|------|-------------|
| `channelId` | `string` | Teams channel ID. If this is provided, you must not specify `channelName`, `groupId`, or `teamName`. |
| `channelName` | `string` | Teams channel name. |
| `content` | `object` | Describes the content of the [interactive card](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/what-are-cards). |
| `groupId` | `string` | Teams team group ID. |
| `teamName` | `string` | Teams team name. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendChannelCard";
const args = {
    channelId: "teams-channel-id",
    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 instrument page in Yahoo Finance"
            }
        ]
    }
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendChannelMessage

**Required permissions**:

- `"Channel.ReadBasic.All"`
- `"ChannelMessage.Read.All"`
- `"ChannelSettings.Read.All"`
- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Sends a message to an existing channel in which the current user participates. Returns information about the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    message: {
        // Message details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `body` | `object` | Defines the message content and content type. Use this instead of `message` if you want to include mentions in the message. |
| `channelId` | `string` | Teams channel ID. If this is provided, you must not specify `channelName`, `groupId`, or `teamName`. |
| `channelName` | `string` | Teams channel name. |
| `format` | `"text" \| "html" \| "markdown"` | Text format. |
| `groupId` | `string` | Teams team group ID. |
| `importance` | `"normal" \| "high" \| "urgent"` | Message importance. |
| `mentions` | `object[]` | List of objects defining mentions to include in the message. The attributes of each mention can be used in the message content specified in the `body` property. |
| `message` | `string` | Message to send. Use this if you are sending a simple message without mentions. |
| `replyTo` | `string` | ID of a channel message to which to reply. |
| `teamName` | `string` | Teams team name. |

The `body` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `content` | `string` | Message content. |
| `contentType` | `"text" \| "html"` | Type of the message content. Set to `"html"` when using mentions. |

Each object in the `mentions` array has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `id` | `string` | Unique ID of the mentioned resource. Can be used as a mention identifier in the message content specified in the `body` property. |
| `mentioned` | `object[]` | Describes the [mentioned resource](https://learn.microsoft.com/en-us/graph/api/resources/chatmessagementionedidentityset?view=graph-rest-1.0). |
| `mentionText` | `string` | Text for the mention specified in the `body` property. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendChannelMessage";
const args = {
    channelId: "teams-channel-id",
    importance: "high",
    body: {
        // Mentioning a user in the message content.
        content: `Hi, <at id="0">${mention.mentionText}</at>!`,
        contentType: "html"
    },
    mentions: [
        // Defining a user to mention.
        {
            id: 0,
            mentionText: "John",
            mentioned: {
                user: {
                    displayName: "John Doe",
                    id: "teams-user-id",
                    userIdentityType: "aadUser"
                }
            }
        }
    ]
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SendFileToChannel

**Required permissions**:

- `"Channel.ReadBasic.All"`
- `"ChannelMessage.Read.All"`
- `"ChannelSettings.Read.All"`
- `"Files.ReadWrite"`
- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Sends a [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) to an existing channel in which the user participates. Returns information about the [channel](https://learn.microsoft.com/en-us/graph/api/resources/channel?view=graph-rest-1.0), the sent [message](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0), and the sent [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) in the following format:

```javascript
{
    channel: {
        // Channel details.
    },
    message: {
        // Message details.
    },
    driveItem: {
        // File details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `allowUploadToDrive` | `boolean` | Must be set to `true` if you want to send a file that isn't in located in Microsoft OneDrive. |
| `channelId` | `string` | Teams channel ID. If this is provided, you must not specify `channelName`, `groupId`, or `teamName`. |
| `channelName` | `string` | Teams channel name. |
| `conflictBehavior` | `"fail" \| "rename" \| "replace"` | Conflict resolution behavior in case a file with the same name already exists. Defaults to `"replace"`. |
| `data` | `File \| Blob \| string` | Data to upload. Required if `url` isn't specified. |
| `dataIsBase64` | `boolean` | Must be set to `true` if the uploaded data is in Base64 format. |
| `driveItemETag` | `string` | The `eTag` of the already uploaded [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0). Required if `url` is specified. |
| `groupId` | `string` | Teams team group ID. |
| `name` | `string` | Valid name for the uploaded file. |
| `parentPath` | `string` | Name of the parent directory that will contain the file. |
| `replyTo` | `string` | ID of a channel message to which to reply. |
| `url` | `string` | The `webUrl` of the already uploaded [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0). Required if `data` isn't specified. |
| `teamName` | `string` | Teams team name. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SendFileToChannel";
const args = {
    channelId: "teams-channel-id",
    url: "https://example-my.sharepoint.com/personal/file=my-uploaded-document.docx",
    name: "my-uploaded-document.docx",
    driveItemETag: "drive-item-eTag"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

## Files

### io.Teams.UploadToDrive

**Required permissions**:

- `"Files.ReadWrite"`

Uploads a [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) to Microsoft OneDrive. Returns information about the uploaded [file](https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0) in the following format:

```javascript
{
    data: {
        // File details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `conflictBehavior` | `"fail" \| "rename" \| "replace"` | Conflict resolution behavior in case a file with the same name already exists. Defaults to `"replace"`. |
| `data` | `File \| Blob \| string` | Data to upload. |
| `dataIsBase64` | `boolean` | Must be set to `true` if the uploaded data is in Base64 format. |
| `name` | `string` | Valid name for the uploaded file. |
| `parentPath` | `string` | Name of the parent directory that will contain the file. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.UploadToDrive";
const args = {
    name: "my-uploaded-document.docx",
    data: myBase64String,
    dataIsBase64: true
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

## Events

### io.Teams.CreateEvent

**Required permissions**:

- `"Calendars.ReadWrite"`

Creates a calendar [event](https://learn.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0). Returns information about the created [event](https://learn.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0) in the following format:

```javascript
{
    event: {
        // Event details.
    }
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `attendees` | `object[]` | **Required.** List of objects describing the event attendees. |
| `body` | `object` | **Required.** Text body for the event item. |
| `end` | `object` | **Required.** End time of the event. |
| `isOnlineMeeting` | `boolean` | If `true`, the event will be created as an online meeting. |
| `location` | `object` | **Required.** Object with a `displayName` string property holding the name of the event location. |
| `onlineMeetingProvider` | `"unknown" \| "teamsForBusiness" \| "skypeForBusiness" \| "skypeForConsumer"` | Online meeting provider. |
| `start` | `object` | **Required.** Start time of the event. |
| `subject` | `string` | **Required.** Subject for the event item. |

Each object in the `attendees` array has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `emailAddress` | `object` | **Required.** Object with `address` and `name` string properties holding the email address and the name of the attendee respectively. |
| `type` | `"required" \| "optional" \| "resource"` | **Required.** Specifies the type of the attendee. |

The `body` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `content` | `string` | **Required.** Text content for the event item. |
| `contentType` | `"HTML" \| "text"` | **Required.** Type of the text content for the event item. |

The `start` and `end` objects have the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `dateTime` | `string` | **Required.** Timestamp for the event start or end in date time string format (e.g., `2024-07-19T12:00:00`). |
| `timeZone` | `string` | **Required.** Time zone name for the event start or end (e.g., `"Pacific Standard Time"`). |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.CreateEvent";
const args = {
    subject: "My Event",
    body: {
        contentType: "text",
        content: "Welcome to my event!"
    },
    start: {
        dateTime: "2024-07-19T12:00:00",
        timeZone: "Pacific Standard Time"
    },
    end: {
        dateTime: "2024-07-19T12:30:00",
        timeZone: "Pacific Standard Time"
    },
    location:{
        displayName: "Online"
    },
    attendees: [
        {
            emailAddress: {
                address:"john.doe@my-org.com",
                name: "John Doe"
            },
            type: "required"
        },
        {
            emailAddress: {
                address:"jane.doe@my-org.com",
                name: "Jane Doe"
            },
            type: "required"
        }
    ]
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.GetMeetingTranscript

**Required permissions**:

- `"OnlineMeetings.Read"`
- `"OnlineMeetingTranscript.Read.All"`

Retrieves list of the [call transcripts](https://learn.microsoft.com/en-us/graph/api/resources/calltranscript?view=graph-rest-1.0) for a Teams online meeting in the following format:

```javascript
{
    transcripts: [
        {
            // Call transcript details.
        }
    ]
}
```

| Property | Type | Description |
|----------|------|-------------|
| `parse` | `boolean`| If `true`, the call transcripts will be returned in JSON format. Otherwise, the call transcripts will be returned in VTT format. |
| `webUrl` | `string \| string[]`| **Required.** The join URL (or a list of join URLs) for a Teams online meeting. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.GetMeetingTranscript";
const args = {
    webUrl: "https://teams.microsoft.com/l/meetup-join/example",
    parse: true
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

## Search

### io.Teams.SearchChannels

**Required permissions**:

- `"Channel.ReadBasic.All"`
- `"ChannelSettings.Read.All"`
- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Searches the list of channels in which the user participates. This functionality can be invoked without arguments - in this case, an array of all channels in which the user participates will be returned. If providing arguments, it's required to specify either `groupId` or `teamName` in the arguments. If you provide only `groupId` or `teamName` as an argument, all channels in the specified team will be returned. The `channelId` and `channelName` properties can't be used simultaneously. All matching channels will be returned. If no channel is found, will return an empty array.

> ⚠️ *Note that due to limitations of the Microsoft Graph API, using `channelId` or `channelName` without specifying `groupId` or `teamName` won't work.*

Returns information about the found [channels](https://learn.microsoft.com/en-us/graph/api/resources/channel?view=graph-rest-1.0) in the following format:

```javascript
{
    channels: [
        {
            // Channel details.
        }
    ],
    // Returned when the result set is paginated.
    // Use in a subsequent request to retrieve the next result page.
    $skipToken: "skip-token"
}
```

> ⚠️ *Note that due to server-side paging, this functionality may not return all requested entries in one response. In this case, a `"$skipToken"` property will be returned, which the caller must pass in a subsequent request to get the next batch of entries.*

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$skipToken` | `string` | OData [query parameter](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#other-query-parameters). Returned in the response when the result set is paginated. Use the returned value in a subsequent request to retrieve the next page of a paginated result set. |
| `channelId` | `string` | Teams channel ID. |
| `channelName` | `string` | Teams channel name. |
| `groupId` | `string` | Teams team group ID. Required if `teamName` isn't provided. |
| `teamName` | `string` | Teams team name. Required if `groupId` isn't provided. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchChannels";
const args = {
    teamName: "My Team"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchChannelMessages

**Required permissions**:

- `"ChannelMessage.Read.All"`

Searches for chat messages in Teams channels by provided `messageId` or a combination of `channelId` and `groupId`. If `messageId` is specified, `channelId` and `groupId` must not be specified. If `messageId` isn't provided, will search through all available messages.

> ⚠️ *Note that this method uses [payment models](https://learn.microsoft.com/en-us/graph/teams-licenses) for access to paid Microsoft Graph APIs.*

Returns information about the found [chat messages](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    messages: [
        {
            // Message details.
        }
    ],
    // Returned when the result set is paginated.
    // Use in a subsequent request to retrieve the next result page.
    $skipToken: "skip-token"
}
```

> ⚠️ *Note that due to server-side paging, this functionality may not return all requested entries in one response (even if `$top` is specified). In this case, a `"$skipToken"` property will be returned, which the caller must pass in a subsequent request to get the next batch of entries.*

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$skipToken` | `string` | OData [query parameter](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#other-query-parameters). Returned in the response when the result set is paginated. Use the returned value in a subsequent request to retrieve the next page of a paginated result set. |
| `$top` | `number` | Specifies the maximum [number of entries](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter) to be included in the response. |
| `channelId` | `string` | Teams channel ID. |
| `groupId` | `string` | Teams team group ID. |
| `messageId` | `string` | Teams message ID. If this is provided, you must not specify `channelId` or `groupId`. |
| `paymentModel` | `"A" \| "B" \| null` | Specifies the Teams [payment model](https://learn.microsoft.com/en-us/graph/teams-licenses). |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchChannelMessages";
const args = {
    channelId: "teams-channel-id"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchChatMessages

**Required permissions**:

- `"Chat.Read.All"`
- `"Chat.ReadWrite.All"`

Searches for chat messages in Teams chats by provided `messageId` or `chatId`. The `messageId` and `chatId` properties can't be used simultaneously. This functionality can be invoked without arguments - in this case, it will search through all available messages.

> ⚠️ *Note that this method uses [payment models](https://learn.microsoft.com/en-us/graph/teams-licenses) for access to paid Microsoft Graph APIs.*

Returns information about the found [chat messages](https://learn.microsoft.com/en-us/graph/api/resources/chatmessage?view=graph-rest-1.0) in the following format:

```javascript
{
    messages: [
        {
            // Message details.
        }
    ],
    // Returned when the result set is paginated.
    // Use in a subsequent request to retrieve the next result page.
    $skipToken: "skip-token"
}
```

> ⚠️ *Note that due to server-side paging, this functionality may not return all requested entries in one response (even if `$top` is specified). In this case, a `"$skipToken"` property will be returned, which the caller must pass in a subsequent request to get the next batch of entries.*

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$skipToken` | `string` | OData [query parameter](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#other-query-parameters). Returned in the response when the result set is paginated. Use the returned value in a subsequent request to retrieve the next page of a paginated result set. |
| `$top` | `number` | Specifies the maximum [number of entries](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter) to be included in the response. |
| `chatId` | `string` | Teams chat ID. If this is provided, you must not specify `messageId`. |
| `messageId` | `string` | Teams message ID. If this is provided, you must not specify `chatId`. |
| `paymentModel` | `"A" \| "B" \| null` | Specifies the Teams [payment model](https://learn.microsoft.com/en-us/graph/teams-licenses). |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchChatMessages";
const args = {
    chatId: "teams-chat-id"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchChats

**Required permissions**:

- `"Chat.Read"`
- `"Chat.ReadBasic"`
- `"Chat.ReadWrite"`
- `"ChatMessage.Read"`

Searches through all chats in which the user participates. All arguments for the search operation are optional. This functionality can be invoked without arguments - in this case, an array of all chats in which the user participates will be returned. All chats that match the search criteria will be returned. If no chats are found, will return an empty array.

> ⚠️ *Note that due to server-side paging, this functionality may not return all requested entries in one response (even if `$top` is specified). In this case, a `"$skipToken"` property will be returned, which the caller must pass in a subsequent request to get the next batch of entries.*

Returns information about the found [chats](https://learn.microsoft.com/en-us/graph/api/resources/chat?view=graph-rest-1.0) in the following format:

```javascript
{
    chats: [
        {
            // Chat details.
        }
    ],
    // Returned when the result set is paginated.
    // Use in a subsequent request to retrieve the next result page.
    $skipToken: "skip-token"
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$expand` | `string` | [Expands the response](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#expand-parameter) by including additional fields in it. |
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$orderBy` | `string` | [Orders the results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#orderby-parameter) by a specified field name. |
| `$skipToken` | `string` | OData [query parameter](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#other-query-parameters). Returned in the response when the result set is paginated. Use the returned value in a subsequent request to retrieve the next page of a paginated result set. |
| `$top` | `number` | Specifies the maximum [number of entries](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter) to be included in the response. |
| `chatId` | `string` | Teams chat ID. |
| `chatMembers` | `string[]` | List of user emails or Teams user IDs. Users can only interact with chats in which they participate. |
| `chatName` | `string` | Teams chat name. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchChats";
const args = {
    chatId: "teams-chat-id"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchContacts

**Required permissions**:

- `"User.ReadBasic.All"`

Retrieves a list of Teams [users](https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0) based on the provided search criteria.

Returns information about the found [users](https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0) in the following format:

```javascript
{
    contacts: [
        {
            // User details.
        }
    ]
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$count` | `boolean` | Retrieves the total [number of results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#count-parameter) in the response. |
| `$expand` | `string` | [Expands the response](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#expand-parameter) by including additional fields in it. |
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$orderBy` | `string` | [Orders the results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#orderby-parameter) by a specified field name. |
| `$search` | `string` | Limits the results based on a [search criterion](https://learn.microsoft.com/en-us/graph/search-query-parameter). |
| `$select` | `string` | Specifies a [subset of properties](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#select-parameter) to return for each result. |
| `$top` | `number` | Specifies the maximum [number of entries](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter) to be included in the response. |
| `userId` | `string` | Teams user ID. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchContacts";
const args = {
    userId: "teams-user-id"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchEvents

**Required permissions**:

- `"Calendars.Read"`

Retrieves a list of calendar [events](https://learn.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0) based on the provided search criteria.

Returns information about the found calendar [events](https://learn.microsoft.com/en-us/graph/api/resources/event?view=graph-rest-1.0) in the following format:

```javascript
{
    events: [
        {
            // Event details.
        }
    ],
    // Number of skipped results. If there aren't skipped results, will be set to `null`.
    // Skipped results are counted from the start of the results collection in the response.
    $skip: "10"
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `$count` | `boolean` | Retrieves the total [number of results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#count-parameter) in the response. |
| `$expand` | `string` | [Expands the response](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#expand-parameter) by including additional fields in it. |
| `$filter` | `string` | OData [filter expression](https://learn.microsoft.com/en-us/graph/filter-query-parameter). |
| `$format` | `string` | Specifies the [format of the returned results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#format-parameter) (e.g., JSON, XML). |
| `$orderBy` | `string` | [Orders the results](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#orderby-parameter) by a specified field name. |
| `$search` | `string` | Limits the results based on a [search criterion](https://learn.microsoft.com/en-us/graph/search-query-parameter). |
| `$select` | `string` | Specifies a [subset of properties](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#select-parameter) to return for each result. |
| `$skip` | `string` | Specifies the [number of results to skip](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#skip-parameter) (from the start of the result collection) in the response. Can be used in combination with `$top` for pagination. |
| `$top` | `number` | Specifies the maximum [number of entries](https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter) to be included in the response. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchEvents";
const args = {
    $filter: "startswith(subject, 'All')"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```

### io.Teams.SearchTeams

**Required permissions**:

- `"Group.Read.All"`
- `"Group.ReadWrite.All"`
- `"Team.ReadBasic.All"`
- `"User.Read.All"`

Retrieves a collection of [teams](https://learn.microsoft.com/en-us/graph/api/resources/team?view=graph-rest-1.0) in which the user participates. This functionality can be invoked without arguments - in this case, it will return all teams in which the user participates.

Returns information about the found [teams](https://learn.microsoft.com/en-us/graph/api/resources/team?view=graph-rest-1.0) in the following format:

```javascript
{
    teams: [
        {
            // Team details.
        }
    ]
}
```

Accepts as an argument an object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `groupId` | `string` | Teams team group ID. |
| `teamName` | `string` | Teams team name. |

Example Interop method invocation:

```javascript
const methodName = "io.Teams.SearchTeams";
const args = {
    teamName: "My Team"
};

const result = await io.interop.invoke(methodName, args);

console.log(result.returned);
```
