mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
🚧 WIP for websocket connection
This commit is contained in:
parent
dacf719a24
commit
8b74713fe9
|
@ -11,6 +11,7 @@ import {
|
|||
|
||||
import {
|
||||
discordApiRequest,
|
||||
setHeartbeatInterval,
|
||||
} from './GenericFunctions';
|
||||
|
||||
import {
|
||||
|
@ -20,6 +21,12 @@ import {
|
|||
userOperations,
|
||||
} from './descriptions';
|
||||
|
||||
import WebSocket = require('ws');
|
||||
|
||||
import {
|
||||
clearInterval,
|
||||
} from 'timers';
|
||||
|
||||
export class Discord implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Discord',
|
||||
|
@ -75,6 +82,44 @@ export class Discord implements INodeType {
|
|||
let responseData;
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
const { url } = await discordApiRequest.call(this, 'GET', '/gateway');
|
||||
|
||||
const ws = new WebSocket(`${url}?v=8&encoding=json`);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
ws.on('open', () => {
|
||||
console.log('*** WEBSOCKET CONNECTION OPEN ***');
|
||||
});
|
||||
|
||||
let heartbeatInterval: NodeJS.Timeout;
|
||||
|
||||
ws.on('message', (data: string) => {
|
||||
const op = JSON.parse(data).op;
|
||||
const mapping: { [key: number]: 'hello' | 'acknowledgment' } = {
|
||||
10: 'hello',
|
||||
11: 'acknowledgment',
|
||||
};
|
||||
|
||||
console.log(`--- MESSAGE RECEIVED: ${mapping[op]} ---`);
|
||||
|
||||
if (mapping[op] === 'hello') {
|
||||
console.log('--- SET HEARTBEAT ---');
|
||||
heartbeatInterval = setHeartbeatInterval(ws, data);
|
||||
resolve();
|
||||
}
|
||||
|
||||
// TODO close connection if heartbeat acknowledgment does not arrive
|
||||
console.log(`--- MESSAGE CONTENTS FOR ${mapping[op]} ---`);
|
||||
console.log(JSON.parse(data));
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('*** WEBSOCKET CONNECTION CLOSED ***');
|
||||
console.log('--- UNSET HEARTBEAT ---');
|
||||
clearInterval(heartbeatInterval);
|
||||
});
|
||||
});
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
if (resource === 'message') {
|
||||
|
@ -104,7 +149,31 @@ export class Discord implements INodeType {
|
|||
|
||||
await discordApiRequest.call(this, 'POST', '', body, {}, webhookUrl);
|
||||
responseData = { success: true };
|
||||
|
||||
} else if (operation === 'ws') {
|
||||
|
||||
const { oauthTokenData } = this.getCredentials('discordOAuth2Api') as {
|
||||
oauthTokenData: { access_token: string }
|
||||
};
|
||||
|
||||
const payload = JSON.stringify({
|
||||
op: 2,
|
||||
d: {
|
||||
token: oauthTokenData.access_token,
|
||||
intents: 513,
|
||||
properties: {
|
||||
$os: 'linux',
|
||||
$browser: 'firefox',
|
||||
$device: 'n8n',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ws.send(payload);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (resource === 'user') {
|
||||
|
@ -136,6 +205,15 @@ export class Discord implements INodeType {
|
|||
: returnData.push(responseData);
|
||||
}
|
||||
|
||||
await new Promise(resolve => {
|
||||
setTimeout(resolve, 3 * 60 * 1000);
|
||||
});
|
||||
|
||||
ws.terminate();
|
||||
|
||||
|
||||
// console.log(ws.);
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import {
|
|||
IDataObject,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import WebSocket = require('ws');
|
||||
|
||||
export async function discordApiRequest(
|
||||
this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
|
||||
method: string,
|
||||
|
@ -21,9 +23,15 @@ export async function discordApiRequest(
|
|||
uri?: string,
|
||||
option: IDataObject = {},
|
||||
) {
|
||||
|
||||
const { oauthTokenData } = this.getCredentials('discordOAuth2Api') as {
|
||||
oauthTokenData: { access_token: string }
|
||||
};
|
||||
|
||||
const options: OptionsWithUri = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${oauthTokenData.access_token}`,
|
||||
},
|
||||
method,
|
||||
body,
|
||||
|
@ -49,20 +57,24 @@ export async function discordApiRequest(
|
|||
};
|
||||
|
||||
try {
|
||||
console.log(options);
|
||||
// console.log(options);
|
||||
return await this.helpers.requestOAuth2!.call(this, 'discordOAuth2Api', options, oAuth2Options);
|
||||
// return await this.helpers.request!.call(this, options);
|
||||
} catch (error) {
|
||||
|
||||
const errors = error.response.body.context_info.errors;
|
||||
const message = error.response.body.message;
|
||||
|
||||
if (errors) {
|
||||
const errorMessage = errors.map((e: IDataObject) => e.message).join('|');
|
||||
throw new Error(`Discord error response [${error.statusCode}]: ${errorMessage}`);
|
||||
} else if (message) {
|
||||
throw new Error(`Discord error response [${error.statusCode}]: ${message}`);
|
||||
}
|
||||
// TODO
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function setHeartbeatInterval(ws: WebSocket, data: string) {
|
||||
const interval = JSON.parse(data).d.heartbeat_interval;
|
||||
|
||||
const payload = JSON.stringify({
|
||||
op: 1, // opcode
|
||||
d: 251, // last sequence number `s` received by client
|
||||
});
|
||||
|
||||
return setInterval(() => ws.send(payload), interval);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ export const messageOperations = [
|
|||
value: 'create',
|
||||
description: 'Create a message',
|
||||
},
|
||||
{
|
||||
name: 'WS',
|
||||
value: 'ws',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
description: 'The operation to perform.',
|
||||
|
|
|
@ -555,6 +555,7 @@
|
|||
"@types/ssh2-sftp-client": "^5.1.0",
|
||||
"@types/tmp": "^0.2.0",
|
||||
"@types/uuid": "^3.4.6",
|
||||
"@types/ws": "^7.4.0",
|
||||
"@types/xml2js": "^0.4.3",
|
||||
"gulp": "^4.0.0",
|
||||
"jest": "^26.4.2",
|
||||
|
@ -609,6 +610,7 @@
|
|||
"tmp-promise": "^3.0.2",
|
||||
"uuid": "^3.4.0",
|
||||
"vm2": "^3.6.10",
|
||||
"ws": "^7.4.3",
|
||||
"xlsx": "^0.16.7",
|
||||
"xml2js": "^0.4.22"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue