-
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.
* smooch start * text * typing indicators * image * choices * carousel * postback * readme * more typings * fix * location * readme * file * audio video * yarn.lock * add to server
- Loading branch information
1 parent
2382f30
commit c10e228
Showing
25 changed files
with
644 additions
and
16 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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
### Sending | ||
|
||
| Channels | Smooch | | ||
| -------- | :----: | | ||
| Text | ✅ | | ||
| Image | ✅ | | ||
| Choice | ✅ | | ||
| Dropdown | ✅ | | ||
| Card | ✅ | | ||
| Carousel | ✅ | | ||
| File | ✅ | | ||
| Audio | ✅ | | ||
| Video | ✅ | | ||
| Location | ✅ | | ||
|
||
### Receiving | ||
|
||
| Channels | Smooch | | ||
| ------------- | :----: | | ||
| Text | ✅ | | ||
| Quick Reply | N/A | | ||
| 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,70 @@ | ||
import express, { Response } from 'express' | ||
import { ChannelApi, ChannelApiManager, ChannelApiRequest } from '../base/api' | ||
import { POSTBACK_PREFIX, SAY_PREFIX } from './renderers/carousel' | ||
import { SmoochService } from './service' | ||
import { SmoochEvent, SmoochMessageEvent, SmoochPostbackEvent, SmoochRequestBody } from './smooch' | ||
|
||
export class SmoochApi extends ChannelApi<SmoochService> { | ||
async setup(router: ChannelApiManager) { | ||
router.use('/smooch', express.json()) | ||
router.post('/smooch', this.handleRequest.bind(this)) | ||
} | ||
|
||
private async handleRequest(req: ChannelApiRequest, res: Response) { | ||
const apiKey = req.headers['x-api-key'] as string | undefined | ||
const { config } = this.service.get(req.scope) | ||
|
||
if (apiKey !== config.webhookSecret) { | ||
return res.sendStatus(403) | ||
} | ||
|
||
const body = req.body as SmoochRequestBody | ||
|
||
for (const event of body.events) { | ||
await this.handleEvent(req.scope, event) | ||
} | ||
|
||
res.sendStatus(200) | ||
} | ||
|
||
private async handleEvent(scope: string, event: SmoochEvent) { | ||
if (event.type === 'conversation:message') { | ||
return this.handleMessage(scope, event) | ||
} else if (event.type === 'conversation:postback') { | ||
return this.handlePostback(scope, event) | ||
} | ||
} | ||
|
||
private async handleMessage(scope: string, event: SmoochMessageEvent) { | ||
const { conversation, message } = event.payload | ||
|
||
if (message.author.type === 'business') { | ||
return | ||
} | ||
|
||
await this.service.receive( | ||
scope, | ||
{ identity: '*', sender: message.author.userId, thread: conversation.id }, | ||
{ type: 'text', text: message.content.text } | ||
) | ||
} | ||
|
||
private async handlePostback(scope: string, event: SmoochPostbackEvent) { | ||
const { conversation, postback, user } = event.payload | ||
const { payload } = postback | ||
|
||
const endpoint = { identity: '*', sender: user.id, thread: conversation.id } | ||
|
||
if (payload.startsWith(POSTBACK_PREFIX)) { | ||
await this.service.receive(scope, endpoint, { | ||
type: 'postback', | ||
payload: payload.replace(POSTBACK_PREFIX, '') | ||
}) | ||
} else if (payload.startsWith(SAY_PREFIX)) { | ||
await this.service.receive(scope, endpoint, { | ||
type: 'say_something', | ||
text: payload.replace(SAY_PREFIX, '') | ||
}) | ||
} | ||
} | ||
} |
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 { SmoochApi } from './api' | ||
import { SmoochConfig, SmoochConfigSchema } from './config' | ||
import { SmoochService } from './service' | ||
import { SmoochStream } from './stream' | ||
|
||
export class SmoochChannel extends ChannelTemplate<SmoochConfig, SmoochService, SmoochApi, SmoochStream> { | ||
get meta() { | ||
return { | ||
id: '82c7a7ee-f1c9-4fb6-8306-18f03d6aadc9', | ||
name: 'smooch', | ||
version: '1.0.0', | ||
schema: SmoochConfigSchema, | ||
initiable: true, | ||
lazy: true | ||
} | ||
} | ||
|
||
constructor() { | ||
const service = new SmoochService() | ||
super(service, new SmoochApi(service), new SmoochStream(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,16 @@ | ||
import Joi from 'joi' | ||
import { ChannelConfig } from '../base/config' | ||
|
||
export interface SmoochConfig extends ChannelConfig { | ||
appId: string | ||
keyId: string | ||
keySecret: string | ||
webhookSecret: string | ||
} | ||
|
||
export const SmoochConfigSchema = { | ||
appId: Joi.string().required(), | ||
keyId: Joi.string().required(), | ||
keySecret: Joi.string().required(), | ||
webhookSecret: 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,7 @@ | ||
import { ChannelContext } from '../base/context' | ||
import { SmoochState } from './service' | ||
import { SmoochContent } from './smooch' | ||
|
||
export type SmoochContext = ChannelContext<SmoochState> & { | ||
messages: SmoochContent[] | ||
} |
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 { SmoochContext } from '../context' | ||
|
||
export class SmoochAudioRenderer extends AudioRenderer { | ||
renderAudio(context: SmoochContext, payload: AudioContent) { | ||
context.messages.push({ type: 'file', text: 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,72 @@ | ||
import { CarouselContext, CarouselRenderer } from '../../base/renderers/carousel' | ||
import { ActionOpenURL, ActionPostback, ActionSaySomething, CardContent, CarouselContent } from '../../content/types' | ||
import { SmoochContext } from '../context' | ||
import { SmoochAction, SmoochCard } from '../smooch' | ||
|
||
export const POSTBACK_PREFIX = 'postback::' | ||
export const SAY_PREFIX = 'say::' | ||
|
||
type Context = CarouselContext<SmoochContext> & { | ||
items: SmoochCard[] | ||
actions: SmoochAction[] | ||
} | ||
|
||
export class SmoochCarouselRenderer extends CarouselRenderer { | ||
startRender(context: Context, carousel: CarouselContent) { | ||
context.items = [] | ||
} | ||
|
||
startRenderCard(context: Context, card: CardContent) { | ||
context.actions = [] | ||
} | ||
|
||
renderButtonUrl(context: Context, button: ActionOpenURL) { | ||
context.actions.push({ | ||
type: 'link', | ||
text: button.title, | ||
uri: button.url | ||
}) | ||
} | ||
|
||
renderButtonPostback(context: Context, button: ActionPostback) { | ||
context.actions.push({ | ||
type: 'postback', | ||
text: button.title, | ||
payload: `${POSTBACK_PREFIX}${button.payload}` | ||
}) | ||
} | ||
|
||
renderButtonSay(context: Context, button: ActionSaySomething) { | ||
context.actions.push({ | ||
type: 'postback', | ||
text: button.title, | ||
payload: `${SAY_PREFIX}${button.text}` | ||
}) | ||
} | ||
|
||
endRenderCard(context: Context, card: CardContent) { | ||
if (context.actions.length === 0) { | ||
context.actions.push({ | ||
type: 'postback', | ||
text: card.title, | ||
payload: card.title | ||
}) | ||
} | ||
|
||
const smoochCard: SmoochCard = { | ||
title: card.title, | ||
description: card.subtitle, | ||
mediaUrl: card.image, | ||
actions: context.actions | ||
} | ||
|
||
context.items.push(smoochCard) | ||
} | ||
|
||
endRender(context: Context, carousel: CarouselContent) { | ||
context.channel.messages.push({ | ||
type: 'carousel', | ||
items: context.items | ||
}) | ||
} | ||
} |
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,10 @@ | ||
import { ChoicesRenderer } from '../../base/renderers/choices' | ||
import { ChoiceContent } from '../../content/types' | ||
import { SmoochContext } from '../context' | ||
|
||
export class SmoochChoicesRenderer extends ChoicesRenderer { | ||
renderChoice(context: SmoochContext, payload: ChoiceContent): void { | ||
const message = context.messages[0] | ||
message.actions = payload.choices.map((r) => ({ type: 'reply', text: r.title, payload: r.value })) | ||
} | ||
} |
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 { SmoochContext } from '../context' | ||
|
||
export class SmoochFileRenderer extends FileRenderer { | ||
renderFile(context: SmoochContext, payload: FileContent) { | ||
context.messages.push({ type: 'file', text: payload.title, mediaUrl: 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 { SmoochContext } from '../context' | ||
|
||
export class SmoochImageRenderer extends ImageRenderer { | ||
renderImage(context: SmoochContext, payload: ImageContent): void { | ||
context.messages.push({ type: 'image', mediaUrl: payload.image, text: payload.title }) | ||
} | ||
} |
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 { SmoochAudioRenderer } from './audio' | ||
import { SmoochCarouselRenderer } from './carousel' | ||
import { SmoochChoicesRenderer } from './choices' | ||
import { SmoochFileRenderer } from './file' | ||
import { SmoochImageRenderer } from './image' | ||
import { SmoochLocationRenderer } from './location' | ||
import { SmoochTextRenderer } from './text' | ||
import { SmoochVideoRenderer } from './video' | ||
|
||
export const SmoochRenderers = [ | ||
new SmoochTextRenderer(), | ||
new SmoochImageRenderer(), | ||
new SmoochChoicesRenderer(), | ||
new SmoochCarouselRenderer(), | ||
new SmoochFileRenderer(), | ||
new SmoochAudioRenderer(), | ||
new SmoochVideoRenderer(), | ||
new SmoochLocationRenderer() | ||
] |
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 { LocationRenderer } from '../../base/renderers/location' | ||
import { LocationContent } from '../../content/types' | ||
import { SmoochContext } from '../context' | ||
|
||
export class SmoochLocationRenderer extends LocationRenderer { | ||
renderLocation(context: SmoochContext, payload: LocationContent) { | ||
context.messages.push({ | ||
type: 'location', | ||
coordinates: { | ||
lat: payload.latitude, | ||
long: payload.longitude | ||
}, | ||
location: { | ||
address: payload.address, | ||
name: payload.title | ||
} | ||
}) | ||
} | ||
} |
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 { TextRenderer } from '../../base/renderers/text' | ||
import { TextContent } from '../../content/types' | ||
import { SmoochContext } from '../context' | ||
|
||
export class SmoochTextRenderer extends TextRenderer { | ||
renderText(context: SmoochContext, payload: TextContent): void { | ||
context.messages.push({ | ||
type: 'text', | ||
text: 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 { SmoochContext } from '../context' | ||
|
||
export class SmoochVideoRenderer extends VideoRenderer { | ||
renderVideo(context: SmoochContext, payload: VideoContent) { | ||
context.messages.push({ type: 'file', text: payload.title, mediaUrl: 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,17 @@ | ||
import { CommonSender } from '../../base/senders/common' | ||
import { SmoochContext } from '../context' | ||
const SunshineConversationsClient = require('sunshine-conversations-client') | ||
|
||
export class SmoochCommonSender extends CommonSender { | ||
async send(context: SmoochContext) { | ||
for (const message of context.messages) { | ||
const data = new SunshineConversationsClient.MessagePost() | ||
data.author = { | ||
type: 'business' | ||
} | ||
data.content = message | ||
|
||
await context.state.smooch.messages.postMessage(context.state.config.appId, context.thread, data) | ||
} | ||
} | ||
} |
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,4 @@ | ||
import { SmoochCommonSender } from './common' | ||
import { SmoochTypingSender } from './typing' | ||
|
||
export const SmoochSenders = [new SmoochTypingSender(), new SmoochCommonSender()] |
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 @@ | ||
import { TypingSender } from '../../base/senders/typing' | ||
import { SmoochContext } from '../context' | ||
const SunshineConversationsClient = require('sunshine-conversations-client') | ||
|
||
export class SmoochTypingSender extends TypingSender { | ||
async sendIndicator(context: SmoochContext) { | ||
const data = new SunshineConversationsClient.ActivityPost() | ||
data.author = { | ||
type: 'business' | ||
} | ||
data.type = 'typing:start' | ||
|
||
await context.state.smooch.activity.postActivity(context.state.config.appId, context.thread, data) | ||
} | ||
} |
Oops, something went wrong.