diff --git a/package-lock.json b/package-lock.json index b89be32a4..5c7a7d222 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "botserver", - "version": "2.0.141", + "version": "2.0.151", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -80,15 +80,15 @@ } }, "@azure/core-rest-pipeline": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.1.1.tgz", - "integrity": "sha512-ObF8iTEDXIG7/NlL28ni9bR3XLJwgm2S3GWO4aNW6CsTCFVoY9HMdbBtN7xOB+pUQwifehifXNnootbzzuwJnw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.3.0.tgz", + "integrity": "sha512-XdGCm4sVfLvFbd3x17Aw6XNA8SK+sWFvVlOnNSSL2OJGJ4g10LspCpGnIqB+V6OZAaVwOx/eQQN2rOfZzf4Q5w==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.12", + "@azure/core-tracing": "1.0.0-preview.13", "@azure/logger": "^1.0.0", - "form-data": "^3.0.0", + "form-data": "^4.0.0", "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", "tslib": "^2.2.0", @@ -96,9 +96,9 @@ }, "dependencies": { "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -106,9 +106,9 @@ } }, "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, "uuid": { "version": "8.3.2", @@ -118,35 +118,35 @@ } }, "@azure/core-tracing": { - "version": "1.0.0-preview.12", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.12.tgz", - "integrity": "sha512-nvo2Wc4EKZGN6eFu9n3U7OXmASmL8VxoPIH7xaD6OlQqi44bouF0YIi9ID5rEsKLiAU59IYx6M297nqWVMWPDg==", + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", "requires": { - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" }, "dependencies": { "@opentelemetry/api": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.1.tgz", - "integrity": "sha512-H5Djcc2txGAINgf3TNaq4yFofYSIK3722PM89S/3R8FuI/eqi1UscajlXk7EBkG9s2pxss/q6SHlpturaavXaw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz", + "integrity": "sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ==" }, "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" } } }, "@azure/cosmos": { - "version": "3.12.2", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.12.2.tgz", - "integrity": "sha512-57KPx3nXOFxhrlFsjP9+ZE87IJ7TFjy/kFa6FS+fmA3MGFDoKULJkZ9YThKMiUXgT+isUeDlQSiURDq10XbIqA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.14.1.tgz", + "integrity": "sha512-i8HJOlmVfr1P5qMNgKbEpszddtT8Ooskj2pJm0ZD7jeMuwN2tYlQ68eLyCmynv1j5PQimLGjlobBVuFuM8uNAA==", "requires": { "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-rest-pipeline": "^1.2.0", "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "jsbi": "^3.1.3", "node-abort-controller": "^1.2.0", "priorityqueuejs": "^1.0.0", @@ -165,9 +165,9 @@ } }, "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, "uuid": { "version": "8.3.2", @@ -185,9 +185,9 @@ }, "dependencies": { "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" } } }, @@ -3455,9 +3455,9 @@ } }, "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.6.tgz", + "integrity": "sha512-nUeYhBHLG08VFOkVwai0pLXge6NNlahH+ccwxXodvl+SLa5l9mXHjg40jRVzofRPz29goiTGze7vIKmCltKtSA==" }, "agent-base": { "version": "4.3.0", @@ -5250,9 +5250,9 @@ } }, "botlib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/botlib/-/botlib-1.9.3.tgz", - "integrity": "sha512-t5xLXHghHy0694tE+64nvSRlv5SNX5BAUJEOQ2P7tA685UzKbFekrS1Tik8Z+5Rl9MMxfuZFFbMyZQX/2opSxQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/botlib/-/botlib-1.9.4.tgz", + "integrity": "sha512-WC9+iss8ch2aDhXDUfiVD5gO1tKcWbPyo8Ul+CNUwM+CdjqVW1mndg83OSX2VZS5vqjU024AwFEJ1jq3EosXvQ==", "requires": { "async": "3.2.0", "botbuilder": "4.11.0", @@ -5807,9 +5807,9 @@ }, "dependencies": { "dayjs": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz", - "integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==" + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" } } }, @@ -8347,6 +8347,13 @@ "adm-zip": "^0.4.4", "bluebird": "^3.5.1", "xml2js": "^0.4.4" + }, + "dependencies": { + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + } } }, "error-ex": { diff --git a/package.json b/package.json index e7b4a49c3..5fd719acb 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@sendgrid/mail": "^7.4.4", "@types/validator": "13.1.4", "adal-node": "0.2.2", + "adm-zip": "^0.5.6", "any-shell-escape": "0.1.1", "async-promises": "0.2.3", "azure-arm-cognitiveservices": "3.0.0", @@ -73,7 +74,7 @@ "botbuilder-ai": "4.11.0", "botbuilder-dialogs": "4.11.0", "botframework-connector": "4.11.0", - "botlib": "1.9.3", + "botlib": "1.9.4", "cli-spinner": "0.2.10", "core-js": "3.14.0", "date-diff": "^0.2.2", diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index f922d3c6b..45f53d3dd 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -36,7 +36,7 @@ 'use strict'; -import { GBLog, GBMinInstance, IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib'; +import { GBLog, IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib'; import * as fs from 'fs'; import { Sequelize, SequelizeOptions } from 'sequelize-typescript'; import { Op, Dialect } from 'sequelize'; @@ -50,12 +50,11 @@ import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp import { GBKBPackage } from '../../kb.gbapp'; import { GBSecurityPackage } from '../../security.gbapp'; import { GBWhatsappPackage } from '../../whatsapp.gblib/index'; -import { GuaribasInstance, GuaribasSchedule } from '../models/GBModel'; +import { GuaribasInstance } from '../models/GBModel'; import { GBConfigService } from './GBConfigService'; import { GBAzureDeployerPackage } from '../../azuredeployer.gbapp'; import { GBSharePointPackage } from '../../sharepoint.gblib'; import { CollectionUtil } from 'pragmatismo-io-framework'; -import { GBVMService } from '../../basic.gblib/services/GBVMService'; import { GBBasicPackage } from '../../basic.gblib'; import { GBGoogleChatPackage } from '../../google-chat.gblib'; diff --git a/packages/core.gbapp/services/GBDeployer.ts b/packages/core.gbapp/services/GBDeployer.ts index d7b3f8d9a..6ff0badc1 100644 --- a/packages/core.gbapp/services/GBDeployer.ts +++ b/packages/core.gbapp/services/GBDeployer.ts @@ -43,7 +43,7 @@ const express = require('express'); const child_process = require('child_process'); const rimraf = require('rimraf'); const request = require('request-promise-native'); - +const uuidv4 = require('uuid/v4'); import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBDeployer, IGBInstance, IGBPackage } from 'botlib'; import { AzureSearch } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework'; @@ -55,6 +55,7 @@ import { AzureDeployerService } from './../../azuredeployer.gbapp/services/Azure import { KBService } from './../../kb.gbapp/services/KBService'; import { GBConfigService } from './GBConfigService'; import { GBImporter } from './GBImporterService'; +import { TeamsService } from '../../teams.gblib/services/TeamsService'; const MicrosoftGraph = require('@microsoft/microsoft-graph-client'); /** @@ -356,6 +357,16 @@ export class GBDeployer implements IGBDeployer { sleep(5000); } + /** + * Return a zip file for importing bot in apps, currently MS Teams. + */ + public async getBotManifest(instance: IGBInstance): Promise { + const s = new TeamsService(); + const manifest = await s.getManifest(instance.marketplaceId, instance.title, instance.description, + uuidv4().toString(), instance.botId, "General Bots"); + return await s.getAppFile(manifest); + } + /** * Refreshes NLP entities on the remote service. */ @@ -446,7 +457,7 @@ export class GBDeployer implements IGBDeployer { baseUrl: string = null, client = null): Promise { - GBLog.info(`downloadFolder: localPath=${localPath}, remotePath=${remotePath}, baseUrl=${baseUrl}`); + GBLog.info(`downloadFolder: localPath=${localPath}, remotePath=${remotePath}, baseUrl=${baseUrl}`); if (!baseUrl) { [baseUrl, client] = await GBDeployer.internalGetDriveClient(min); @@ -473,7 +484,7 @@ export class GBDeployer implements IGBDeployer { const botId = min.instance.botId; const path = urlJoin(`/${botId}.gbai`, remotePath); let url = `${baseUrl}/drive/root:${path}:/children`; - + GBLog.info(`Download URL: ${url}`); const res = await client @@ -500,10 +511,7 @@ export class GBDeployer implements IGBDeployer { } else { GBLog.info(`Downloading ${itemPath}...`); const url = item['@microsoft.graph.downloadUrl']; - const options = { - uri: url, - encoding: null - }; + const response = await request({ uri: url, encoding: null }); Fs.writeFileSync(itemPath, response, { encoding: null }); } @@ -909,7 +917,8 @@ export class GBDeployer implements IGBDeployer { 'azuredeployer.gbapp', 'customer-satisfaction.gbapp', 'kb.gbapp', - 'google-chat.gblib' + 'google-chat.gblib', + 'teams.gblib' ]; return names.indexOf(name) > -1; diff --git a/packages/google-chat.gblib/services/GoogleChatDirectLine.ts b/packages/google-chat.gblib/services/GoogleChatDirectLine.ts index ee3d2605a..7bbe3daea 100644 --- a/packages/google-chat.gblib/services/GoogleChatDirectLine.ts +++ b/packages/google-chat.gblib/services/GoogleChatDirectLine.ts @@ -129,6 +129,7 @@ export class GoogleChatDirectLine extends GBService { GBLog.info(`GBGoogleChat: Checking server...`); } + // TODO: Check service.Users.Messages.List("me"). public async receiver(message) { const event = JSON.parse(Buffer.from(message.data, 'binary').toString()); diff --git a/packages/teams.gblib/index.ts b/packages/teams.gblib/index.ts new file mode 100644 index 000000000..7a015c53b --- /dev/null +++ b/packages/teams.gblib/index.ts @@ -0,0 +1,71 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| General Bots Copyright (c) Pragmatismo.io. All rights reserved. | +| Licensed under the AGPL-3.0. | +| | +| According to our dual licensing model, this program can be used either | +| under the terms of the GNU Affero General Public License, version 3, | +| or under a proprietary license. | +| | +| The texts of the GNU Affero General Public License with an additional | +| permission and of our proprietary license can be found at and | +| in the LICENSE file you have received along with this program. | +| | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY, without even the implied warranty of | +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +| GNU Affero General Public License for more details. | +| | +| "General Bots" is a registered trademark of Pragmatismo.io. | +| The licensing of the program under the AGPLv3 does not imply a | +| trademark license. Therefore any rights, title and interest in | +| our trademarks remain entirely with us. | +| | +\*****************************************************************************/ + +/** + * @fileoverview General Bots server core. + */ + +'use strict'; + +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; +import { Sequelize } from 'sequelize-typescript'; + +/** + * Package for whatsapp.gblib + */ +export class GBTeamsPackage implements IGBPackage { + public sysPackages: IGBPackage[]; + + public async loadBot(min: GBMinInstance): Promise { + + } + + public async getDialogs(min: GBMinInstance) { + GBLog.verbose(`getDialogs called.`); + } + public async loadPackage(core: IGBCoreService, sequelize: Sequelize): Promise { + GBLog.verbose(`loadPackage called.`); + } + public async unloadPackage(core: IGBCoreService): Promise { + GBLog.verbose(`unloadPackage called.`); + } + public async unloadBot(min: GBMinInstance): Promise { + GBLog.verbose(`unloadBot called.`); + } + public async onNewSession(min: GBMinInstance, step: GBDialogStep): Promise { + GBLog.verbose(`onNewSession called.`); + } + public async onExchangeData(min: GBMinInstance, kind: string, data: any) { + GBLog.verbose(`onExchangeData called.`); + } + +} diff --git a/packages/teams.gblib/services/TeamsService.ts b/packages/teams.gblib/services/TeamsService.ts new file mode 100644 index 000000000..cffae7bfa --- /dev/null +++ b/packages/teams.gblib/services/TeamsService.ts @@ -0,0 +1,65 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| General Bots Copyright (c) Pragmatismo.io. All rights reserved. | +| Licensed under the AGPL-3.0. | +| | +| According to our dual licensing model, this program can be used either | +| under the terms of the GNU Affero General Public License, version 3, | +| or under a proprietary license. | +| | +| The texts of the GNU Affero General Public License with an additional | +| permission and of our proprietary license can be found at and | +| in the LICENSE file you have received along with this program. | +| | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY, without even the implied warranty of | +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +| GNU Affero General Public License for more details. | +| | +| "General Bots" is a registered trademark of Pragmatismo.io. | +| The licensing of the program under the AGPLv3 does not imply a | +| trademark license. Therefore any rights, title and interest in | +| our trademarks remain entirely with us. | +| | +\*****************************************************************************/ + +import urlJoin = require('url-join'); +import { GBService } from 'botlib'; +const fs = require('fs'); +var AdmZip = require("adm-zip"); + + +/** + * Support for Whatsapp. + */ +export class TeamsService extends GBService { + + public async getAppFile(manifest) + { + var zip = new AdmZip(); + zip.addFile("manifest.json", Buffer.from(manifest, "utf8"), "Built with General Bots™."); + zip.addLocalFile("teams-color.png", null, "color.png"); + zip.addLocalFile("teams-outline.png", null, "outline.png"); + return zip.toBuffer(); + } + + public async getManifest(marketplaceId, botName, botDescription, id, packageName, yourName) { + let content = fs.readFileSync('teams-manifest.json', 'utf8'); + + content = content.replace(/\@\@marketplaceId/gi, marketplaceId); + content = content.replace(/\@\@botName/gi, botName); + content = content.replace(/\@\@botDescription/gi, botDescription); + content = content.replace(/\@\@id/gi, id); + content = content.replace(/\@\@packageName/gi, packageName); + content = content.replace(/\@\@yourName/gi, yourName); + + return content; + } +} diff --git a/packages/teams.gblib/strings.ts b/packages/teams.gblib/strings.ts new file mode 100644 index 000000000..d30f544b1 --- /dev/null +++ b/packages/teams.gblib/strings.ts @@ -0,0 +1,8 @@ +export const Messages = { + 'en-US': { + + }, + 'pt-BR': { + + } +}; diff --git a/teams-color.png b/teams-color.png new file mode 100644 index 000000000..651fe52e9 Binary files /dev/null and b/teams-color.png differ diff --git a/teams-manifest.json b/teams-manifest.json new file mode 100644 index 000000000..439c66a4f --- /dev/null +++ b/teams-manifest.json @@ -0,0 +1,56 @@ +{ + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.9/MicrosoftTeams.schema.json", + "manifestVersion": "1.9", + "version": "1.0.0", + "id": "@@id", + "packageName": "@@packageName", + "developer": { + "name": "@@yourName", + "websiteUrl": "https://pragmatismo.io", + "privacyUrl": "https://generalbots.ai/privacy.html", + "termsOfUseUrl": "https://generalbots.ai/terms.html" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "@@botName", + "full": "@@botName" + }, + "description": { + "short": "@@botName for Microsoft Teams", + "full": "@@botName for Microsoft Teams." + }, + "accentColor": "#7B7B7B", + "staticTabs": [ + { + "entityId": "conversations", + "scopes": [ + "personal" + ] + }, + { + "entityId": "about", + "scopes": [ + "personal" + ] + } + ], + "bots": [ + { + "botId": "@@marketplaceId", + "scopes": [ + "personal", + "team" + ], + "supportsFiles": false, + "isNotificationOnly": false + } + ], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [] +} \ No newline at end of file diff --git a/teams-outline.png b/teams-outline.png new file mode 100644 index 000000000..b1aed48a9 Binary files /dev/null and b/teams-outline.png differ