@@ -11,13 +11,16 @@ import * as https from 'https';
1111import * as oauth from './oauth' ;
1212import * as ssl from './ssl' ;
1313import debug from 'debug' ;
14+ import Promise from 'bluebird' ;
1415
1516// Debug log
1617const log = debug ( 'watsonwork-echo-app' ) ;
1718
19+ const post = Promise . promisify ( request . post ) ;
20+
1821// Echoes Watson Work chat messages containing 'hello' or 'hey' back
1922// to the space they were sent to
20- export const echo = ( appId , token ) => ( req , res ) => {
23+ export const echo = ( appId , token ) => async ( req , res ) => {
2124 // Respond to the Webhook right away, as the response message will
2225 // be sent asynchronously
2326 res . status ( 201 ) . end ( ) ;
@@ -38,52 +41,58 @@ export const echo = (appId, token) => (req, res) => {
3841 . filter ( ( word ) => / ^ ( h e l l o | h e y ) $ / i. test ( word ) ) . length )
3942
4043 // Send the echo message
41- send ( req . body . spaceId ,
44+ await send ( req . body . spaceId ,
4245 util . format (
4346 'Hey %s, did you say %s?' ,
4447 req . body . userName , req . body . content ) ,
45- token ( ) ,
46- ( err , res ) => {
47- if ( ! err )
48- log ( 'Sent message to space %s' , req . body . spaceId ) ;
49- } ) ;
48+ token ( ) ) ;
49+ log ( 'Sent message to space %s' , req . body . spaceId ) ;
5050} ;
5151
5252// Send an app message to the conversation in a space
53- const send = ( spaceId , text , tok , cb ) => {
54- request . post (
55- 'https://api.watsonwork.ibm.com/v1/spaces/' + spaceId + '/messages' , {
56- headers : {
57- Authorization : 'Bearer ' + tok
58- } ,
59- json : true ,
60- // An App message can specify a color, a title, markdown text and
61- // an 'actor' useful to show where the message is coming from
62- body : {
63- type : 'appMessage' ,
64- version : 1.0 ,
65- annotations : [ {
66- type : 'generic' ,
53+ const send = async ( spaceId , text , tok ) => {
54+ let res ;
55+ try {
56+ res = await post (
57+ 'https://api.watsonwork.ibm.com/v1/spaces/' + spaceId + '/messages' , {
58+ headers : {
59+ Authorization : 'Bearer ' + tok
60+ } ,
61+ json : true ,
62+ // An App message can specify a color, a title, markdown text and
63+ // an 'actor' useful to show where the message is coming from
64+ body : {
65+ type : 'appMessage' ,
6766 version : 1.0 ,
68-
69- color : '#6CB7FB' ,
70- title : 'Echo message' ,
71- text : text ,
72-
73- actor : {
74- name : 'Sample echo app'
75- }
76- } ]
77- }
78- } , ( err , res ) => {
79- if ( err || res . statusCode !== 201 ) {
80- log ( 'Error sending message %o' , err || res . statusCode ) ;
81- cb ( err || new Error ( res . statusCode ) ) ;
82- return ;
83- }
67+ annotations : [ {
68+ type : 'generic' ,
69+ version : 1.0 ,
70+
71+ color : '#6CB7FB' ,
72+ title : 'Echo message' ,
73+ text : text ,
74+
75+ actor : {
76+ name : 'Sample echo app'
77+ }
78+ } ]
79+ }
80+ } ) ;
81+
82+ // Handle invalid status response code
83+ if ( res . statusCode !== 201 )
84+ throw new Error ( res . statusCode ) ;
85+
86+ // log the valid response and its body
87+ else
8488 log ( 'Send result %d, %o' , res . statusCode , res . body ) ;
85- cb ( null , res . body ) ;
86- } ) ;
89+ }
90+ catch ( err ) {
91+ // log the error and rethrow it
92+ log ( 'Error sending message %o' , err ) ;
93+ throw err ;
94+ }
95+ return res ;
8796} ;
8897
8998// Verify Watson Work request signature
@@ -113,73 +122,64 @@ export const challenge = (wsecret) => (req, res, next) => {
113122} ;
114123
115124// Create Express Web app
116- export const webapp = ( appId , secret , wsecret , cb ) => {
125+ export const webapp = async ( appId , secret , wsecret ) => {
117126 // Authenticate the app and get an OAuth token
118- oauth . run ( appId , secret , ( err , token ) => {
119- if ( err ) {
120- cb ( err ) ;
121- return ;
122- }
123-
124- // Return the Express Web app
125- cb ( null , express ( )
126-
127- // Configure Express route for the app Webhook
128- . post ( '/echo' ,
127+ const token = await oauth . run ( appId , secret ) ;
128+ // Configure Express route for the app Webhook
129+ return express ( ) . post ( '/echo' ,
129130
130- // Verify Watson Work request signature and parse request body
131- bparser . json ( {
132- type : '*/*' ,
133- verify : verify ( wsecret )
134- } ) ,
131+ // Verify Watson Work request signature and parse request body
132+ bparser . json ( {
133+ type : '*/*' ,
134+ verify : verify ( wsecret )
135+ } ) ,
135136
136- // Handle Watson Work Webhook challenge requests
137- challenge ( wsecret ) ,
137+ // Handle Watson Work Webhook challenge requests
138+ challenge ( wsecret ) ,
138139
139- // Handle Watson Work messages
140- echo ( appId , token ) ) ) ;
141- } ) ;
140+ // Handle Watson Work messages
141+ echo ( appId , token ) ) ;
142142} ;
143143
144144// App main entry point
145- const main = ( argv , env , cb ) => {
146- // Create Express Web app
147- webapp (
148- env . ECHO_APP_ID , env . ECHO_APP_SECRET ,
149- env . ECHO_WEBHOOK_SECRET , ( err , app ) => {
150- if ( err ) {
151- cb ( err ) ;
152- return ;
153- }
154-
155- if ( env . PORT ) {
156- // In a hosting environment like Bluemix for example, HTTPS is
157- // handled by a reverse proxy in front of the app, just listen
158- // on the configured HTTP port
159- log ( 'HTTP server listening on port %d' , env . PORT ) ;
160- http . createServer ( app ) . listen ( env . PORT , cb ) ;
161- }
162-
163- else
164- // Listen on the configured HTTPS port, default to 443
165- ssl . conf ( env , ( err , conf ) => {
166- if ( err ) {
167- cb ( err ) ;
168- return ;
169- }
170- const port = env . SSLPORT || 443 ;
171- log ( 'HTTPS server listening on port %d' , port ) ;
172- https . createServer ( conf , app ) . listen ( port , cb ) ;
173- } ) ;
174- } ) ;
145+ const main = async ( argv , env ) => {
146+ try {
147+ // Create Express Web app
148+ const app = await webapp (
149+ env . ECHO_APP_ID , env . ECHO_APP_SECRET ,
150+ env . ECHO_WEBHOOK_SECRET ) ;
151+ if ( env . PORT ) {
152+ // In a hosting environment like Bluemix for example, HTTPS is
153+ // handled by a reverse proxy in front of the app, just listen
154+ // on the configured HTTP port
155+ log ( 'HTTP server listening on port %d' , env . PORT ) ;
156+ http . createServer ( app ) . listen ( env . PORT ) ;
157+ }
158+
159+ else {
160+
161+ // Listen on the configured HTTPS port, default to 443
162+ const sslConfig = await ssl . conf ( env ) ;
163+ const port = env . SSLPORT || 443 ;
164+ log ( 'HTTPS server listening on port %D' , port ) ;
165+ https . createServer ( sslConfig , app ) . listen ( port ) ;
166+ }
167+ }
168+ catch ( err ) {
169+ throw err ;
170+ }
175171} ;
176172
177- if ( require . main === module )
178- main ( process . argv , process . env , ( err ) => {
179- if ( err ) {
173+ // Run main as IIFE (top level await not supported)
174+ ( async ( ) => {
175+ if ( require . main === module )
176+ try {
177+ await main ( process . argv , process . env ) ;
178+ log ( 'App started!' ) ;
179+ }
180+ catch ( err ) {
180181 console . log ( 'Error starting app:' , err ) ;
181- return ;
182182 }
183- log ( 'App started' ) ;
184- } ) ;
183+ } ) ( ) ;
184+
185185
0 commit comments