1- const DirectLine = require ( 'botframework-directlinejs' ) . DirectLine
1+ const mime = require ( 'mime-types' )
2+ const { DirectLine, ConnectionStatus } = require ( 'botframework-directlinejs' )
23const debug = require ( 'debug' ) ( 'botium-connector-directline3' )
34
45global . XMLHttpRequest = require ( 'xhr2' )
56
7+ const Capabilities = {
8+ DIRECTLINE3_SECRET : 'DIRECTLINE3_SECRET' ,
9+ DIRECTLINE3_WEBSOCKET : 'DIRECTLINE3_WEBSOCKET' ,
10+ DIRECTLINE3_POLLINGINTERVAL : 'DIRECTLINE3_POLLINGINTERVAL'
11+ }
12+
13+ const Defaults = {
14+ [ Capabilities . DIRECTLINE3_WEBSOCKET ] : true ,
15+ [ Capabilities . DIRECTLINE3_POLLINGINTERVAL ] : 1000
16+ }
17+
618class BotiumConnectorDirectline3 {
719 constructor ( { queueBotSays, caps } ) {
820 this . queueBotSays = queueBotSays
@@ -11,6 +23,8 @@ class BotiumConnectorDirectline3 {
1123
1224 Validate ( ) {
1325 debug ( 'Validate called' )
26+ this . caps = Object . assign ( { } , Defaults , this . caps )
27+
1428 if ( ! this . caps [ 'DIRECTLINE3_SECRET' ] ) throw new Error ( 'DIRECTLINE3_SECRET capability required' )
1529
1630 return Promise . resolve ( )
@@ -39,13 +53,81 @@ class BotiumConnectorDirectline3 {
3953 if ( this . receivedMessageIds [ message . id ] ) {
4054 debug ( 'ignore already received message ' , message )
4155 } else {
42- debug ( 'received message ' , message )
56+ debug ( 'received message ' , JSON . stringify ( message , null , 2 ) )
4357 this . receivedMessageIds [ message . id ] = true
44- const botMsg = { sender : 'bot' , sourceData : message , messageText : message . text }
58+ const botMsg = { sender : 'bot' , sourceData : message , media : [ ] , buttons : [ ] , cards : [ ] }
59+ botMsg . messageText = message . text || null
60+
61+ const mapButton = ( b ) => ( {
62+ text : b . title ,
63+ payload : b . value ,
64+ imageUri : b . image
65+ } )
66+ const mapImage = ( i ) => ( {
67+ mediaUri : i . url ,
68+ mimeType : mime . lookup ( i . url ) || 'application/unknown' ,
69+ altText : i . alt
70+ } )
71+ const mapMedia = ( m ) => ( {
72+ mediaUri : m . url ,
73+ mimeType : mime . lookup ( m . url ) || 'application/unknown' ,
74+ altText : m . profile
75+ } )
76+
77+ message . attachments && message . attachments . forEach ( a => {
78+ if ( a . contentType === 'application/vnd.microsoft.card.hero' ) {
79+ botMsg . cards . push ( {
80+ text : a . content . title ,
81+ image : a . content . images && a . content . images . length > 0 && [ mapImage ( a . content . images [ 0 ] ) ] ,
82+ buttons : a . content . buttons && a . content . buttons . map ( mapButton )
83+ } )
84+ } else if ( a . contentType === 'application/vnd.microsoft.card.adaptive' ) {
85+ // TODO
86+ } else if ( a . contentType === 'application/vnd.microsoft.card.animation' ||
87+ a . contentType === 'application/vnd.microsoft.card.audio' ||
88+ a . contentType === 'application/vnd.microsoft.card.video' ) {
89+ botMsg . media = botMsg . media . concat ( a . content . media && a . content . media . map ( mapMedia ) )
90+ botMsg . buttons = botMsg . buttons . concat ( a . content . buttons && a . content . buttons . map ( mapButton ) )
91+ } else if ( a . contentType === 'application/vnd.microsoft.card.thumbnail' ) {
92+ botMsg . media = botMsg . media . concat ( a . content . images && a . content . images . map ( mapImage ) )
93+ botMsg . buttons = botMsg . buttons . concat ( a . content . buttons && a . content . buttons . map ( mapButton ) )
94+ } else if ( a . contentType && a . contentUrl ) {
95+ botMsg . media . push ( {
96+ mediaUri : a . contentUrl ,
97+ mimeType : a . contentType ,
98+ altText : a . name
99+ } )
100+ }
101+ } )
102+
45103 this . queueBotSays ( botMsg )
46104 }
47105 }
48106 )
107+ this . connSubscription = this . directLine . connectionStatus$
108+ . subscribe ( connectionStatus => {
109+ switch ( connectionStatus ) {
110+ case ConnectionStatus . Uninitialized :
111+ debug ( `Directline Connection Status: ${ connectionStatus } / Uninitialized` )
112+ break
113+ case ConnectionStatus . Connecting :
114+ debug ( `Directline Connection Status: ${ connectionStatus } / Connecting` )
115+ break
116+ case ConnectionStatus . Online :
117+ debug ( `Directline Connection Status: ${ connectionStatus } / Online` )
118+ break
119+ case ConnectionStatus . ExpiredToken :
120+ debug ( `Directline Connection Status: ${ connectionStatus } / ExpiredToken` )
121+ break
122+ case ConnectionStatus . FailedToConnect :
123+ debug ( `Directline Connection Status: ${ connectionStatus } / FailedToConnect` )
124+ break
125+ case ConnectionStatus . Ended :
126+ debug ( `Directline Connection Status: ${ connectionStatus } / Ended` )
127+ break
128+ }
129+ } )
130+
49131 return Promise . resolve ( )
50132 }
51133
@@ -83,10 +165,15 @@ class BotiumConnectorDirectline3 {
83165
84166 _stopSubscription ( ) {
85167 if ( this . subscription ) {
86- debug ( 'unsubscribing from directline subscription' )
168+ debug ( 'unsubscribing from directline activity subscription' )
87169 this . subscription . unsubscribe ( )
88170 this . subscription = null
89171 }
172+ if ( this . connSubscription ) {
173+ debug ( 'unsubscribing from directline connectionstatus subscription' )
174+ this . connSubscription . unsubscribe ( )
175+ this . connSubscription = null
176+ }
90177 }
91178}
92179
0 commit comments