meshblu-connector-skype
Version:
183 lines (147 loc) • 6.92 kB
text/coffeescript
{EventEmitter} = require 'events'
_ = require 'lodash'
moment = require 'moment'
debug = require('debug')('meshblu-connector-skype:index')
LyncEventEmitter = require './lync-event-emitter'
LyncLauncher = require './lync-launcher'
LyncDisableFeedback = require './lync-disable-feedback'
class Connector extends EventEmitter
constructor: ({}={}) ->
LyncManager = require('./lync-manager')
= new LyncManager { dirname: process.env.MESHBLU_CONNECTOR_EDGE_ASSETS_DIR }
= new LyncEventEmitter()
start: (device, callback) =>
= setInterval , 10000
.on 'config',
.on 'config', _.throttle (=> ()), 1000
LyncDisableFeedback.disable (error) =>
return callback error if error?
{ } = device
device, (error) =>
return callback error if error
callback
close: (callback) =>
clearInterval
return callback()
onConfig: ({desiredState, autoLaunchSkype}={}, callback=->) =>
callback()
debug 'autoLaunchSkype', autoLaunchSkype
debug 'desiredState', JSON.stringify(desiredState, null, 2)
LyncLauncher.stopAutoCheck()
LyncLauncher.autoCheck() if autoLaunchSkype
return if _.isEmpty desiredState
.emitEvents .handle
= _.cloneDeep desiredState
{}
()
killFeedback: =>
.killFeedback (error) =>
console.error '@Lync.killFeedback', error.stack if error?
startMeeting: ({audioEnabled, videoEnabled}, callback) =>
finishStartMeetingHandler = (conversations) =>
currentState = _.first _.values conversations
conversationUrl = _.get currentState, 'properties.conferenceAccessInformation.ExternalUrl'
if conversationUrl
.off 'config', finishStartMeetingHandler
callback null, meeting: url: conversationUrl
.stopMeetings null, (error) =>
console.error '@Lync.stopMeetings', error.stack if error?
.on 'config', finishStartMeetingHandler
{audioEnabled, videoEnabled, meeting: {}}
truthAndReconcilliation: =>
currentState = _.first _.values .conversations
debug "truthAndReconcilliation", {currentState, }
return unless ?
currentState, (error) =>
console.error '@_handleMeeting', error.stack if error?
delete .meeting
currentState
currentState
updateDesiredState: (desiredState) =>
'update', {desiredState}
_refreshCurrentState: (callback=->) =>
(error, state) =>
return callback error if error?
{state}, callback
_emitNoClient: ({state}, callback) =>
'error', new Error('Cannot find running Lync Process')
{state}, callback
_emitUpdate: (update, callback) =>
return callback() if _.isEqual update,
'update', _.defaults {connectorUpdatedAt: moment().utc().toISOString()}, update
= update
callback()
_computeState: (callback) =>
debug '_computeState'
currentState = _.first _.values .conversations
return callback null, {meeting: null} unless currentState?
conversationUrl = _.get currentState, 'properties.conferenceAccessInformation.ExternalUrl'
conversationUrl = null if _.isEmpty conversationUrl
self = currentState.participants?[currentState.self]
videoState = _.get currentState, 'video.state'
ourKindaState =
meeting:
url: conversationUrl
subject: _.get currentState, 'subject'
participants: _.get currentState, 'participants'
conversationId: _.get currentState, 'properties.id'
videoState: _.get currentState, 'video.state'
videoEnabled: videoState == 'Send' || videoState == 'SendReceive'
videoActions: _.get currentState, 'video.actions'
audioEnabled: !self?.isMuted
callback null, ourKindaState
_handleAudioEnabled: (currentState, callback=->) =>
debug '_handleAudioEnabled', {currentState, }
return callback() unless _.has , 'audioEnabled'
return callback() unless _.has currentState, 'self'
return callback() unless _.lowerCase(currentState?.state) == 'active'
self = _.get currentState, "participants.#{currentState.self}"
debug .audioEnabled, self.isMuted
if .audioEnabled
debug 'unmuting'
return .unmute null, (error) =>
debug 'unmuted', error
return callback error if error?
delete .audioEnabled
callback()
debug 'muting'
return .mute null, (error) =>
debug 'muted', error
return callback error if error?
delete .audioEnabled
callback()
_handleMeeting: (currentState, callback=->) =>
debug '_handleMeeting', {, currentState}
{meeting} =
delete .meeting
return callback() if meeting == undefined
return .stopMeetings null, callback if meeting == null
conversationUrl = _.get currentState, 'properties.conferenceAccessInformation.ExternalUrl'
return callback() if conversationUrl && meeting.url == conversationUrl
debug 'stopping meetings'
.stopMeetings null, (error) =>
return callback error if error?
return .createMeeting null, callback if _.isEmpty meeting.url
.joinMeeting meeting.url, callback
_handleVideoEnabled: (currentState, callback=->) =>
debug '_handleVideoEnabled',
return callback() unless _.has , 'videoEnabled'
return callback() unless _.lowerCase(currentState?.state) == 'active'
return .stopVideo null, callback unless .videoEnabled
return currentState, callback
_startVideo: (currentState, callback) =>
debug "trying to _startVideo"
videoState = _.get currentState, 'video.state'
if videoState == 'Send' || videoState == 'SendReceive'
debug "videoState was #{videoState}. We're done!"
delete .videoEnabled
return callback()
unless _.get(currentState, 'modality.state') == 'Connected'
debug 'not connected. waiting till next time'
return callback()
unless _.get(currentState, 'video.actions.Start') || _.get(currentState, 'video.actions.Resume')
debug "I can't resume or start the video. waiting until next time"
return callback()
debug "Starting video"
.startVideo null, callback
module.exports = Connector