'use strict' ; import { DirectLine , ConnectionStatus , Activity , Message as BotMessage } from 'botframework-directlinejs' ; import { Client } from './client_interface' ; import { Message , MessageType } from '../spec/message' ; import * as program from 'commander' ; import * as chalk from 'chalk' ; const globalAny = global ; globalAny . XMLHttpRequest = require ( 'xhr2' ) ; const retried = new Set < string > ( ) ; export class BotFrameworkClient extends Client { private conectionStatus : ConnectionStatus ; private directLine : DirectLine ; private messageIdToUser = new Map < string , string > ( ) ; private onReadyCb : ( ) => void ; private historyIds : string [ ] = [ ] ; constructor ( directLineSecret , domain ? ) { super ( ) ; this . directLine = new DirectLine ( { domain , secret : directLineSecret , webSocket : ! domain } ) ; this . subscribeToConnectionStatus ( ) ; } public send ( message ) { const activity = { from : { id : message . user , name : message . user } , type : 'message' , text : message . text , } ; this . directLine . postActivity ( activity ) . subscribe ( ( id ) => { if ( id === 'retry' ) { const messageKey = JSON . stringify ( message ) ; if ( retried . has ( messageKey ) ) { console . log ( 'DirectLine error, can\'t send: ' ) ; } retried . add ( messageKey ) ; this . send ( message ) ; } } , error => console . log ( 'DirectLine error, can\'t send: ' , error ) ) ; } public onReply ( callback ) { this . directLine . activity$ . filter ( ( activity ) => { const exists = this . historyIds . includes ( activity . id ) ; if ( ! exists ) this . historyIds . push ( activity . id ) ; return activity . type === 'message' && ! exists ; } ) . subscribe ( ( dlMessage ) => { try { if ( program . json ) { console . log ( `RECEIVED: ${ JSON . stringify ( dlMessage ) }` ) ; } if ( dlMessage . from . id . indexOf ( 'testuser' ) !== - 1 ) { this . messageIdToUser . set ( dlMessage . id , dlMessage . from . name ) ; } else { const user = this . messageIdToUser . get ( dlMessage . replyToId ) ; if ( user === undefined ) { console . error ( 'Unrecognized conversation on directline' , dlMessage ) ; return ; } const message = { user , messageTypes : [ dlMessage . text && MessageType . Text , dlMessage . attachments && dlMessage . attachments . some ( a => a . contentType . includes ( 'image' ) ) && MessageType . Image , dlMessage . attachments && dlMessage . attachments . some ( a => a . contentType . includes ( 'hero' ) ) && MessageType . Card , ] . filter ( m => m ) , text : dlMessage . text || null , } ; if ( message . messageTypes . length ) { callback ( message ) ; return ; } } } catch ( error ) { console . error ( chalk . red ( 'DIRECTLINE ERROR' ) , error ) ; } } ) ; } onReady ( ) { return new Promise < void > ( ( resolve ) => { if ( this . conectionStatus === ConnectionStatus . Online ) { resolve ( ) ; } else { this . onReadyCb = resolve ; } } ) ; } public close ( ) { this . directLine . end ( ) ; } private subscribeToConnectionStatus ( ) { this . directLine . connectionStatus$ . subscribe ( ( connectionStatus ) => { this . conectionStatus = connectionStatus ; switch ( connectionStatus ) { case ConnectionStatus . Uninitialized : break ; case ConnectionStatus . Connecting : if ( program . verbose ) { console . log ( 'Connecting to DirectLine...' ) ; } break ; case ConnectionStatus . Online : if ( program . verbose ) { console . log ( 'Connected to DirectLine.' ) ; } if ( this . onReadyCb ) { this . onReadyCb ( ) ; } break ; case ConnectionStatus . ExpiredToken : console . log ( 'DirectLine error: token expired.' ) ; process . exit ( 1 ) ; break ; case ConnectionStatus . FailedToConnect : console . log ( 'DirectLine error: failed to connect.' ) ; process . exit ( 1 ) ; break ; case ConnectionStatus . Ended : break ; } } ) ; } } export default Client ;