mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
feat(Microsoft Teams Node): Add chat message support (#2635)
* ✨ Add chat messages to MS Teams node * Updated credentials to include missing scope * ⚡ Small improvements Co-authored-by: Jonathan Bennetts <jonathan.bennetts@gmail.com> Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
parent
39a6f41720
commit
984f62df9e
|
@ -16,7 +16,7 @@ export class MicrosoftTeamsOAuth2Api implements ICredentialType {
|
||||||
displayName: 'Scope',
|
displayName: 'Scope',
|
||||||
name: 'scope',
|
name: 'scope',
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
default: 'openid offline_access User.ReadWrite.All Group.ReadWrite.All',
|
default: 'openid offline_access User.ReadWrite.All Group.ReadWrite.All Chat.ReadWrite',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const chatMessageOperations: INodeProperties[] = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a message',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Get a message',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Get all messages',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
description: 'The operation to perform.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const chatMessageFields: INodeProperties[] = [
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* chatMessage:create */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
{
|
||||||
|
displayName: 'Chat ID',
|
||||||
|
name: 'chatId',
|
||||||
|
required: true,
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getChats',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Chat ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message Type',
|
||||||
|
name: 'messageType',
|
||||||
|
required: true,
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Text',
|
||||||
|
value: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'HTML',
|
||||||
|
value: 'html',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'The type of the content',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'The content of the item.',
|
||||||
|
},
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* chatMessage:get */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
{
|
||||||
|
displayName: 'Message ID',
|
||||||
|
name: 'messageId',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* chatMessage:getAll */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
{
|
||||||
|
displayName: 'Chat ID',
|
||||||
|
name: 'chatId',
|
||||||
|
required: true,
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getChats',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Chat ID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'chatMessage',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
];
|
|
@ -26,6 +26,11 @@ import {
|
||||||
channelMessageOperations,
|
channelMessageOperations,
|
||||||
} from './ChannelMessageDescription';
|
} from './ChannelMessageDescription';
|
||||||
|
|
||||||
|
import {
|
||||||
|
chatMessageFields,
|
||||||
|
chatMessageOperations,
|
||||||
|
} from './ChatMessageDescription';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
taskFields,
|
taskFields,
|
||||||
taskOperations,
|
taskOperations,
|
||||||
|
@ -65,6 +70,10 @@ export class MicrosoftTeams implements INodeType {
|
||||||
name: 'Channel Message (Beta)',
|
name: 'Channel Message (Beta)',
|
||||||
value: 'channelMessage',
|
value: 'channelMessage',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Chat Message',
|
||||||
|
value: 'chatMessage',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Task',
|
name: 'Task',
|
||||||
value: 'task',
|
value: 'task',
|
||||||
|
@ -79,6 +88,8 @@ export class MicrosoftTeams implements INodeType {
|
||||||
/// MESSAGE
|
/// MESSAGE
|
||||||
...channelMessageOperations,
|
...channelMessageOperations,
|
||||||
...channelMessageFields,
|
...channelMessageFields,
|
||||||
|
...chatMessageOperations,
|
||||||
|
...chatMessageFields,
|
||||||
///TASK
|
///TASK
|
||||||
...taskOperations,
|
...taskOperations,
|
||||||
...taskFields,
|
...taskFields,
|
||||||
|
@ -189,6 +200,29 @@ export class MicrosoftTeams implements INodeType {
|
||||||
}
|
}
|
||||||
return returnData;
|
return returnData;
|
||||||
},
|
},
|
||||||
|
// Get all the chats to display them to user so that they can
|
||||||
|
// select them easily
|
||||||
|
async getChats(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const qs: IDataObject = {
|
||||||
|
$expand: 'members',
|
||||||
|
};
|
||||||
|
const { value } = await microsoftApiRequest.call(this, 'GET', '/v1.0/chats', {}, qs);
|
||||||
|
for (const chat of value) {
|
||||||
|
if (!chat.topic) {
|
||||||
|
chat.topic = chat.members
|
||||||
|
.filter((member: IDataObject) => member.displayName)
|
||||||
|
.map((member: IDataObject) => member.displayName).join(', ');
|
||||||
|
}
|
||||||
|
const chatName = `${chat.topic || '(no title) - ' + chat.id} (${chat.chatType})`;
|
||||||
|
const chatId = chat.id;
|
||||||
|
returnData.push({
|
||||||
|
name: chatName,
|
||||||
|
value: chatId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -298,6 +332,39 @@ export class MicrosoftTeams implements INodeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (resource === 'chatMessage') {
|
||||||
|
// https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-1.0&tabs=http
|
||||||
|
if (operation === 'create') {
|
||||||
|
const chatId = this.getNodeParameter('chatId', i) as string;
|
||||||
|
const messageType = this.getNodeParameter('messageType', i) as string;
|
||||||
|
const message = this.getNodeParameter('message', i) as string;
|
||||||
|
const body: IDataObject = {
|
||||||
|
body: {
|
||||||
|
contentType: messageType,
|
||||||
|
content: message,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
responseData = await microsoftApiRequest.call(this, 'POST', `/v1.0/chats/${chatId}/messages`, body);
|
||||||
|
}
|
||||||
|
// https://docs.microsoft.com/en-us/graph/api/chat-list-messages?view=graph-rest-1.0&tabs=http
|
||||||
|
if (operation === 'get') {
|
||||||
|
const chatId = this.getNodeParameter('chatId', i) as string;
|
||||||
|
const messageId = this.getNodeParameter('messageId', i) as string;
|
||||||
|
responseData = await microsoftApiRequest.call(this, 'GET', `/v1.0/chats/${chatId}/messages/${messageId}`);
|
||||||
|
}
|
||||||
|
// https://docs.microsoft.com/en-us/graph/api/chat-list-messages?view=graph-rest-1.0&tabs=http
|
||||||
|
if (operation === 'getAll') {
|
||||||
|
const chatId = this.getNodeParameter('chatId', i) as string;
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
if (returnAll) {
|
||||||
|
responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/chats/${chatId}/messages`);
|
||||||
|
} else {
|
||||||
|
qs.limit = this.getNodeParameter('limit', i) as number;
|
||||||
|
responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/chats/${chatId}/messages`, {});
|
||||||
|
responseData = responseData.splice(0, qs.limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (resource === 'task') {
|
if (resource === 'task') {
|
||||||
//https://docs.microsoft.com/en-us/graph/api/planner-post-tasks?view=graph-rest-1.0&tabs=http
|
//https://docs.microsoft.com/en-us/graph/api/planner-post-tasks?view=graph-rest-1.0&tabs=http
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
|
Loading…
Reference in a new issue