new(all): Google Chat (Workspace) connector added.

This commit is contained in:
Rodrigo Rodriguez 2021-06-15 08:36:13 -03:00
parent d8b17af9e8
commit 1b37504077
7 changed files with 212 additions and 170 deletions

1
.gitignore vendored
View file

@ -18,4 +18,3 @@
.env .env
*.env *.env
.vscode/launch.json .vscode/launch.json
/google-chat.json

View file

@ -104,4 +104,7 @@ ALTER TABLE dbo.GuaribasInstance ADD
googleBotKey nvarchar(255) NULL, googleBotKey nvarchar(255) NULL,
googleChatApiKey nvarchar(255) NULL, googleChatApiKey nvarchar(255) NULL,
googleChatSubscriptionName nvarchar(255) NULL, googleChatSubscriptionName nvarchar(255) NULL,
googleClientEmail nvarchar(255) NULL,
googlePrivateKey nvarchar(4000) NULL,
googleProjectId nvarchar(255) NULL
GO GO

216
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "botserver", "name": "botserver",
"version": "2.0.119", "version": "3.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1294,15 +1294,6 @@
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
}, },
"@babel/runtime-corejs3": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.5.tgz",
"integrity": "sha512-cBbwXj3F2xjnQJ0ERaFRLjxhUSBYsQPXJ7CERz/ecx6q6hzQ99eTflAPFC3ks4q/IG4CWupNVdflc4jlFBJVsg==",
"requires": {
"core-js-pure": "^3.14.0",
"regenerator-runtime": "^0.13.4"
}
},
"@babel/template": { "@babel/template": {
"version": "7.10.4", "version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
@ -5249,9 +5240,9 @@
} }
}, },
"botlib": { "botlib": {
"version": "1.8.1", "version": "1.8.3",
"resolved": "https://registry.npmjs.org/botlib/-/botlib-1.8.1.tgz", "resolved": "https://registry.npmjs.org/botlib/-/botlib-1.8.3.tgz",
"integrity": "sha512-u890+yJVOVWKtskY1LvgKz5cM+7XEXAkVUCsLDa7MxTW/GDJQIqHg5i8Zmhp/f6ARiE28WW0gAqXWM9jRKVtbQ==", "integrity": "sha512-NWVeSgavucALMJ6yZT7ld0v01mL3964+3OLCW8oW2nuFxG4eBEpNztsg5HKJWBKb9nbeNWU70ynstC43kMQ+uw==",
"requires": { "requires": {
"async": "3.2.0", "async": "3.2.0",
"botbuilder": "4.13.5", "botbuilder": "4.13.5",
@ -5311,11 +5302,6 @@
"util-deprecate": "^1.0.1" "util-deprecate": "^1.0.1"
} }
}, },
"underscore": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
"integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g=="
},
"winston": { "winston": {
"version": "3.3.3", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz",
@ -7353,11 +7339,6 @@
} }
} }
}, },
"core-js-pure": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.14.0.tgz",
"integrity": "sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g=="
},
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@ -7762,7 +7743,8 @@
"deep-extend": { "deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
}, },
"deep-is": { "deep-is": {
"version": "0.1.3", "version": "0.1.3",
@ -8983,11 +8965,6 @@
} }
} }
}, },
"fast-json-patch": {
"version": "3.0.0-1",
"resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.0.0-1.tgz",
"integrity": "sha512-6pdFb07cknxvPzCeLsFHStEy+MysPJPgZQ9LbQ/2O67unQF93SNqfdSqnPPl71YMHX+AD8gbl7iuoGFzHEdDuw=="
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@ -11218,14 +11195,6 @@
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
}, },
"isomorphic-form-data": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-2.0.0.tgz",
"integrity": "sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg==",
"requires": {
"form-data": "^2.3.2"
}
},
"isstream": { "isstream": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -12363,6 +12332,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
}, },
"lodash-compat": {
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/lodash-compat/-/lodash-compat-3.10.2.tgz",
"integrity": "sha1-xpQBKKnTD46QLNLPmf0Muk7PwYM="
},
"lodash.camelcase": { "lodash.camelcase": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
@ -17543,24 +17517,13 @@
"q": { "q": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
"dev": true
}, },
"qs": { "qs": {
"version": "6.5.2", "version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
}, },
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
},
"querystring-browser": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/querystring-browser/-/querystring-browser-1.0.4.tgz",
"integrity": "sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY="
},
"querystringify": { "querystringify": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@ -17754,6 +17717,11 @@
"esprima": "~4.0.0" "esprima": "~4.0.0"
} }
}, },
"reduce-component": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz",
"integrity": "sha1-4Mk1QsV0UhvqE98PlIjtgqt3xdo="
},
"reflect-metadata": { "reflect-metadata": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@ -19566,52 +19534,116 @@
} }
}, },
"swagger-client": { "swagger-client": {
"version": "3.13.5", "version": "2.1.18",
"resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.5.tgz", "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-2.1.18.tgz",
"integrity": "sha512-n4+yS0+jvx7PNq95TulWhjN+v9Cz6GRkdloF3LL0JV2eQ8E8a3a+0/XEppsYGIzb7i2/h7ZMcM5hIxIr7Gr1RA==", "integrity": "sha1-0zrd7Li438Qjh931t1pAXlQ32M8=",
"requires": { "requires": {
"@babel/runtime-corejs3": "^7.11.2", "btoa": "^1.1.2",
"btoa": "^1.2.1", "cookiejar": "^2.0.1",
"buffer": "^6.0.3", "js-yaml": "^3.3.0",
"cookie": "~0.4.1", "lodash-compat": "^3.5.0",
"cross-fetch": "^3.0.6", "q": "^1.4.1",
"deep-extend": "~0.6.0", "superagent": "^1.2"
"fast-json-patch": "^3.0.0-1",
"isomorphic-form-data": "~2.0.0",
"js-yaml": "^3.14.0",
"lodash": "^4.17.19",
"qs": "^6.9.4",
"querystring-browser": "^1.0.4",
"traverse": "~0.6.6",
"url": "~0.11.0"
}, },
"dependencies": { "dependencies": {
"buffer": { "async": {
"version": "6.0.3", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
},
"component-emitter": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": { "requires": {
"base64-js": "^1.3.1", "ms": "2.0.0"
"ieee754": "^1.2.1"
} }
}, },
"cookie": { "extend": {
"version": "0.4.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ="
},
"form-data": {
"version": "1.0.0-rc3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
"integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=",
"requires": {
"async": "^1.4.0",
"combined-stream": "^1.0.5",
"mime-types": "^2.1.3"
}
},
"formidable": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.16.tgz",
"integrity": "sha1-SRbP38TL7QILJXpqlQWpqzjCzQ4="
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"mime": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
"integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}, },
"qs": { "qs": {
"version": "6.10.1", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ="
},
"readable-stream": {
"version": "1.0.27-1",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
"integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=",
"requires": { "requires": {
"side-channel": "^1.0.4" "core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
} }
}, },
"traverse": { "string_decoder": {
"version": "0.6.6", "version": "0.10.31",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"superagent": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-1.8.5.tgz",
"integrity": "sha1-HA3cOvMOgOuE68BcshItqP6UC1U=",
"requires": {
"component-emitter": "~1.2.0",
"cookiejar": "2.0.6",
"debug": "2",
"extend": "3.0.0",
"form-data": "1.0.0-rc3",
"formidable": "~1.0.14",
"methods": "~1.1.1",
"mime": "1.3.4",
"qs": "2.3.3",
"readable-stream": "1.0.27-1",
"reduce-component": "1.0.1"
},
"dependencies": {
"cookiejar": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz",
"integrity": "sha1-Cr81atANHFohnYjURRgEbdAmrP4="
}
}
} }
} }
}, },
@ -20893,22 +20925,6 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
"integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
},
"dependencies": {
"punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
}
}
},
"url-join": { "url-join": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "botserver", "name": "botserver",
"version": "2.0.119", "version": "3.0.0",
"description": "General Bot Community Edition open-core server.", "description": "General Bot Community Edition open-core server.",
"main": "./boot.js", "main": "./boot.js",
"bugs": "https://github.com/pragmatismo-io/BotServer/issues", "bugs": "https://github.com/pragmatismo-io/BotServer/issues",
@ -72,7 +72,7 @@
"botbuilder-ai": "4.13.5", "botbuilder-ai": "4.13.5",
"botbuilder-dialogs": "4.13.5", "botbuilder-dialogs": "4.13.5",
"botframework-connector": "4.13.5", "botframework-connector": "4.13.5",
"botlib": "1.8.1", "botlib": "1.8.3",
"cli-spinner": "0.2.10", "cli-spinner": "0.2.10",
"core-js": "3.14.0", "core-js": "3.14.0",
"dotenv-extended": "2.9.0", "dotenv-extended": "2.9.0",
@ -107,7 +107,7 @@
"speakingurl": "^14.0.1", "speakingurl": "^14.0.1",
"sppull": "2.7.0", "sppull": "2.7.0",
"strict-password-generator": "1.1.2", "strict-password-generator": "1.1.2",
"swagger-client": "^3.13.5", "swagger-client": "2.1.18",
"tedious": "9.2.1", "tedious": "9.2.1",
"textract": "2.5.0", "textract": "2.5.0",
"typescript": "3.9.4", "typescript": "3.9.4",

View file

@ -142,6 +142,15 @@ export class GuaribasInstance extends Model<GuaribasInstance>
@Column @Column
public googleChatSubscriptionName: string; public googleChatSubscriptionName: string;
@Column
public googleClientEmail: string;
@Column({ type: DataType.STRING(4000) })
public googlePrivateKey: string;
@Column
public googleProjectId: string;
@Column @Column
public whatsappBotKey: string; public whatsappBotKey: string;

View file

@ -227,7 +227,7 @@ export class GBMinService {
const url = `/api/messages/${instance.botId}`; const url = `/api/messages/${instance.botId}`;
GBServer.globals.server.post(url, receiver); GBServer.globals.server.post(url, receiver);
GBServer.globals.server.get(url, (req, res) => { GBServer.globals.server.get(url, (req, res) => {
if (req.query['hub.mode'] === 'subscribe') { if (req.query['hub.mode'] === 'subscribe') {
if (req.query['hub.verify_token'] === process.env.FACEBOOK_VERIFY_TOKEN) { if (req.query['hub.verify_token'] === process.env.FACEBOOK_VERIFY_TOKEN) {
const val = req.query['hub.challenge']; const val = req.query['hub.challenge'];
res.send(val); res.send(val);
@ -651,16 +651,19 @@ export class GBMinService {
} }
}); });
if (min.instance.googlePrivateKey) {
min['googleDirectLine'] = new GoogleChatDirectLine( min['googleDirectLine'] = new GoogleChatDirectLine(
min, min,
min.botId, min.botId,
min.instance.googleBotKey, min.instance.googleBotKey,
min.instance.googleChatSubscriptionName, min.instance.googleChatSubscriptionName,
min.instance.googleChatApiKey min.instance.googleChatApiKey,
); min.instance.googleClientEmail,
await min['googleDirectLine'].setup(true); min.instance.googlePrivateKey.replace(/\\n/gm, '\n'),
min.instance.googleProjectId
);
await min['googleDirectLine'].setup(true);
}
// If there is WhatsApp configuration specified, initialize // If there is WhatsApp configuration specified, initialize
// infrastructure objects. // infrastructure objects.
@ -773,9 +776,8 @@ export class GBMinService {
let adapter = min.bot; let adapter = min.bot;
if (req.body.object) if (req.body.object) {
{ req['rawBody'] = JSON.stringify(req.body);
req['rawBody']=JSON.stringify(req.body);
adapter = min['fbAdapter']; adapter = min['fbAdapter'];
} }

View file

@ -30,30 +30,17 @@
| | | |
\*****************************************************************************/ \*****************************************************************************/
import urlJoin = require('url-join');
const Swagger = require('swagger-client'); const Swagger = require('swagger-client');
const rp = require('request-promise');
const fs = require('fs'); const fs = require('fs');
import { GBLog, GBMinInstance, GBService, IGBPackage } from 'botlib';
import { CollectionUtil } from 'pragmatismo-io-framework';
import * as request from 'request-promise-native';
import { GBServer } from '../../../src/app';
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService';
import { SecService } from '../../security.gbapp/services/SecService';
import { Messages } from '../strings';
const { google } = require('googleapis') const { google } = require('googleapis')
const chat = google.chat('v1');
const { promisify } = require('util'); const { promisify } = require('util');
chat.spaces.messages.createAsync = promisify(chat.spaces.messages.create);
const { PubSub } = require('@google-cloud/pubsub'); const { PubSub } = require('@google-cloud/pubsub');
import { GBLog, GBMinInstance, GBService } from 'botlib';
// Creates a client; cache this for further use import { GBServer } from '../../../src/app';
const subscriptionName = 'projects/eastern-amp-316323/topics/generalbots'; import { SecService } from '../../security.gbapp/services/SecService';
const timeout = 60;
/** /**
* Support for GoogleChat. * Support for Google Chat.
*/ */
export class GoogleChatDirectLine extends GBService { export class GoogleChatDirectLine extends GBService {
@ -68,6 +55,9 @@ export class GoogleChatDirectLine extends GBService {
private directLineSecret: string; private directLineSecret: string;
pubSubClient: any; pubSubClient: any;
GoogleChatApiKey: any; GoogleChatApiKey: any;
GoogleClientEmail: any;
GoogleClientPrivateKey: any;
GoogleProjectId: any;
constructor( constructor(
min: GBMinInstance, min: GBMinInstance,
@ -75,6 +65,9 @@ export class GoogleChatDirectLine extends GBService {
directLineSecret, directLineSecret,
GoogleChatSubscriptionName, GoogleChatSubscriptionName,
GoogleChatApiKey, GoogleChatApiKey,
GoogleClientEmail,
GoogleClientPrivateKey,
GoogleProjectId
) { ) {
super(); super();
@ -82,8 +75,15 @@ export class GoogleChatDirectLine extends GBService {
this.botId = botId; this.botId = botId;
this.directLineSecret = directLineSecret; this.directLineSecret = directLineSecret;
this.GoogleChatSubscriptionName = GoogleChatSubscriptionName; this.GoogleChatSubscriptionName = GoogleChatSubscriptionName;
this.pubSubClient = new PubSub();
this.GoogleChatApiKey = GoogleChatApiKey; this.GoogleChatApiKey = GoogleChatApiKey;
this.GoogleClientEmail = GoogleClientEmail;
this.GoogleClientPrivateKey = GoogleClientPrivateKey;
this.GoogleProjectId = GoogleProjectId;
this.pubSubClient = new PubSub({
projectId: this.GoogleProjectId,
credentials: { client_email: GoogleClientEmail, private_key: GoogleClientPrivateKey }
});
} }
@ -107,8 +107,6 @@ export class GoogleChatDirectLine extends GBService {
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${this.directLineSecret}`, 'header') new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${this.directLineSecret}`, 'header')
); );
if (setUrl) { if (setUrl) {
try { try {
@ -136,15 +134,13 @@ export class GoogleChatDirectLine extends GBService {
const event = JSON.parse(Buffer.from(message.data, 'binary').toString()); const event = JSON.parse(Buffer.from(message.data, 'binary').toString());
let from = ''; let from = '';
let fromName=''; let fromName = '';
let text; let text;
const threadName = event.message.thread.name; const threadName = event.message.thread.name;
if (event['type'] === 'ADDED_TO_SPACE' && event['space']['singleUserBotDm']) if (event['type'] === 'ADDED_TO_SPACE' && event['space']['singleUserBotDm']) {
{
}else if(event['type'] === 'MESSAGE') } else if (event['type'] === 'MESSAGE') {
{
text = event.message.text; text = event.message.text;
fromName = event.message.sender.displayName; fromName = event.message.sender.displayName;
from = event.message.sender.email; from = event.message.sender.email;
@ -152,27 +148,33 @@ export class GoogleChatDirectLine extends GBService {
} }
message.ack(); message.ack();
const sec = new SecService();
const user = await sec.ensureUser(this.min.instance.instanceId, from,
from, '', 'googlechat', fromName, from);
await sec.updateConversationReferenceById(user.userId, threadName);
GBLog.info(`GBGoogleChat: RCV ${from}: ${text})`); GBLog.info(`GBGoogleChat: RCV ${from}: ${text})`);
const client = await this.directLineClient; const client = await this.directLineClient;
const conversationId = GoogleChatDirectLine.conversationIds[threadName]; const conversationId = GoogleChatDirectLine.conversationIds[from];
if (GoogleChatDirectLine.conversationIds[threadName] === undefined) { if (GoogleChatDirectLine.conversationIds[from] === undefined) {
GBLog.info(`GBGoogleChat: Starting new conversation on Bot.`); GBLog.info(`GBGoogleChat: Starting new conversation on Bot.`);
const response = await client.Conversations.Conversations_StartConversation(); const response = await client.Conversations.Conversations_StartConversation();
const generatedConversationId = response.obj.conversationId; const generatedConversationId = response.obj.conversationId;
GoogleChatDirectLine.conversationIds[threadName] = generatedConversationId; GoogleChatDirectLine.conversationIds[from] = generatedConversationId;
this.pollMessages(client, generatedConversationId, from, fromName); this.pollMessages(client, generatedConversationId, threadName, from, fromName);
this.inputMessage(client, generatedConversationId, text, from, fromName); this.inputMessage(client, generatedConversationId, threadName, text, from, fromName);
} else { } else {
this.inputMessage(client, conversationId, text, from, fromName); this.inputMessage(client, conversationId, threadName, text, from, fromName);
} }
} }
public inputMessage(client, conversationId, text, from, fromName) { public inputMessage(client, conversationId, threadName, text, from, fromName) {
return client.Conversations.Conversations_PostActivity({ return client.Conversations.Conversations_PostActivity({
conversationId: conversationId, conversationId: conversationId,
activity: { activity: {
@ -189,7 +191,7 @@ export class GoogleChatDirectLine extends GBService {
}); });
} }
public pollMessages(client, conversationId, from, fromName) { public pollMessages(client, conversationId, threadName, from, fromName) {
GBLog.info(`GBGoogleChat: Starting message polling(${from}, ${conversationId}).`); GBLog.info(`GBGoogleChat: Starting message polling(${from}, ${conversationId}).`);
let watermark: any; let watermark: any;
@ -201,7 +203,7 @@ export class GoogleChatDirectLine extends GBService {
watermark: watermark watermark: watermark
}); });
watermark = response.obj.watermark; watermark = response.obj.watermark;
await this.printMessages(response.obj.activities, conversationId, from, fromName); await this.printMessages(response.obj.activities, conversationId, threadName, from, fromName);
} catch (err) { } catch (err) {
GBLog.error(`Error calling printMessages on GoogleChat channel ${err.data === undefined ? err : err.data}`); GBLog.error(`Error calling printMessages on GoogleChat channel ${err.data === undefined ? err : err.data}`);
} }
@ -209,7 +211,7 @@ export class GoogleChatDirectLine extends GBService {
setInterval(worker, this.pollInterval); setInterval(worker, this.pollInterval);
} }
public async printMessages(activities, conversationId, from, fromName) { public async printMessages(activities, conversationId, threadName, from, fromName) {
if (activities && activities.length) { if (activities && activities.length) {
// Ignore own messages. // Ignore own messages.
@ -219,13 +221,13 @@ export class GoogleChatDirectLine extends GBService {
// Print other messages. // Print other messages.
await GoogleChatDirectLine.asyncForEach(activities, async activity => { await GoogleChatDirectLine.asyncForEach(activities, async activity => {
await this.printMessage(activity, conversationId, from, fromName); await this.printMessage(activity, conversationId, threadName, from, fromName);
}); });
} }
} }
} }
public async printMessage(activity, conversationId, from, fromName) { public async printMessage(activity, conversationId, threadName, from, fromName) {
let output = ''; let output = '';
if (activity.text) { if (activity.text) {
@ -246,34 +248,45 @@ export class GoogleChatDirectLine extends GBService {
}); });
} }
await this.sendToDevice(from, output); await this.sendToDevice(from, conversationId, threadName, output);
} }
public async sendToDevice(threadName: string, msg: string) { public async sendToDevice(from: string, conversationId: string, threadName, msg: string) {
try { try {
let threadParts = threadName.split('/'); let threadParts = threadName.split('/');
let spaces = threadParts[1]; let spaces = threadParts[1];
let threadKey = threadParts[3]; let threadKey = threadParts[3];
const scopes = ['https://www.googleapis.com/auth/chat.bot'];
const jwtClient = new google.auth.JWT(
this.GoogleClientEmail,
null,
this.GoogleClientPrivateKey,
scopes,
null
);
await jwtClient.authorize();
const chat = google.chat({version: 'v1', auth: jwtClient});
chat.spaces.messages.createAsync = promisify(chat.spaces.messages.create);
const res = await chat.spaces.messages.createAsync({ const res = await chat.spaces.messages.createAsync({
auth: this.GoogleChatApiKey,
parent: `spaces/${spaces}`, parent: `spaces/${spaces}`,
threadKey: threadKey, threadKey: threadKey,
body: { requestBody: {
text: msg text: msg
} }
}); });
GBLog.info(res); GBLog.info(res);
GBLog.info(`Message [${msg}] sent to ${threadName}: `); GBLog.info(`Message [${msg}] sent to ${from}: `);
} catch (error) { } catch (error) {
GBLog.error(`Error sending message to GoogleChat provider ${error.message}`); GBLog.error(`Error sending message to GoogleChat provider ${error.message}`);
} }
} }
public async sendToDeviceEx(to, text, locale) { public async sendToDeviceEx(to, conversationId, threadName, text, locale) {
const minBoot = GBServer.globals.minBoot as any; const minBoot = GBServer.globals.minBoot as any;
text = await minBoot.conversationalService.translate( text = await minBoot.conversationalService.translate(
@ -281,6 +294,6 @@ export class GoogleChatDirectLine extends GBService {
text, text,
locale locale
); );
await this.sendToDevice(to, text); await this.sendToDevice(to, conversationId, threadName, text);
} }
} }