-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(channels): channels package (#270)
* feat(channels): conversation.started * fix * feat(channels): channels package * fix * config file * schwag * more schwag * twilio * twilio validation * smooch * change config * abstract * abstract telegram * abstract twilio * abstract app * fix * teams * fix * bring changes * bring changes * bring changes * add base renderers * refact streams * telegram all content types * abstract * twilio all content types * slack all content types * vonage all content types * messenger all content * teams all content * smooch all content * destroy * initialize * bring changes * chore(channels): delete channels (#271) * delete channel code * chore(channels): use channels from channels package (#272) * use telegram from channel package * use package twilio * use teams * use smooch * example change * config change * slack * messenger * vonage * integrate other channels * telegram + * fix tests * fix docker * initialize * stop when server closes * dispatch stop * webhookRouter * ChannelTemplate * prettier * fix * any -> void * remove || '*' in server * remove ChannelStreamRenderers * initialize messenger * messenger map scope * fix * put back twilio testing * vonage receive content types * restore index responses * fix * fix * logger * logger * printWebhook * kvs interface * fix
- Loading branch information
1 parent
b05bb69
commit 2dadfee
Showing
194 changed files
with
2,242 additions
and
2,049 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import clc from 'cli-color' | ||
import { Router } from 'express' | ||
import { Channel } from '../src/base/channel' | ||
import { MessengerChannel } from '../src/messenger/channel' | ||
import { SlackChannel } from '../src/slack/channel' | ||
import { SmoochChannel } from '../src/smooch/channel' | ||
import { TeamsChannel } from '../src/teams/channel' | ||
import { TelegramChannel } from '../src/telegram/channel' | ||
import { TwilioChannel } from '../src/twilio/channel' | ||
import { VonageChannel } from '../src/vonage/channel' | ||
import payloads from './payloads.json' | ||
|
||
export class App { | ||
constructor(private router: Router, private config: any) {} | ||
|
||
async setup() { | ||
await this.setupChannel('telegram', new TelegramChannel()) | ||
await this.setupChannel('twilio', new TwilioChannel()) | ||
await this.setupChannel('smooch', new SmoochChannel()) | ||
await this.setupChannel('teams', new TeamsChannel()) | ||
await this.setupChannel('slack', new SlackChannel()) | ||
await this.setupChannel('messenger', new MessengerChannel()) | ||
await this.setupChannel('vonage', new VonageChannel()) | ||
} | ||
|
||
async setupChannel(name: string, channel: Channel) { | ||
await channel.setup(this.router) | ||
|
||
channel.on('message', async ({ scope, endpoint, content }) => { | ||
this.log('message', name, scope, { endpoint, content }) | ||
|
||
const respond = async () => { | ||
try { | ||
for (const payload of payloads) { | ||
await channel.send(scope, endpoint, payload) | ||
} | ||
} catch (e) { | ||
console.error('Error occurred sending message', e) | ||
} | ||
} | ||
|
||
void respond() | ||
}) | ||
|
||
channel.makeUrl(async (scope: string) => { | ||
return `${this.config.externalUrl}/webhooks/${scope}/${channel.meta.name}` | ||
}) | ||
|
||
for (const [key, val] of Object.entries<any>(this.config.scopes)) { | ||
if (val[name]) { | ||
await channel.start(key, val[name]) | ||
this.log('conf', name, key, val[name]) | ||
} | ||
} | ||
} | ||
|
||
private log(type: string, channel: string, context: string, obj: any) { | ||
console.info(clc.blue(type), clc.bold(channel), context, obj) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"externalUrl": "", | ||
"scopes": { | ||
"CLIENT_ID": { | ||
"telegram": { | ||
"botToken": "" | ||
}, | ||
"twilio": { | ||
"accountSID": "", | ||
"authToken": "" | ||
}, | ||
"smooch": { | ||
"keyId": "", | ||
"secret": "" | ||
}, | ||
"teams": { | ||
"appId": "", | ||
"appPassword": "" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import clc from 'cli-color' | ||
import express, { Router } from 'express' | ||
import { App } from './app' | ||
import config from './config.json' | ||
|
||
const setup = async () => { | ||
console.info('====================\n' + ` ${clc.magentaBright('channels example')}\n` + '====================') | ||
|
||
const exp = express() | ||
exp.get('/', (req, res) => { | ||
res.sendStatus(200) | ||
}) | ||
|
||
const router = Router() | ||
const app = new App(router, config) | ||
await app.setup() | ||
|
||
const port = 3100 | ||
exp.use('/webhooks', router) | ||
exp.listen(port) | ||
|
||
console.info(`${clc.cyan('url')} ${config.externalUrl}`) | ||
console.info(`${clc.cyan('port')} ${port}`) | ||
} | ||
|
||
void setup() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
[ | ||
{ "type": "text", "text": "yoyo", "typing": true }, | ||
{ | ||
"type": "image", | ||
"title": "ducky duck duck", | ||
"image": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Mallard2.jpg", | ||
"typing": true | ||
}, | ||
{ | ||
"type": "card", | ||
"title": "A banana card", | ||
"subtitle": "This is a banana", | ||
"image": "https://upload.wikimedia.org/wikipedia/commons/8/8a/Banana-Single.jpg", | ||
"actions": [ | ||
{ | ||
"action": "Open URL", | ||
"title": "Learn more", | ||
"url": "https://en.wikipedia.org/wiki/Banana" | ||
}, | ||
{ | ||
"action": "Say something", | ||
"title": "Say Banana!", | ||
"text": "Banana!!!" | ||
}, | ||
{ | ||
"action": "Postback", | ||
"title": "Post banana", | ||
"payload": "BANANA" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "carousel", | ||
"items": [ | ||
{ | ||
"title": "Dinosaurs", | ||
"subtitle": "A bunch of dinosaurs", | ||
"image": "https://upload.wikimedia.org/wikipedia/commons/2/28/Macronaria_scrubbed_enh.jpg", | ||
"actions": [ | ||
{ | ||
"action": "Open URL", | ||
"title": "Learn more", | ||
"url": "https://en.wikipedia.org/wiki/Dinosaur" | ||
}, | ||
{ | ||
"action": "Postback", | ||
"title": "Cool", | ||
"payload": "COOL" | ||
} | ||
] | ||
}, | ||
{ | ||
"title": "T-Rex", | ||
"subtitle": "A big dinosaur", | ||
"image": "https://d.newsweek.com/en/full/986534/gettyimages-967254666.jpg", | ||
"actions": [ | ||
{ | ||
"action": "Say something", | ||
"title": "Roar", | ||
"text": "Woof woof" | ||
} | ||
] | ||
}, | ||
{ | ||
"title": "T-Bone", | ||
"subtitle": "A big steak", | ||
"image": "https://upload.wikimedia.org/wikipedia/commons/9/91/T-bone-raw-MCB.jpg", | ||
"actions": [ | ||
{ | ||
"action": "Open URL", | ||
"title": "Learn more", | ||
"url": "https://en.wikipedia.org/wiki/T-bone_steak" | ||
}, | ||
{ | ||
"action": "Say something", | ||
"title": "Miam", | ||
"text": "Miam Miam" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "single-choice", | ||
"text": "Make a choice :", | ||
"choices": [ | ||
{ "title": "Yay", "value": "YES" }, | ||
{ "title": "Nay", "value": "NO" } | ||
] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"extends": "../../../tsconfig.packages.json", | ||
"compilerOptions": { | ||
"rootDir": ".." | ||
}, | ||
"include": ["../test/**/*", "../src/**/*"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "@botpress/messaging-channels", | ||
"version": "0.0.1", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"source": "src/index.ts", | ||
"license": "AGPL-3.0", | ||
"scripts": { | ||
"build": "yarn --silent && tsc --build", | ||
"watch": "yarn --silent && tsc --build --watch", | ||
"example": "yarn --silent && ts-node-dev --debounce 500 --transpile-only example/index.ts" | ||
}, | ||
"devDependencies": {}, | ||
"dependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import clc from 'cli-color' | ||
import { Request, Router, Response, RequestHandler, NextFunction } from 'express' | ||
import yn from 'yn' | ||
import { Logger } from './logger' | ||
import { ChannelService } from './service' | ||
|
||
export class ChannelApi<TService extends ChannelService<any, any>> { | ||
protected urlCallback?: (scope: string) => Promise<string> | ||
|
||
constructor(protected readonly service: TService) {} | ||
|
||
async setup(router: ChannelApiManager) {} | ||
|
||
makeUrl(callback: (scope: string) => Promise<string>) { | ||
this.urlCallback = callback | ||
} | ||
|
||
protected async printWebhook(scope: string, name: string, path?: string) { | ||
// TODO: remove this dependency on server env vars | ||
if (yn(process.env.SPINNED)) { | ||
const externalUrl = await this.urlCallback!(scope) | ||
|
||
this.service.logger?.info( | ||
`[${scope}] ${clc.bold(name.charAt(0).toUpperCase() + name.slice(1))}${ | ||
path ? ' ' + path : '' | ||
} webhook ${clc.blackBright(`${externalUrl}/${name}${path ? `/${path}` : ''}`)}` | ||
) | ||
} | ||
} | ||
} | ||
|
||
export type Middleware<T> = (req: T, res: Response, next: NextFunction) => Promise<void> | ||
|
||
export class ChannelApiManager { | ||
constructor(private service: ChannelService<any, any>, private router: Router, private logger?: Logger) {} | ||
|
||
post(path: string, fn: Middleware<ChannelApiRequest>) { | ||
this.wrap('post', path, fn) | ||
} | ||
|
||
get(path: string, fn: Middleware<ChannelApiRequest>) { | ||
this.wrap('get', path, fn) | ||
} | ||
|
||
delete(path: string, fn: Middleware<ChannelApiRequest>) { | ||
this.wrap('delete', path, fn) | ||
} | ||
|
||
use(path: string, fn: RequestHandler) { | ||
this.router.use(`/:scope${path}`, fn) | ||
} | ||
|
||
protected wrap(type: 'post' | 'get' | 'delete' | 'use', path: string, fn: Middleware<ChannelApiRequest>) { | ||
this.router[type]( | ||
`/:scope${path}`, | ||
this.asyncMiddleware(async (req, res, next) => { | ||
const nreq = req as ChannelApiRequest | ||
nreq.scope = req.params.scope | ||
await this.service.require(nreq.scope) | ||
await fn(nreq, res, next) | ||
}) | ||
) | ||
} | ||
|
||
protected asyncMiddleware(fn: Middleware<Request>) { | ||
return (req: Request, res: Response, next: NextFunction) => { | ||
fn(req, res, next).catch((e) => { | ||
this.logger?.error(`Error occurred calling route ${req.originalUrl}`, e) | ||
return res.sendStatus(500) | ||
}) | ||
} | ||
} | ||
} | ||
|
||
export interface ChannelApiRequest extends Request { | ||
scope: string | ||
} |
Oops, something went wrong.