@botpress/cli 0.8.11 → 0.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/command-implementations/init-command.js +42 -14
  2. package/dist/command-implementations/init-command.js.map +2 -2
  3. package/dist/consts.js +11 -3
  4. package/dist/consts.js.map +2 -2
  5. package/package.json +4 -4
  6. package/templates/echo-bot/package.json +3 -6
  7. package/templates/echo-bot/src/index.ts +1 -1
  8. package/templates/empty-integration/.botpress/implementation/channels/index.ts +0 -3
  9. package/templates/empty-integration/.botpress/implementation/index.ts +1 -1
  10. package/templates/empty-integration/hub.md +1 -0
  11. package/templates/empty-integration/icon.svg +8 -0
  12. package/templates/empty-integration/integration.definition.ts +6 -9
  13. package/templates/empty-integration/package.json +4 -7
  14. package/templates/empty-integration/src/index.ts +7 -55
  15. package/templates/hello-world/.botpress/implementation/actions/helloWorld/index.ts +12 -0
  16. package/templates/{empty-integration/.botpress/implementation/channels/channel/messages/video.ts → hello-world/.botpress/implementation/actions/helloWorld/input.ts} +2 -2
  17. package/templates/{empty-integration/.botpress/implementation/channels/channel/messages/audio.ts → hello-world/.botpress/implementation/actions/helloWorld/output.ts} +2 -2
  18. package/templates/hello-world/.botpress/implementation/actions/index.ts +9 -0
  19. package/templates/hello-world/.botpress/implementation/channels/index.ts +6 -0
  20. package/templates/{empty-integration/.botpress/implementation/channels/channel/messages/markdown.ts → hello-world/.botpress/implementation/configuration/index.ts} +2 -2
  21. package/templates/hello-world/.botpress/implementation/events/index.ts +6 -0
  22. package/templates/hello-world/.botpress/implementation/index.ts +36 -0
  23. package/templates/hello-world/.botpress/implementation/states/index.ts +6 -0
  24. package/templates/hello-world/.botpress/index.ts +2 -0
  25. package/templates/hello-world/.botpress/secrets/index.ts +6 -0
  26. package/templates/hello-world/hub.md +1 -0
  27. package/templates/hello-world/icon.svg +8 -0
  28. package/templates/hello-world/integration.definition.ts +25 -0
  29. package/templates/hello-world/package.json +17 -0
  30. package/templates/hello-world/src/index.ts +33 -0
  31. package/templates/hello-world/tsconfig.json +28 -0
  32. package/templates/webhook-message/.botpress/implementation/actions/index.ts +6 -0
  33. package/templates/webhook-message/.botpress/implementation/channels/index.ts +9 -0
  34. package/templates/webhook-message/.botpress/implementation/channels/webhook/index.ts +12 -0
  35. package/templates/webhook-message/.botpress/implementation/channels/webhook/messages/index.ts +9 -0
  36. package/templates/{empty-integration/.botpress/implementation/channels/channel/messages/choice.ts → webhook-message/.botpress/implementation/configuration/index.ts} +5 -6
  37. package/templates/webhook-message/.botpress/implementation/events/index.ts +6 -0
  38. package/templates/webhook-message/.botpress/implementation/index.ts +36 -0
  39. package/templates/webhook-message/.botpress/implementation/states/index.ts +6 -0
  40. package/templates/webhook-message/.botpress/index.ts +2 -0
  41. package/templates/webhook-message/.botpress/secrets/index.ts +6 -0
  42. package/templates/webhook-message/hub.md +1 -0
  43. package/templates/webhook-message/icon.svg +8 -0
  44. package/templates/webhook-message/integration.definition.ts +36 -0
  45. package/templates/webhook-message/package.json +18 -0
  46. package/templates/webhook-message/src/index.ts +122 -0
  47. package/templates/webhook-message/tsconfig.json +28 -0
  48. package/templates/empty-integration/.botpress/implementation/channels/channel/index.ts +0 -12
  49. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/bloc.ts +0 -57
  50. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/card.ts +0 -17
  51. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/carousel.ts +0 -19
  52. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/dropdown.ts +0 -14
  53. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/file.ts +0 -11
  54. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/image.ts +0 -10
  55. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/index.ts +0 -42
  56. package/templates/empty-integration/.botpress/implementation/channels/channel/messages/location.ts +0 -13
  57. /package/templates/{empty-integration/.botpress/implementation/channels/channel → webhook-message/.botpress/implementation/channels/webhook}/messages/text.ts +0 -0
@@ -46,26 +46,54 @@ class InitCommand extends import_global_command.GlobalCommand {
46
46
  }
47
47
  projectType = promptedType;
48
48
  }
49
- let name = this.argv.name;
50
- if (!name) {
51
- const defaultName = projectType === "bot" ? consts.echoBotDirName : consts.emptyIntegrationDirName;
52
- const promptMessage = `What is the name of your ${projectType}?`;
53
- const promptedName = await this.prompt.text(promptMessage, { initial: defaultName });
54
- if (!promptedName) {
55
- throw new errors.ParamRequiredError("Project Name");
56
- }
57
- name = promptedName;
58
- }
59
49
  const workDir = utils.path.absoluteFrom(utils.path.cwd(), this.argv.workDir);
60
50
  if (projectType === "bot") {
61
- await this._copy({ srcDir: this.globalPaths.abs.echoBotTemplate, destDir: workDir, name });
62
- this.logger.success(`Bot project initialized in ${import_chalk.default.bold(workDir)}`);
51
+ await this._initBot({ workDir });
63
52
  return;
64
53
  }
65
- await this._copy({ srcDir: this.globalPaths.abs.emptyIntegrationTemplate, destDir: workDir, name });
66
- this.logger.success(`Integration project initialized in ${import_chalk.default.bold(this.argv.workDir)}`);
54
+ await this._initIntegration({ workDir });
67
55
  return;
68
56
  }
