-
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.
* delete old * use legacy * remove deps * use channels 0.1.0 * bring changes * gif * feat(twilio): twilio v2 * bring changes * file audio video location * fix * fix * fix * fix * bring changes * rewire comment * fix * fix * fix * bring changes * bump * fix merge * fix * add twilio to server
- Loading branch information
1 parent
626ffb9
commit a1acd2f
Showing
24 changed files
with
341 additions
and
8 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
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 |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './base/channel' | ||
export * from './base/endpoint' | ||
export * from './twilio/channel' | ||
export * from './telegram/channel' |
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,29 @@ | ||
### Sending | ||
|
||
| Channels | Twilio | | ||
| -------- | :----: | | ||
| Text | ✅ | | ||
| Image | ✅ | | ||
| Choice | ✅ | | ||
| Dropdown | ✅ | | ||
| Card | ✅ | | ||
| Carousel | ✅ | | ||
| File | ✅ | | ||
| Audio | ✅ | | ||
| Video | ✅ | | ||
| Location | ✅ | | ||
|
||
### Receiving | ||
|
||
| Channels | Twilio | | ||
| ------------- | :----: | | ||
| Text | ✅ | | ||
| Quick Reply | ✅ | | ||
| Postback | ✅ | | ||
| Say Something | ✅ | | ||
| Voice | ❌ | | ||
| Image | ❌ | | ||
| File | ❌ | | ||
| Audio | ❌ | | ||
| Video | ❌ | | ||
| Location | ❌ | |
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,39 @@ | ||
import express, { Response } from 'express' | ||
import { validateRequest } from 'twilio' | ||
import yn from 'yn' | ||
import { ChannelApi, ChannelApiManager, ChannelApiRequest } from '../base/api' | ||
import { TwilioService } from './service' | ||
|
||
export class TwilioApi extends ChannelApi<TwilioService> { | ||
async setup(router: ChannelApiManager) { | ||
router.use('/twilio', express.urlencoded({ extended: true })) | ||
router.post('/twilio', this.handleRequest.bind(this)) | ||
} | ||
|
||
private async handleRequest(req: ChannelApiRequest, res: Response) { | ||
const { config } = this.service.get(req.scope) | ||
|
||
const signature = req.headers['x-twilio-signature'] as string | ||
const webhookUrl = await this.urlCallback!(req.scope) | ||
|
||
if (validateRequest(config.authToken, signature, webhookUrl, req.body) || yn(process.env.TWILIO_TESTING)) { | ||
await this.receive(req.scope, req.body) | ||
res.sendStatus(204) | ||
} else { | ||
res.sendStatus(401) | ||
} | ||
} | ||
|
||
private async receive(scope: string, body: any) { | ||
const botPhoneNumber = body.To | ||
const userPhoneNumber = body.From | ||
|
||
const index = Number(body.Body) | ||
const content = this.service.handleIndexResponse(scope, index, botPhoneNumber, userPhoneNumber) || { | ||
type: 'text', | ||
text: body.Body | ||
} | ||
|
||
await this.service.receive(scope, { identity: botPhoneNumber, sender: userPhoneNumber, thread: '*' }, content) | ||
} | ||
} |
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,23 @@ | ||
import { ChannelTemplate } from '../base/channel' | ||
import { TwilioApi } from './api' | ||
import { TwilioConfig, TwilioConfigSchema } from './config' | ||
import { TwilioService } from './service' | ||
import { TwilioStream } from './stream' | ||
|
||
export class TwilioChannel extends ChannelTemplate<TwilioConfig, TwilioService, TwilioApi, TwilioStream> { | ||
get meta() { | ||
return { | ||
id: 'a711e325-7e71-4955-a76c-b46e62cdebd7', | ||
name: 'twilio', | ||
version: '1.0.0', | ||
schema: TwilioConfigSchema, | ||
initiable: false, | ||
lazy: true | ||
} | ||
} | ||
|
||
constructor() { | ||
const service = new TwilioService() | ||
super(service, new TwilioApi(service), new TwilioStream(service)) | ||
} | ||
} |
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,12 @@ | ||
import Joi from 'joi' | ||
import { ChannelConfig } from '../base/config' | ||
|
||
export interface TwilioConfig extends ChannelConfig { | ||
accountSID: string | ||
authToken: string | ||
} | ||
|
||
export const TwilioConfigSchema = { | ||
accountSID: Joi.string().required(), | ||
authToken: Joi.string().required() | ||
} |
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,8 @@ | ||
import { MessageListInstanceCreateOptions } from 'twilio/lib/rest/api/v2010/account/message' | ||
import { ChannelContext, IndexChoiceOption } from '../base/context' | ||
import { TwilioState } from './service' | ||
|
||
export type TwilioContext = ChannelContext<TwilioState> & { | ||
messages: Partial<MessageListInstanceCreateOptions>[] | ||
prepareIndexResponse(scope: string, identity: string, sender: string, options: IndexChoiceOption[]): void | ||
} |
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,9 @@ | ||
import { AudioRenderer } from '../../base/renderers/audio' | ||
import { AudioContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioAudioRenderer extends AudioRenderer { | ||
renderAudio(context: TwilioContext, payload: AudioContent) { | ||
context.messages.push({ body: payload.title, mediaUrl: payload.audio }) | ||
} | ||
} |
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,57 @@ | ||
import { IndexChoiceOption, IndexChoiceType } from '../../base/context' | ||
import { CarouselRenderer, CarouselContext } from '../../base/renderers/carousel' | ||
import { ActionOpenURL, ActionPostback, ActionSaySomething, CardContent, CarouselContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
type Context = CarouselContext<TwilioContext> & { | ||
options: IndexChoiceOption[] | ||
allOptions: IndexChoiceOption[] | ||
index: number | ||
} | ||
|
||
export class TwilioCarouselRenderer extends CarouselRenderer { | ||
startRender(context: Context, carousel: CarouselContent) { | ||
context.allOptions = [] | ||
} | ||
|
||
startRenderCard(context: Context, card: CardContent) { | ||
context.options = [] | ||
} | ||
|
||
renderButtonUrl(context: Context, button: ActionOpenURL) { | ||
context.options.push({ | ||
type: IndexChoiceType.OpenUrl, | ||
title: `${button.title} : ${button.url}` | ||
}) | ||
} | ||
|
||
renderButtonPostback(context: Context, button: ActionPostback) { | ||
context.options.push({ type: IndexChoiceType.PostBack, title: button.title, value: button.payload }) | ||
} | ||
|
||
renderButtonSay(context: Context, button: ActionSaySomething) { | ||
context.options.push({ | ||
type: IndexChoiceType.SaySomething, | ||
title: button.title, | ||
value: button.text | ||
}) | ||
} | ||
|
||
endRenderCard(context: Context, card: CardContent) { | ||
const body = `${card.title}\n\n${card.subtitle || ''}\n\n${context.options | ||
.map(({ title }, idx) => `${idx + context.allOptions.length + 1}. ${title}`) | ||
.join('\n')}` | ||
|
||
context.channel.messages.push(<any>{ body, mediaUrl: card.image }) | ||
context.allOptions.push(...context.options) | ||
} | ||
|
||
endRender(context: Context, carousel: CarouselContent) { | ||
context.channel.prepareIndexResponse( | ||
context.channel.scope, | ||
context.channel.identity, | ||
context.channel.sender, | ||
context.allOptions | ||
) | ||
} | ||
} |
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,25 @@ | ||
import { IndexChoiceType } from '../../base/context' | ||
import { ChoicesRenderer } from '../../base/renderers/choices' | ||
import { ChoiceContent, ChoiceOption } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioChoicesRenderer extends ChoicesRenderer { | ||
renderChoice(context: TwilioContext, payload: ChoiceContent) { | ||
if (!context.messages.length) { | ||
context.messages.push({}) | ||
} | ||
|
||
const message = context.messages[0] | ||
|
||
message.body = `${message.body || ''}\n\n${payload.choices | ||
.map(({ title }, idx) => `${idx + 1}. ${title}`) | ||
.join('\n')}` | ||
|
||
context.prepareIndexResponse( | ||
context.scope, | ||
context.identity, | ||
context.sender, | ||
payload.choices.map((x: ChoiceOption) => ({ ...x, type: IndexChoiceType.QuickReply })) | ||
) | ||
} | ||
} |
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,9 @@ | ||
import { FileRenderer } from '../../base/renderers/file' | ||
import { FileContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioFileRenderer extends FileRenderer { | ||
renderFile(context: TwilioContext, payload: FileContent) { | ||
context.messages.push({ body: `${payload.title}\n\n${payload.file}` }) | ||
} | ||
} |
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,9 @@ | ||
import { ImageRenderer } from '../../base/renderers/image' | ||
import { ImageContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioImageRenderer extends ImageRenderer { | ||
renderImage(context: TwilioContext, payload: ImageContent) { | ||
context.messages.push({ body: payload.title, mediaUrl: payload.image }) | ||
} | ||
} |
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,19 @@ | ||
import { TwilioAudioRenderer } from './audio' | ||
import { TwilioCarouselRenderer } from './carousel' | ||
import { TwilioChoicesRenderer } from './choices' | ||
import { TwilioFileRenderer } from './file' | ||
import { TwilioImageRenderer } from './image' | ||
import { TwilioLocationRenderer } from './location' | ||
import { TwilioTextRenderer } from './text' | ||
import { TwilioVideoRenderer } from './video' | ||
|
||
export const TwilioRenderers = [ | ||
new TwilioTextRenderer(), | ||
new TwilioImageRenderer(), | ||
new TwilioCarouselRenderer(), | ||
new TwilioChoicesRenderer(), | ||
new TwilioFileRenderer(), | ||
new TwilioAudioRenderer(), | ||
new TwilioVideoRenderer(), | ||
new TwilioLocationRenderer() | ||
] |
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,11 @@ | ||
import { LocationRenderer } from '../../base/renderers/location' | ||
import { LocationContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioLocationRenderer extends LocationRenderer { | ||
renderLocation(context: TwilioContext, payload: LocationContent) { | ||
const googleMapsLink = `https://www.google.com/maps/search/?api=1&query=${payload.latitude},${payload.longitude}` | ||
|
||
context.messages.push({ body: `${payload.title}\n\n${googleMapsLink}` }) | ||
} | ||
} |
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,9 @@ | ||
import { TextRenderer } from '../../base/renderers/text' | ||
import { TextContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioTextRenderer extends TextRenderer { | ||
renderText(context: TwilioContext, payload: TextContent) { | ||
context.messages.push({ body: payload.text }) | ||
} | ||
} |
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,9 @@ | ||
import { VideoRenderer } from '../../base/renderers/video' | ||
import { VideoContent } from '../../content/types' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioVideoRenderer extends VideoRenderer { | ||
renderVideo(context: TwilioContext, payload: VideoContent) { | ||
context.messages.push({ body: `${payload.title}\n\n${payload.video}` }) | ||
} | ||
} |
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,14 @@ | ||
import { CommonSender } from '../../base/senders/common' | ||
import { TwilioContext } from '../context' | ||
|
||
export class TwilioCommonSender extends CommonSender { | ||
async send(context: TwilioContext) { | ||
for (const message of context.messages) { | ||
await context.state.twilio.messages.create({ | ||
...message, | ||
from: context.identity, | ||
to: context.sender | ||
}) | ||
} | ||
} | ||
} |
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,3 @@ | ||
import { TwilioCommonSender } from './common' | ||
|
||
export const TwilioSenders = [new TwilioCommonSender()] |
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,16 @@ | ||
import { Twilio } from 'twilio' | ||
import { ChannelService, ChannelState } from '../base/service' | ||
import { TwilioConfig } from './config' | ||
|
||
export interface TwilioState extends ChannelState<TwilioConfig> { | ||
twilio: Twilio | ||
} | ||
|
||
export class TwilioService extends ChannelService<TwilioConfig, TwilioState> { | ||
async create(scope: string, config: TwilioConfig) { | ||
return { | ||
config, | ||
twilio: new Twilio(config.accountSID, config.authToken) | ||
} | ||
} | ||
} |
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,27 @@ | ||
import { ChannelContext } from '../base/context' | ||
import { CardToCarouselRenderer } from '../base/renderers/card' | ||
import { DropdownToChoicesRenderer } from '../base/renderers/dropdown' | ||
import { TypingSender } from '../base/senders/typing' | ||
import { ChannelStream } from '../base/stream' | ||
import { TwilioContext } from './context' | ||
import { TwilioRenderers } from './renderers' | ||
import { TwilioSenders } from './senders' | ||
import { TwilioService } from './service' | ||
|
||
export class TwilioStream extends ChannelStream<TwilioService, TwilioContext> { | ||
get renderers() { | ||
return [new CardToCarouselRenderer(), new DropdownToChoicesRenderer(), ...TwilioRenderers] | ||
} | ||
|
||
get senders() { | ||
return [new TypingSender(), ...TwilioSenders] | ||
} | ||
|
||
protected async getContext(base: ChannelContext<any>): Promise<TwilioContext> { | ||
return { | ||
...base, | ||
messages: [], | ||
prepareIndexResponse: this.service.prepareIndexResponse.bind(this.service) | ||
} | ||
} | ||
} |
Oops, something went wrong.