57
+ _initBot = async (args) => {
58
+ const { workDir } = args;
59
+ const name = await this._getName("bot", consts.echoBotDirName);
60
+ await this._copy({ srcDir: this.globalPaths.abs.echoBotTemplate, destDir: workDir, name });
61
+ this.logger.success(`Bot project initialized in ${import_chalk.default.bold(workDir)}`);
62
+ };
63
+ _initIntegration = async (args) => {
64
+ const { workDir } = args;
65
+ const template = await this.prompt.select("Which template do you want to use?", {
66
+ choices: [
67
+ { title: "Empty Integration", value: consts.emptyIntegrationDirName },
68
+ { title: "Hello World", value: consts.helloWorldIntegrationDirName },
69
+ { title: "Webhook Message", value: consts.webhookMessageIntegrationDirName }
70
+ ],
71
+ default: consts.emptyIntegrationDirName
72
+ });
73
+ let srcDirPath;
74
+ if (template === consts.helloWorldIntegrationDirName) {
75
+ srcDirPath = this.globalPaths.abs.helloWorldIntegrationTemplate;
76
+ } else if (template === consts.webhookMessageIntegrationDirName) {
77
+ srcDirPath = this.globalPaths.abs.webhookMessageIntegrationTemplate;
78
+ } else {
79
+ srcDirPath = this.globalPaths.abs.emptyIntegrationTemplate;
80
+ }
81
+ const name = await this._getName("integration", template ?? consts.emptyIntegrationDirName);
82
+ await this._copy({ srcDir: srcDirPath, destDir: workDir, name });
83
+ this.logger.success(`Integration project initialized in ${import_chalk.default.bold(this.argv.workDir)}`);
84
+ return;
85
+ };
86
+ _getName = async (projectType, defaultName) => {
87
+ if (this.argv.name) {
88
+ return this.argv.name;
89
+ }
90
+ const promptMessage = `What is the name of your ${projectType}?`;
91
+ const promptedName = await this.prompt.text(promptMessage, { initial: defaultName });
92
+ if (!promptedName) {
93
+ throw new errors.ParamRequiredError("Project Name");
94
+ }
95
+ return promptedName;
96
+ };
69
97
  _copy = async (props) => {
70
98
  const { srcDir, destDir, name } = props;
71
99
  const dirName = utils.casing.to.kebabCase(name);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/command-implementations/init-command.ts"],
4
- "sourcesContent": ["import chalk from 'chalk'\nimport * as fs from 'fs'\nimport * as pathlib from 'path'\nimport type commandDefinitions from '../command-definitions'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { GlobalCommand } from './global-command'\n\nexport type InitCommandDefinition = typeof commandDefinitions.init\nexport class InitCommand extends GlobalCommand<InitCommandDefinition> {\n public async run(): Promise<void> {\n let { type: projectType } = this.argv\n\n if (!projectType) {\n const promptedType = await this.prompt.select('What type of project do you wish to initialize?', {\n choices: (['bot', 'integration'] as const).map((t) => ({ title: t, value: t })),\n })\n\n if (!promptedType) {\n throw new errors.ParamRequiredError('Project Type')\n }\n\n projectType = promptedType\n }\n\n let name = this.argv.name\n if (!name) {\n const defaultName = projectType === 'bot' ? consts.echoBotDirName : consts.emptyIntegrationDirName\n const promptMessage = `What is the name of your ${projectType}?`\n const promptedName = await this.prompt.text(promptMessage, { initial: defaultName })\n if (!promptedName) {\n throw new errors.ParamRequiredError('Project Name')\n }\n name = promptedName\n }\n\n const workDir = utils.path.absoluteFrom(utils.path.cwd(), this.argv.workDir)\n\n if (projectType === 'bot') {\n await this._copy({ srcDir: this.globalPaths.abs.echoBotTemplate, destDir: workDir, name })\n this.logger.success(`Bot project initialized in ${chalk.bold(workDir)}`)\n return\n }\n\n await this._copy({ srcDir: this.globalPaths.abs.emptyIntegrationTemplate, destDir: workDir, name })\n this.logger.success(`Integration project initialized in ${chalk.bold(this.argv.workDir)}`)\n return\n }\n\n private _copy = async (props: { srcDir: string; destDir: string; name: string }) => {\n const { srcDir, destDir, name } = props\n\n const dirName = utils.casing.to.kebabCase(name)\n const destination = pathlib.join(destDir, dirName)\n\n const exist = await this._checkIfDestinationExists(destination)\n if (exist) {\n return\n }\n\n await fs.promises.cp(srcDir, destination, { recursive: true })\n\n const pkgJsonPath = pathlib.join(destination, 'package.json')\n const strContent = await fs.promises.readFile(pkgJsonPath, 'utf-8')\n const { name: _, integrationName: __, ...json } = JSON.parse(strContent)\n\n const pkgJsonName = utils.casing.to.snakeCase(name)\n const updatedJson = { name: pkgJsonName, integrationName: name, ...json }\n await fs.promises.writeFile(pkgJsonPath, JSON.stringify(updatedJson, null, 2))\n }\n\n private _checkIfDestinationExists = async (destination: string) => {\n if (fs.existsSync(destination)) {\n const override = await this.prompt.confirm(\n `Directory ${chalk.bold(destination)} already exists. Do you want to overwrite it?`\n )\n if (!override) {\n this.logger.log('Aborting')\n return true\n }\n }\n return false\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAClB,SAAoB;AACpB,cAAyB;AAEzB,aAAwB;AACxB,aAAwB;AACxB,YAAuB;AACvB,4BAA8B;AAGvB,MAAM,oBAAoB,oCAAqC;AAAA,EACpE,MAAa,MAAqB;AAChC,QAAI,EAAE,MAAM,YAAY,IAAI,KAAK;AAEjC,QAAI,CAAC,aAAa;AAChB,YAAM,eAAe,MAAM,KAAK,OAAO,OAAO,mDAAmD;AAAA,QAC/F,SAAU,CAAC,OAAO,aAAa,EAAY,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE;AAAA,MAChF,CAAC;AAED,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,OAAO,mBAAmB,cAAc;AAAA,MACpD;AAEA,oBAAc;AAAA,IAChB;AAEA,QAAI,OAAO,KAAK,KAAK;AACrB,QAAI,CAAC,MAAM;AACT,YAAM,cAAc,gBAAgB,QAAQ,OAAO,iBAAiB,OAAO;AAC3E,YAAM,gBAAgB,4BAA4B;AAClD,YAAM,eAAe,MAAM,KAAK,OAAO,KAAK,eAAe,EAAE,SAAS,YAAY,CAAC;AACnF,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,OAAO,mBAAmB,cAAc;AAAA,MACpD;AACA,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,MAAM,KAAK,aAAa,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO;AAE3E,QAAI,gBAAgB,OAAO;AACzB,YAAM,KAAK,MAAM,EAAE,QAAQ,KAAK,YAAY,IAAI,iBAAiB,SAAS,SAAS,KAAK,CAAC;AACzF,WAAK,OAAO,QAAQ,8BAA8B,aAAAA,QAAM,KAAK,OAAO,GAAG;AACvE;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,EAAE,QAAQ,KAAK,YAAY,IAAI,0BAA0B,SAAS,SAAS,KAAK,CAAC;AAClG,SAAK,OAAO,QAAQ,sCAAsC,aAAAA,QAAM,KAAK,KAAK,KAAK,OAAO,GAAG;AACzF;AAAA,EACF;AAAA,EAEQ,QAAQ,OAAO,UAA6D;AAClF,UAAM,EAAE,QAAQ,SAAS,KAAK,IAAI;AAElC,UAAM,UAAU,MAAM,OAAO,GAAG,UAAU,IAAI;AAC9C,UAAM,cAAc,QAAQ,KAAK,SAAS,OAAO;AAEjD,UAAM,QAAQ,MAAM,KAAK,0BAA0B,WAAW;AAC9D,QAAI,OAAO;AACT;AAAA,IACF;AAEA,UAAM,GAAG,SAAS,GAAG,QAAQ,aAAa,EAAE,WAAW,KAAK,CAAC;AAE7D,UAAM,cAAc,QAAQ,KAAK,aAAa,cAAc;AAC5D,UAAM,aAAa,MAAM,GAAG,SAAS,SAAS,aAAa,OAAO;AAClE,UAAM,EAAE,MAAM,GAAG,iBAAiB,OAAO,KAAK,IAAI,KAAK,MAAM,UAAU;AAEvE,UAAM,cAAc,MAAM,OAAO,GAAG,UAAU,IAAI;AAClD,UAAM,cAAc,EAAE,MAAM,aAAa,iBAAiB,MAAM,GAAG,KAAK;AACxE,UAAM,GAAG,SAAS,UAAU,aAAa,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,EAC/E;AAAA,EAEQ,4BAA4B,OAAO,gBAAwB;AACjE,QAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,YAAM,WAAW,MAAM,KAAK,OAAO;AAAA,QACjC,aAAa,aAAAA,QAAM,KAAK,WAAW;AAAA,MACrC;AACA,UAAI,CAAC,UAAU;AACb,aAAK,OAAO,IAAI,UAAU;AAC1B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;",
4
+ "sourcesContent": ["import chalk from 'chalk'\nimport * as fs from 'fs'\nimport * as pathlib from 'path'\nimport type commandDefinitions from '../command-definitions'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { GlobalCommand } from './global-command'\n\ntype ProjectType = 'bot' | 'integration'\n\nexport type InitCommandDefinition = typeof commandDefinitions.init\nexport class InitCommand extends GlobalCommand<InitCommandDefinition> {\n public async run(): Promise<void> {\n let { type: projectType } = this.argv\n\n if (!projectType) {\n const promptedType = await this.prompt.select('What type of project do you wish to initialize?', {\n choices: (['bot', 'integration'] as const).map((t) => ({ title: t, value: t })),\n })\n\n if (!promptedType) {\n throw new errors.ParamRequiredError('Project Type')\n }\n\n projectType = promptedType\n }\n\n const workDir = utils.path.absoluteFrom(utils.path.cwd(), this.argv.workDir)\n\n if (projectType === 'bot') {\n await this._initBot({ workDir })\n return\n }\n\n await this._initIntegration({ workDir })\n return\n }\n\n private _initBot = async (args: { workDir: string }) => {\n const { workDir } = args\n const name = await this._getName('bot', consts.echoBotDirName)\n await this._copy({ srcDir: this.globalPaths.abs.echoBotTemplate, destDir: workDir, name })\n this.logger.success(`Bot project initialized in ${chalk.bold(workDir)}`)\n }\n\n private _initIntegration = async (args: { workDir: string }) => {\n const { workDir } = args\n\n const template = await this.prompt.select('Which template do you want to use?', {\n choices: [\n { title: 'Empty Integration', value: consts.emptyIntegrationDirName },\n { title: 'Hello World', value: consts.helloWorldIntegrationDirName },\n { title: 'Webhook Message', value: consts.webhookMessageIntegrationDirName },\n ],\n default: consts.emptyIntegrationDirName,\n })\n\n let srcDirPath: string\n if (template === consts.helloWorldIntegrationDirName) {\n srcDirPath = this.globalPaths.abs.helloWorldIntegrationTemplate\n } else if (template === consts.webhookMessageIntegrationDirName) {\n srcDirPath = this.globalPaths.abs.webhookMessageIntegrationTemplate\n } else {\n srcDirPath = this.globalPaths.abs.emptyIntegrationTemplate\n }\n\n const name = await this._getName('integration', template ?? consts.emptyIntegrationDirName)\n\n await this._copy({ srcDir: srcDirPath, destDir: workDir, name })\n this.logger.success(`Integration project initialized in ${chalk.bold(this.argv.workDir)}`)\n return\n }\n\n private _getName = async (projectType: ProjectType, defaultName: string): Promise<string> => {\n if (this.argv.name) {\n return this.argv.name\n }\n const promptMessage = `What is the name of your ${projectType}?`\n const promptedName = await this.prompt.text(promptMessage, { initial: defaultName })\n if (!promptedName) {\n throw new errors.ParamRequiredError('Project Name')\n }\n return promptedName\n }\n\n private _copy = async (props: { srcDir: string; destDir: string; name: string }) => {\n const { srcDir, destDir, name } = props\n\n const dirName = utils.casing.to.kebabCase(name)\n const destination = pathlib.join(destDir, dirName)\n\n const exist = await this._checkIfDestinationExists(destination)\n if (exist) {\n return\n }\n\n await fs.promises.cp(srcDir, destination, { recursive: true })\n\n const pkgJsonPath = pathlib.join(destination, 'package.json')\n const strContent = await fs.promises.readFile(pkgJsonPath, 'utf-8')\n const { name: _, integrationName: __, ...json } = JSON.parse(strContent)\n\n const pkgJsonName = utils.casing.to.snakeCase(name)\n const updatedJson = { name: pkgJsonName, integrationName: name, ...json }\n await fs.promises.writeFile(pkgJsonPath, JSON.stringify(updatedJson, null, 2))\n }\n\n private _checkIfDestinationExists = async (destination: string) => {\n if (fs.existsSync(destination)) {\n const override = await this.prompt.confirm(\n `Directory ${chalk.bold(destination)} already exists. Do you want to overwrite it?`\n )\n if (!override) {\n this.logger.log('Aborting')\n return true\n }\n }\n return false\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["chalk"]
7
7
  }
package/dist/consts.js CHANGED
@@ -36,7 +36,9 @@ __export(consts_exports, {
36
36
  fromCliRootDir: () => fromCliRootDir,
37
37
  fromHomeDir: () => fromHomeDir,
38
38
  fromOutDir: () => fromOutDir,
39
- fromWorkDir: () => fromWorkDir
39
+ fromWorkDir: () => fromWorkDir,
40
+ helloWorldIntegrationDirName: () => helloWorldIntegrationDirName,
41
+ webhookMessageIntegrationDirName: () => webhookMessageIntegrationDirName
40
42
  });
41
43
  module.exports = __toCommonJS(consts_exports);
42
44
  var import_os = __toESM(require("os"));
@@ -51,9 +53,13 @@ const defaultTunnelUrl = "https://tunnel.botpress.cloud";
51
53
  const cliRootDir = import_root.CLI_ROOT_DIR;
52
54
  const echoBotDirName = "echo-bot";
53
55
  const emptyIntegrationDirName = "empty-integration";
56
+ const helloWorldIntegrationDirName = "hello-world";
57
+ const webhookMessageIntegrationDirName = "webhook-message";
54
58
  const fromCliRootDir = {
55
59
  echoBotTemplate: import_path.default.join("templates", echoBotDirName),
56
- emptyIntegrationTemplate: import_path.default.join("templates", emptyIntegrationDirName)
60
+ emptyIntegrationTemplate: import_path.default.join("templates", emptyIntegrationDirName),
61
+ helloWorldIntegrationTemplate: import_path.default.join("templates", helloWorldIntegrationDirName),
62
+ webhookMessageIntegrationTemplate: import_path.default.join("templates", webhookMessageIntegrationDirName)
57
63
  };
58
64
  const fromHomeDir = {
59
65
  globalCacheFile: "global.cache.json"
@@ -83,6 +89,8 @@ const fromOutDir = {
83
89
  fromCliRootDir,
84
90
  fromHomeDir,
85
91
  fromOutDir,
86
- fromWorkDir
92
+ fromWorkDir,
93
+ helloWorldIntegrationDirName,
94
+ webhookMessageIntegrationDirName
87
95
  });
88
96
  //# sourceMappingURL=consts.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/consts.ts"],
4
- "sourcesContent": ["import os from 'os'\nimport pathlib from 'path'\nimport { CLI_ROOT_DIR } from './root'\n\n// configurable\n\nexport const defaultBotpressHome = pathlib.join(os.homedir(), '.botpress')\n\nexport const defaultOutputFolder = '.botpress'\nexport const defaultEntrypoint = pathlib.join('src', 'index.ts')\nexport const defaultBotpressApiUrl = 'https://api.botpress.cloud'\nexport const defaultBotpressAppUrl = 'https://app.botpress.cloud'\nexport const defaultTunnelUrl = 'https://tunnel.botpress.cloud'\n\n// not configurable\n\nexport const cliRootDir = CLI_ROOT_DIR\n\nexport const echoBotDirName = 'echo-bot'\nexport const emptyIntegrationDirName = 'empty-integration'\n\nexport const fromCliRootDir = {\n echoBotTemplate: pathlib.join('templates', echoBotDirName),\n emptyIntegrationTemplate: pathlib.join('templates', emptyIntegrationDirName),\n}\n\nexport const fromHomeDir = {\n globalCacheFile: 'global.cache.json',\n}\n\nexport const fromWorkDir = {\n definition: 'integration.definition.ts',\n}\n\nexport const fromOutDir = {\n distDir: 'dist',\n outFile: pathlib.join('dist', 'index.js'),\n installDir: 'installations',\n implementationDir: 'implementation',\n secretsDir: 'secrets',\n projectCacheFile: 'project.cache.json',\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAoB;AACpB,kBAA6B;AAItB,MAAM,sBAAsB,YAAAA,QAAQ,KAAK,UAAAC,QAAG,QAAQ,GAAG,WAAW;AAElE,MAAM,sBAAsB;AAC5B,MAAM,oBAAoB,YAAAD,QAAQ,KAAK,OAAO,UAAU;AACxD,MAAM,wBAAwB;AAC9B,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AAIzB,MAAM,aAAa;AAEnB,MAAM,iBAAiB;AACvB,MAAM,0BAA0B;AAEhC,MAAM,iBAAiB;AAAA,EAC5B,iBAAiB,YAAAA,QAAQ,KAAK,aAAa,cAAc;AAAA,EACzD,0BAA0B,YAAAA,QAAQ,KAAK,aAAa,uBAAuB;AAC7E;AAEO,MAAM,cAAc;AAAA,EACzB,iBAAiB;AACnB;AAEO,MAAM,cAAc;AAAA,EACzB,YAAY;AACd;AAEO,MAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,SAAS,YAAAA,QAAQ,KAAK,QAAQ,UAAU;AAAA,EACxC,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AACpB;",
4
+ "sourcesContent": ["import os from 'os'\nimport pathlib from 'path'\nimport { CLI_ROOT_DIR } from './root'\n\n// configurable\n\nexport const defaultBotpressHome = pathlib.join(os.homedir(), '.botpress')\n\nexport const defaultOutputFolder = '.botpress'\nexport const defaultEntrypoint = pathlib.join('src', 'index.ts')\nexport const defaultBotpressApiUrl = 'https://api.botpress.cloud'\nexport const defaultBotpressAppUrl = 'https://app.botpress.cloud'\nexport const defaultTunnelUrl = 'https://tunnel.botpress.cloud'\n\n// not configurable\n\nexport const cliRootDir = CLI_ROOT_DIR\n\nexport const echoBotDirName = 'echo-bot'\nexport const emptyIntegrationDirName = 'empty-integration'\nexport const helloWorldIntegrationDirName = 'hello-world'\nexport const webhookMessageIntegrationDirName = 'webhook-message'\n\nexport const fromCliRootDir = {\n echoBotTemplate: pathlib.join('templates', echoBotDirName),\n emptyIntegrationTemplate: pathlib.join('templates', emptyIntegrationDirName),\n helloWorldIntegrationTemplate: pathlib.join('templates', helloWorldIntegrationDirName),\n webhookMessageIntegrationTemplate: pathlib.join('templates', webhookMessageIntegrationDirName),\n}\n\nexport const fromHomeDir = {\n globalCacheFile: 'global.cache.json',\n}\n\nexport const fromWorkDir = {\n definition: 'integration.definition.ts',\n}\n\nexport const fromOutDir = {\n distDir: 'dist',\n outFile: pathlib.join('dist', 'index.js'),\n installDir: 'installations',\n implementationDir: 'implementation',\n secretsDir: 'secrets',\n projectCacheFile: 'project.cache.json',\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAoB;AACpB,kBAA6B;AAItB,MAAM,sBAAsB,YAAAA,QAAQ,KAAK,UAAAC,QAAG,QAAQ,GAAG,WAAW;AAElE,MAAM,sBAAsB;AAC5B,MAAM,oBAAoB,YAAAD,QAAQ,KAAK,OAAO,UAAU;AACxD,MAAM,wBAAwB;AAC9B,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AAIzB,MAAM,aAAa;AAEnB,MAAM,iBAAiB;AACvB,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,mCAAmC;AAEzC,MAAM,iBAAiB;AAAA,EAC5B,iBAAiB,YAAAA,QAAQ,KAAK,aAAa,cAAc;AAAA,EACzD,0BAA0B,YAAAA,QAAQ,KAAK,aAAa,uBAAuB;AAAA,EAC3E,+BAA+B,YAAAA,QAAQ,KAAK,aAAa,4BAA4B;AAAA,EACrF,mCAAmC,YAAAA,QAAQ,KAAK,aAAa,gCAAgC;AAC/F;AAEO,MAAM,cAAc;AAAA,EACzB,iBAAiB;AACnB;AAEO,MAAM,cAAc;AAAA,EACzB,YAAY;AACd;AAEO,MAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,SAAS,YAAAA,QAAQ,KAAK,QAAQ,UAAU;AAAA,EACxC,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AACpB;",
6
6
  "names": ["pathlib", "os"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botpress/cli",
3
- "version": "0.8.11",
3
+ "version": "0.8.13",
4
4
  "description": "Botpress CLI",
5
5
  "scripts": {
6
6
  "build": "pnpm run bundle && pnpm run template:gen",
@@ -8,7 +8,7 @@
8
8
  "start": "node dist/index.js",
9
9
  "type:check": "tsc --noEmit",
10
10
  "bundle": "ts-node -T build.ts",
11
- "template:gen": "pnpm -r --stream -F echo-bot -F empty-integration exec bp gen",
11
+ "template:gen": "pnpm -r --stream -F @bp-templates/* exec bp gen",
12
12
  "e2e:test": "ts-node -T ./e2e",
13
13
  "unit:test": "pnpm vitest --run"
14
14
  },
@@ -20,8 +20,8 @@
20
20
  },
21
21
  "main": "dist/index.js",
22
22
  "dependencies": {
23
- "@botpress/client": "0.16.1",
24
- "@botpress/sdk": "0.8.8",
23
+ "@botpress/client": "0.16.2",
24
+ "@botpress/sdk": "0.8.9",
25
25
  "@bpinternal/const": "^0.0.20",
26
26
  "@bpinternal/tunnel": "^0.1.1",
27
27
  "@bpinternal/yargs-extra": "^0.0.3",
@@ -1,15 +1,12 @@
1
1
  {
2
- "name": "echo-bot",
2
+ "name": "@bp-templates/echo-bot",
3
3
  "scripts": {
4
4
  "type:check": "tsc --noEmit"
5
5
  },
6
- "keywords": [],
7
6
  "private": true,
8
- "author": "",
9
- "license": "MIT",
10
7
  "dependencies": {
11
- "@botpress/client": "0.16.1",
12
- "@botpress/sdk": "0.8.8"
8
+ "@botpress/client": "0.16.2",
9
+ "@botpress/sdk": "0.8.9"
13
10
  },
14
11
  "devDependencies": {
15
12
  "@types/node": "^18.11.17",
@@ -1,5 +1,5 @@
1
1
  import { Bot, z } from '@botpress/sdk'
2
- // import * as botpress from '.botpress' /** uncomment to get generated code */
2
+ // import * as bp from '.botpress' /** uncomment to get generated code */
3
3
 
4
4
  const bot = new Bot({
5
5
  integrations: {},
@@ -1,9 +1,6 @@
1
1
  /* tslint:disable */
2
2
  // This file is generated
3
3
  // Do not edit this file
4
- import * as channel from "./channel/index";
5
- export * as channel from "./channel/index";
6
4
 
7
5
  export type Channels = {
8
- channel: channel.ChannelChannel;
9
6
  }
@@ -20,7 +20,7 @@ export * as states from "./states/index"
20
20
 
21
21
  type TIntegration = {
22
22
  name: "empty-integration"
23
- version: "0.2.0"
23
+ version: "0.0.1"
24
24
  configuration: configuration.Configuration
25
25
  actions: actions.Actions
26
26
  channels: channels.Channels
@@ -0,0 +1 @@
1
+ # Empty Integration
@@ -0,0 +1,8 @@
1
+ <svg width="241" height="241" viewBox="0 0 241 241" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="241" height="241" rx="34" fill="#AAAAAA"/>
3
+ <path d="M102 112L130.5 95.5L127.5 86L98 103L102 112Z" fill="white"/>
4
+ <path d="M133 157.5L98.5 137.5L101 128.5L136 148.5L133 157.5Z" fill="white"/>
5
+ <path d="M172.014 179.812L155.014 189.672C152.532 191.112 149.468 191.112 146.986 189.672L129.986 179.812C127.519 178.381 126 175.744 126 172.892V152.608C126 149.756 127.519 147.119 129.986 145.688L146.986 135.828C149.468 134.388 152.532 134.388 155.014 135.828L172.014 145.688C174.481 147.119 176 149.756 176 152.608V172.892C176 175.744 174.481 178.381 172.014 179.812Z" fill="white"/>
6
+ <path d="M103 110.108V130.392C103 133.244 101.481 135.881 99.0137 137.312L98.5698 137.57L83.5 129L92 141.38L82.0137 147.172C79.5316 148.612 76.4684 148.612 73.9863 147.172L56.9863 137.312C54.5188 135.881 53 133.244 53 130.392V110.108C53 107.256 54.5188 104.619 56.9863 103.188L73.9863 93.328C76.4684 91.8883 79.5316 91.8883 82.0137 93.328L99.0137 103.188C101.481 104.619 103 107.256 103 110.108Z" fill="white"/>
7
+ <path d="M172.014 95.312L155.014 105.172C152.532 106.612 149.468 106.612 146.986 105.172L137.789 99.8376L147.5 85.5L130.425 95.5666L129.986 95.312C127.519 93.8809 126 91.2442 126 88.3918V68.1082C126 65.2558 127.519 62.6191 129.986 61.188L146.986 51.328C149.468 49.8883 152.532 49.8883 155.014 51.328L172.014 61.188C174.481 62.6191 176 65.2558 176 68.1082V88.3918C176 91.2442 174.481 93.8809 172.014 95.312Z" fill="white"/>
8
+ </svg>
@@ -1,12 +1,9 @@
1
- import { IntegrationDefinition, messages } from '@botpress/sdk'
2
- import { name, integrationName } from './package.json'
1
+ import { IntegrationDefinition } from '@botpress/sdk'
2
+ import { integrationName } from './package.json'
3
3
 
4
4
  export default new IntegrationDefinition({
5
- name: integrationName ?? name,
6
- version: '0.2.0',
7
- channels: {
8
- channel: {
9
- messages: { ...messages.defaults },
10
- },
11
- },
5
+ name: integrationName,
6
+ version: '0.0.1',
7
+ readme: 'hub.md',
8
+ icon: 'icon.svg',
12
9
  })
@@ -1,16 +1,13 @@
1
1
  {
2
- "name": "empty-integration",
3
- "integrationName": null,
2
+ "name": "@bp-templates/empty-integration",
3
+ "integrationName": "empty-integration",
4
4
  "scripts": {
5
5
  "type:check": "tsc --noEmit"
6
6
  },
7
- "keywords": [],
8
7
  "private": true,
9
- "author": "",
10
- "license": "MIT",
11
8
  "dependencies": {
12
- "@botpress/client": "0.16.1",
13
- "@botpress/sdk": "0.8.8"
9
+ "@botpress/client": "0.16.2",
10
+ "@botpress/sdk": "0.8.9"
14
11
  },
15
12
  "devDependencies": {
16
13
  "@types/node": "^18.11.17",
@@ -1,70 +1,22 @@
1
- import * as botpress from '.botpress'
1
+ import * as sdk from '@botpress/sdk'
2
+ import * as bp from '.botpress'
2
3
 
3
- console.info('starting integration')
4
-
5
- class NotImplementedError extends Error {
6
- constructor() {
7
- super('Not implemented')
8
- }
9
- }
10
-
11
- export default new botpress.Integration({
4
+ export default new bp.Integration({
12
5
  register: async () => {
13
6
  /**
14
7
  * This is called when a bot installs the integration.
15
8
  * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
16
9
  */
10
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
17
11
  },
18
12
  unregister: async () => {
19
13
  /**
20
14
  * This is called when a bot removes the integration.
21
15
  * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
22
16
  */
17
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
23
18
  },
24
19
  actions: {},
25
- channels: {
26
- channel: {
27
- messages: {
28
- text: async () => {
29
- throw new NotImplementedError()
30
- },
31
- image: async () => {
32
- throw new NotImplementedError()
33
- },
34
- markdown: async () => {
35
- throw new NotImplementedError()
36
- },
37
- audio: async () => {
38
- throw new NotImplementedError()
39
- },
40
- video: async () => {
41
- throw new NotImplementedError()
42
- },
43
- file: async () => {
44
- throw new NotImplementedError()
45
- },
46
- location: async () => {
47
- throw new NotImplementedError()
48
- },
49
- carousel: async () => {
50
- throw new NotImplementedError()
51
- },
52
- card: async () => {
53
- throw new NotImplementedError()
54
- },
55
- choice: async () => {
56
- throw new NotImplementedError()
57
- },
58
- dropdown: async () => {
59
- throw new NotImplementedError()
60
- },
61
- bloc: async () => {
62
- throw new NotImplementedError()
63
- },
64
- },
65
- },
66
- },
67
- handler: async () => {
68
- throw new NotImplementedError()
69
- },
20
+ channels: {},
21
+ handler: async () => {},
70
22
  })
@@ -0,0 +1,12 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ import * as input from "./input";
5
+ export * as input from "./input";
6
+ import * as output from "./output";
7
+ export * as output from "./output";
8
+
9
+ export type ActionHelloWorld = {
10
+ input: input.Input;
11
+ output: output.Output;
12
+ }
@@ -5,6 +5,6 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export interface Video {
9
- videoUrl: string;
8
+ export interface Input {
9
+ name?: string;
10
10
  }
@@ -5,6 +5,6 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export interface Audio {
9
- audioUrl: string;
8
+ export interface Output {
9
+ message: string;
10
10
  }
@@ -0,0 +1,9 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ import * as helloWorld from "./helloWorld/index";
5
+ export * as helloWorld from "./helloWorld/index";
6
+
7
+ export type Actions = {
8
+ helloWorld: helloWorld.ActionHelloWorld;
9
+ }
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type Channels = {
6
+ }
@@ -5,6 +5,6 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export interface Markdown {
9
- markdown: string;
8
+ export interface Configuration {
9
+ [k: string]: any;
10
10
  }
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type Events = {
6
+ }
@@ -0,0 +1,36 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ /* tslint:disable */
5
+ // This file is generated
6
+ // Do not edit this file
7
+
8
+ import * as sdk from "@botpress/sdk"
9
+
10
+ import type * as configuration from "./configuration/index"
11
+ import type * as actions from "./actions/index"
12
+ import type * as channels from "./channels/index"
13
+ import type * as events from "./events/index"
14
+ import type * as states from "./states/index"
15
+ export * as configuration from "./configuration/index"
16
+ export * as actions from "./actions/index"
17
+ export * as channels from "./channels/index"
18
+ export * as events from "./events/index"
19
+ export * as states from "./states/index"
20
+
21
+ type TIntegration = {
22
+ name: "hello-world"
23
+ version: "0.0.1"
24
+ configuration: configuration.Configuration
25
+ actions: actions.Actions
26
+ channels: channels.Channels
27
+ events: events.Events
28
+ states: states.States
29
+ user: { "tags": {}, "creation": { "enabled": false, "requiredTags": [] } }
30
+ }
31
+
32
+ export type IntegrationProps = sdk.IntegrationProps<TIntegration>
33
+
34
+ export class Integration extends sdk.Integration<TIntegration> {}
35
+
36
+ export type Client = sdk.IntegrationSpecificClient<TIntegration>
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type States = {
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from './implementation'
2
+ export * from './secrets'
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ class Secrets {
5
+ }
6
+ export const secrets = new Secrets()
@@ -0,0 +1 @@
1
+ # Hello World
@@ -0,0 +1,8 @@
1
+ <svg width="241" height="241" viewBox="0 0 241 241" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="241" height="241" rx="34" fill="#AAAAAA"/>
3
+ <path d="M102 112L130.5 95.5L127.5 86L98 103L102 112Z" fill="white"/>
4
+ <path d="M133 157.5L98.5 137.5L101 128.5L136 148.5L133 157.5Z" fill="white"/>
5
+ <path d="M172.014 179.812L155.014 189.672C152.532 191.112 149.468 191.112 146.986 189.672L129.986 179.812C127.519 178.381 126 175.744 126 172.892V152.608C126 149.756 127.519 147.119 129.986 145.688L146.986 135.828C149.468 134.388 152.532 134.388 155.014 135.828L172.014 145.688C174.481 147.119 176 149.756 176 152.608V172.892C176 175.744 174.481 178.381 172.014 179.812Z" fill="white"/>
6
+ <path d="M103 110.108V130.392C103 133.244 101.481 135.881 99.0137 137.312L98.5698 137.57L83.5 129L92 141.38L82.0137 147.172C79.5316 148.612 76.4684 148.612 73.9863 147.172L56.9863 137.312C54.5188 135.881 53 133.244 53 130.392V110.108C53 107.256 54.5188 104.619 56.9863 103.188L73.9863 93.328C76.4684 91.8883 79.5316 91.8883 82.0137 93.328L99.0137 103.188C101.481 104.619 103 107.256 103 110.108Z" fill="white"/>
7
+ <path d="M172.014 95.312L155.014 105.172C152.532 106.612 149.468 106.612 146.986 105.172L137.789 99.8376L147.5 85.5L130.425 95.5666L129.986 95.312C127.519 93.8809 126 91.2442 126 88.3918V68.1082C126 65.2558 127.519 62.6191 129.986 61.188L146.986 51.328C149.468 49.8883 152.532 49.8883 155.014 51.328L172.014 61.188C174.481 62.6191 176 65.2558 176 68.1082V88.3918C176 91.2442 174.481 93.8809 172.014 95.312Z" fill="white"/>
8
+ </svg>
@@ -0,0 +1,25 @@
1
+ import { z, IntegrationDefinition } from '@botpress/sdk'
2
+ import { integrationName } from './package.json'
3
+
4
+ export default new IntegrationDefinition({
5
+ name: integrationName,
6
+ version: '0.0.1',
7
+ readme: 'hub.md',
8
+ icon: 'icon.svg',
9
+ actions: {
10
+ helloWorld: {
11
+ title: 'Hello World',
12
+ description: 'A simple hello world action',
13
+ input: {
14
+ schema: z.object({
15
+ name: z.string().optional(),
16
+ }),
17
+ },
18
+ output: {
19
+ schema: z.object({
20
+ message: z.string(),
21
+ }),
22
+ },
23
+ },
24
+ },
25
+ })
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@bp-templates/hello-world",
3
+ "integrationName": "hello-world",
4
+ "scripts": {
5
+ "type:check": "tsc --noEmit"
6
+ },
7
+ "private": true,
8
+ "dependencies": {
9
+ "@botpress/client": "0.16.2",
10
+ "@botpress/sdk": "0.8.9"
11
+ },
12
+ "devDependencies": {
13
+ "@types/node": "^18.11.17",
14
+ "ts-node": "^10.9.1",
15
+ "typescript": "^4.9.4"
16
+ }
17
+ }
@@ -0,0 +1,33 @@
1
+ import * as sdk from '@botpress/sdk'
2
+ import * as bp from '.botpress'
3
+
4
+ export default new bp.Integration({
5
+ register: async () => {
6
+ /**
7
+ * This is called when a bot installs the integration.
8
+ * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
9
+ */
10
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
11
+ },
12
+ unregister: async () => {
13
+ /**
14
+ * This is called when a bot removes the integration.
15
+ * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
16
+ */
17
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
18
+ },
19
+ actions: {
20
+ helloWorld: async (props) => {
21
+ /**
22
+ * This is called when a bot calls the action `helloWorld`.
23
+ */
24
+ props.logger.forBot().info('Hello World!') // this log will be visible by the bots that use this integration
25
+
26
+ let { name } = props.input
27
+ name = name || 'World'
28
+ return { message: `Hello "${name}"! Nice to meet you ;)` }
29
+ },
30
+ },
31
+ channels: {},
32
+ handler: async () => {},
33
+ })
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["es2022"],
4
+ "module": "commonjs",
5
+ "strict": true,
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "moduleResolution": "node",
10
+ "allowUnusedLabels": false,
11
+ "allowUnreachableCode": false,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noImplicitOverride": true,
14
+ "noImplicitReturns": true,
15
+ "noUncheckedIndexedAccess": true,
16
+ "noUnusedParameters": true,
17
+ "target": "es2017",
18
+ "baseUrl": ".",
19
+ "outDir": "dist",
20
+ "checkJs": false,
21
+ "incremental": true,
22
+ "exactOptionalPropertyTypes": false,
23
+ "resolveJsonModule": true,
24
+ "noPropertyAccessFromIndexSignature": false,
25
+ "noUnusedLocals": false
26
+ },
27
+ "include": [".botpress/**/*", "src/**/*", "./*.ts", "./*.json"]
28
+ }
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type Actions = {
6
+ }
@@ -0,0 +1,9 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ import * as webhook from "./webhook/index";
5
+ export * as webhook from "./webhook/index";
6
+
7
+ export type Channels = {
8
+ webhook: webhook.ChannelWebhook;
9
+ }
@@ -0,0 +1,12 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ import { Messages } from './messages/index'
6
+ export * from './messages/index'
7
+
8
+ export type ChannelWebhook = {
9
+ messages: Messages
10
+ message: { "tags": {} }
11
+ conversation: { "tags": { "id": { "title": "Conversation ID", "description": "The ID of the conversation" } }, "creation": { "enabled": false, "requiredTags": [] } }
12
+ }
@@ -0,0 +1,9 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ import * as text from "./text";
5
+ export * as text from "./text";
6
+
7
+ export type Messages = {
8
+ text: text.Text;
9
+ }
@@ -5,10 +5,9 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export interface Choice {
9
- text: string;
10
- options: {
11
- label: string;
12
- value: string;
13
- }[];
8
+ export interface Configuration {
9
+ /**
10
+ * The url to post the bot answers to.
11
+ */
12
+ webhookUrl: string;
14
13
  }
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type Events = {
6
+ }
@@ -0,0 +1,36 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ /* tslint:disable */
5
+ // This file is generated
6
+ // Do not edit this file
7
+
8
+ import * as sdk from "@botpress/sdk"
9
+
10
+ import type * as configuration from "./configuration/index"
11
+ import type * as actions from "./actions/index"
12
+ import type * as channels from "./channels/index"
13
+ import type * as events from "./events/index"
14
+ import type * as states from "./states/index"
15
+ export * as configuration from "./configuration/index"
16
+ export * as actions from "./actions/index"
17
+ export * as channels from "./channels/index"
18
+ export * as events from "./events/index"
19
+ export * as states from "./states/index"
20
+
21
+ type TIntegration = {
22
+ name: "webhook-message"
23
+ version: "0.0.1"
24
+ configuration: configuration.Configuration
25
+ actions: actions.Actions
26
+ channels: channels.Channels
27
+ events: events.Events
28
+ states: states.States
29
+ user: { "tags": { "id": { "title": "User ID", "description": "The ID of the user" } }, "creation": { "enabled": false, "requiredTags": [] } }
30
+ }
31
+
32
+ export type IntegrationProps = sdk.IntegrationProps<TIntegration>
33
+
34
+ export class Integration extends sdk.Integration<TIntegration> {}
35
+
36
+ export type Client = sdk.IntegrationSpecificClient<TIntegration>
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+
5
+ export type States = {
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from './implementation'
2
+ export * from './secrets'
@@ -0,0 +1,6 @@
1
+ /* tslint:disable */
2
+ // This file is generated
3
+ // Do not edit this file
4
+ class Secrets {
5
+ }
6
+ export const secrets = new Secrets()
@@ -0,0 +1 @@
1
+ # Webhook Message
@@ -0,0 +1,8 @@
1
+ <svg width="241" height="241" viewBox="0 0 241 241" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="241" height="241" rx="34" fill="#AAAAAA"/>
3
+ <path d="M102 112L130.5 95.5L127.5 86L98 103L102 112Z" fill="white"/>
4
+ <path d="M133 157.5L98.5 137.5L101 128.5L136 148.5L133 157.5Z" fill="white"/>
5
+ <path d="M172.014 179.812L155.014 189.672C152.532 191.112 149.468 191.112 146.986 189.672L129.986 179.812C127.519 178.381 126 175.744 126 172.892V152.608C126 149.756 127.519 147.119 129.986 145.688L146.986 135.828C149.468 134.388 152.532 134.388 155.014 135.828L172.014 145.688C174.481 147.119 176 149.756 176 152.608V172.892C176 175.744 174.481 178.381 172.014 179.812Z" fill="white"/>
6
+ <path d="M103 110.108V130.392C103 133.244 101.481 135.881 99.0137 137.312L98.5698 137.57L83.5 129L92 141.38L82.0137 147.172C79.5316 148.612 76.4684 148.612 73.9863 147.172L56.9863 137.312C54.5188 135.881 53 133.244 53 130.392V110.108C53 107.256 54.5188 104.619 56.9863 103.188L73.9863 93.328C76.4684 91.8883 79.5316 91.8883 82.0137 93.328L99.0137 103.188C101.481 104.619 103 107.256 103 110.108Z" fill="white"/>
7
+ <path d="M172.014 95.312L155.014 105.172C152.532 106.612 149.468 106.612 146.986 105.172L137.789 99.8376L147.5 85.5L130.425 95.5666L129.986 95.312C127.519 93.8809 126 91.2442 126 88.3918V68.1082C126 65.2558 127.519 62.6191 129.986 61.188L146.986 51.328C149.468 49.8883 152.532 49.8883 155.014 51.328L172.014 61.188C174.481 62.6191 176 65.2558 176 68.1082V88.3918C176 91.2442 174.481 93.8809 172.014 95.312Z" fill="white"/>
8
+ </svg>
@@ -0,0 +1,36 @@
1
+ import { z, IntegrationDefinition } from '@botpress/sdk'
2
+ import { integrationName } from './package.json'
3
+
4
+ export default new IntegrationDefinition({
5
+ name: integrationName,
6
+ version: '0.0.1',
7
+ readme: 'hub.md',
8
+ icon: 'icon.svg',
9
+ configuration: {
10
+ schema: z.object({
11
+ webhookUrl: z.string().describe('The url to post the bot answers to.'),
12
+ }),
13
+ },
14
+ channels: {
15
+ webhook: {
16
+ conversation: {
17
+ tags: {
18
+ id: { title: 'Conversation ID', description: 'The ID of the conversation' },
19
+ },
20
+ },
21
+ messages: {
22
+ // this channel only supports text messages
23
+ text: {
24
+ schema: z.object({
25
+ text: z.string(),
26
+ }),
27
+ },
28
+ },
29
+ },
30
+ },
31
+ user: {
32
+ tags: {
33
+ id: { title: 'User ID', description: 'The ID of the user' },
34
+ },
35
+ },
36
+ })
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@bp-templates/webhook-message",
3
+ "integrationName": "webhook-message",
4
+ "scripts": {
5
+ "type:check": "tsc --noEmit"
6
+ },
7
+ "private": true,
8
+ "dependencies": {
9
+ "@botpress/client": "0.16.2",
10
+ "@botpress/sdk": "0.8.9",
11
+ "axios": "^1.6.8"
12
+ },
13
+ "devDependencies": {
14
+ "@types/node": "^18.11.17",
15
+ "ts-node": "^10.9.1",
16
+ "typescript": "^4.9.4"
17
+ }
18
+ }
@@ -0,0 +1,122 @@
1
+ import * as sdk from '@botpress/sdk'
2
+ import axios from 'axios'
3
+ import * as bp from '.botpress'
4
+
5
+ const reqBodySchema = sdk.z.object({
6
+ userId: sdk.z.string(),
7
+ conversationId: sdk.z.string(),
8
+ text: sdk.z.string(),
9
+ })
10
+
11
+ export default new bp.Integration({
12
+ register: async () => {
13
+ /**
14
+ * This is called when a bot installs the integration.
15
+ * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
16
+ */
17
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
18
+ },
19
+ unregister: async () => {
20
+ /**
21
+ * This is called when a bot removes the integration.
22
+ * You should use this handler to instanciate ressources in the external service and ensure that the configuration is valid.
23
+ */
24
+ throw new sdk.RuntimeError('Invalid configuration') // replace this with your own validation logic
25
+ },
26
+ actions: {},
27
+ channels: {
28
+ webhook: {
29
+ messages: {
30
+ text: async (props) => {
31
+ /**
32
+ * This is the outgoing message handler. It is called when a bot sends a message to the user.
33
+ */
34
+ const {
35
+ ctx: {
36
+ configuration: { webhookUrl },
37
+ },
38
+ conversation: { id: conversationId },
39
+ user: { id: userId },
40
+ payload: { text },
41
+ } = props
42
+
43
+ const requestBody = {
44
+ userId,
45
+ conversationId,
46
+ text,
47
+ }
48
+
49
+ await axios.post(webhookUrl, requestBody)
50
+ },
51
+ },
52
+ },
53
+ },
54
+ handler: async (props) => {
55
+ /**
56
+ * This is the incoming request handler. It is called by the external service you are integrating with.
57
+ */
58
+ const {
59
+ client,
60
+ req: { body },
61
+ } = props
62
+
63
+ if (!body) {
64
+ return {
65
+ status: 400,
66
+ body: JSON.stringify({ error: 'No body' }),
67
+ }
68
+ }
69
+
70
+ let parsedBody: unknown
71
+ try {
72
+ parsedBody = JSON.parse(body)
73
+ } catch (thrown) {
74
+ return {
75
+ status: 400,
76
+ body: JSON.stringify({ error: 'Invalid JSON Body' }),
77
+ }
78
+ }
79
+
80
+ const parseResult = reqBodySchema.safeParse(parsedBody)
81
+ if (!parseResult.success) {
82
+ return {
83
+ status: 400,
84
+ body: JSON.stringify({ error: 'Invalid body' }),
85
+ }
86
+ }
87
+
88
+ const { userId, conversationId, text } = parseResult.data
89
+
90
+ const { conversation } = await client.getOrCreateConversation({
91
+ channel: 'webhook',
92
+ tags: {
93
+ id: conversationId,
94
+ },
95
+ })
96
+
97
+ const { user } = await client.getOrCreateUser({
98
+ tags: {
99
+ id: userId,
100
+ },
101
+ })
102
+
103
+ const { message } = await client.createMessage({
104
+ type: 'text',
105
+ conversationId: conversation.id,
106
+ userId: user.id,
107
+ payload: {
108
+ text,
109
+ },
110
+ tags: {},
111
+ })
112
+
113
+ const response = {
114
+ message,
115
+ }
116
+
117
+ return {
118
+ status: 200,
119
+ body: JSON.stringify(response),
120
+ }
121
+ },
122
+ })
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["es2022"],
4
+ "module": "commonjs",
5
+ "strict": true,
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "moduleResolution": "node",
10
+ "allowUnusedLabels": false,
11
+ "allowUnreachableCode": false,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noImplicitOverride": true,
14
+ "noImplicitReturns": true,
15
+ "noUncheckedIndexedAccess": true,
16
+ "noUnusedParameters": true,
17
+ "target": "es2017",
18
+ "baseUrl": ".",
19
+ "outDir": "dist",
20
+ "checkJs": false,
21
+ "incremental": true,
22
+ "exactOptionalPropertyTypes": false,
23
+ "resolveJsonModule": true,
24
+ "noPropertyAccessFromIndexSignature": false,
25
+ "noUnusedLocals": false
26
+ },
27
+ "include": [".botpress/**/*", "src/**/*", "./*.ts", "./*.json"]
28
+ }
@@ -1,12 +0,0 @@
1
- /* tslint:disable */
2
- // This file is generated
3
- // Do not edit this file
4
-
5
- import { Messages } from './messages/index'
6
- export * from './messages/index'
7
-
8
- export type ChannelChannel = {
9
- messages: Messages
10
- message: { "tags": {} }
11
- conversation: { "tags": {}, "creation": { "enabled": false, "requiredTags": [] } }
12
- }
@@ -1,57 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Bloc {
9
- items: (
10
- | {
11
- type: "text";
12
- payload: {
13
- text: string;
14
- };
15
- }
16
- | {
17
- type: "markdown";
18
- payload: {
19
- markdown: string;
20
- };
21
- }
22
- | {
23
- type: "image";
24
- payload: {
25
- imageUrl: string;
26
- };
27
- }
28
- | {
29
- type: "audio";
30
- payload: {
31
- audioUrl: string;
32
- };
33
- }
34
- | {
35
- type: "video";
36
- payload: {
37
- videoUrl: string;
38
- };
39
- }
40
- | {
41
- type: "file";
42
- payload: {
43
- fileUrl: string;
44
- title?: string;
45
- };
46
- }
47
- | {
48
- type: "location";
49
- payload: {
50
- latitude: number;
51
- longitude: number;
52
- address?: string;
53
- title?: string;
54
- };
55
- }
56
- )[];
57
- }
@@ -1,17 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Card {
9
- title: string;
10
- subtitle?: string;
11
- imageUrl?: string;
12
- actions: {
13
- action: "postback" | "url" | "say";
14
- label: string;
15
- value: string;
16
- }[];
17
- }
@@ -1,19 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Carousel {
9
- items: {
10
- title: string;
11
- subtitle?: string;
12
- imageUrl?: string;
13
- actions: {
14
- action: "postback" | "url" | "say";
15
- label: string;
16
- value: string;
17
- }[];
18
- }[];
19
- }
@@ -1,14 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Dropdown {
9
- text: string;
10
- options: {
11
- label: string;
12
- value: string;
13
- }[];
14
- }
@@ -1,11 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface File {
9
- fileUrl: string;
10
- title?: string;
11
- }
@@ -1,10 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Image {
9
- imageUrl: string;
10
- }
@@ -1,42 +0,0 @@
1
- /* tslint:disable */
2
- // This file is generated
3
- // Do not edit this file
4
- import * as text from "./text";
5
- export * as text from "./text";
6
- import * as markdown from "./markdown";
7
- export * as markdown from "./markdown";
8
- import * as image from "./image";
9
- export * as image from "./image";
10
- import * as audio from "./audio";
11
- export * as audio from "./audio";
12
- import * as video from "./video";
13
- export * as video from "./video";
14
- import * as file from "./file";
15
- export * as file from "./file";
16
- import * as location from "./location";
17
- export * as location from "./location";
18
- import * as carousel from "./carousel";
19
- export * as carousel from "./carousel";
20
- import * as card from "./card";
21
- export * as card from "./card";
22
- import * as dropdown from "./dropdown";
23
- export * as dropdown from "./dropdown";
24
- import * as choice from "./choice";
25
- export * as choice from "./choice";
26
- import * as bloc from "./bloc";
27
- export * as bloc from "./bloc";
28
-
29
- export type Messages = {
30
- text: text.Text;
31
- markdown: markdown.Markdown;
32
- image: image.Image;
33
- audio: audio.Audio;
34
- video: video.Video;
35
- file: file.File;
36
- location: location.Location;
37
- carousel: carousel.Carousel;
38
- card: card.Card;
39
- dropdown: dropdown.Dropdown;
40
- choice: choice.Choice;
41
- bloc: bloc.Bloc;
42
- }
@@ -1,13 +0,0 @@
1
- /* tslint:disable */
2
- /**
3
- * This file was automatically generated by json-schema-to-typescript.
4
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
- * and run json-schema-to-typescript to regenerate this file.
6
- */
7
-
8
- export interface Location {
9
- latitude: number;
10
- longitude: number;
11
- address?: string;
12
- title?: string;
13
- }