-
Notifications
You must be signed in to change notification settings - Fork 1
/
sipgate.coffee
142 lines (116 loc) · 4.33 KB
/
sipgate.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
class Sipgate
_calls: {}
_callEvents: {}
_Calls: new Meteor.Collection('_sipgateIoCalls')
response: new SipgateResponse()
constructor: ->
self = this
HTTP.methods
"io/call/:userId": post: (data) ->
domain = this.requestHeaders.host
proto = this.requestHeaders["x-forwarded-proto"]
if proto
protocols = proto.split ","
protocol = protocols[0]
url = protocol+"://"+domain+"/"
else
url = Meteor.absoluteUrl()
callData = Sipgate.parsePost data
callData.userId = this.params.userId
currentCall = new Call(callData)
self._Calls.insert currentCall
actions = self._onEvent 'newCall', currentCall
userEvents = self._events()
if userEvents.answer
self.response.setAnswerUrl(url+"io/answer/"+this.params.userId)
if userEvents.hangup
self.response.setHangupUrl(url+"io/hangup/"+this.params.userId)
if actions
for action in actions
if action instanceof SipgateResponseActionGather
action.setDataUrl(url+"io/dtmf/"+this.params.userId)
self.response.setActions(actions)
response = self.response.generateResponseXml()
this.setContentType 'application/xml'
response+"\n"
"io/answer/:userId": post: (data) ->
callData = Sipgate.parsePost data
callData.userId = this.params.userId
call = new Call(self._Calls.findOne _id:callData.callId)
call.answer(callData)
self._Calls.update _id:call._id, call
self._onEvent 'answer', call
response = """
<?xml version="1.0" encoding="UTF-8"?>
<Response><!--empty request--></Response>"""
this.setContentType 'application/xml'
response
"io/hangup/:userId": post: (data) ->
callData = Sipgate.parsePost data
callData.userId = this.params.userId
call = new Call(self._Calls.findOne _id:callData.callId)
call.hangup(callData.cause)
self._Calls.update _id:call._id, call
self._onEvent 'hangup', call
self._Calls.remove _id:call._id
response = """
<?xml version="1.0" encoding="UTF-8"?>
<Response><!--empty request--></Response>"""
this.setContentType 'application/xml'
response
"io/dtmf/:userId": post: (data) ->
domain = this.requestHeaders.host
proto = this.requestHeaders["x-forwarded-proto"]
if proto
protocols = proto.split ","
protocol = protocols[0]
url = protocol+"://"+domain+"/"
else
url = Meteor.absoluteUrl()
callData = Sipgate.parsePost data
callData.userId = this.params.userId
call = new Call(self._Calls.findOne _id:callData.callId)
call.dtmf(callData.dtmf)
self._Calls.update _id:call._id, call
actions = self._onEvent 'dtmf', call
userEvents = self._events()
if userEvents.answer
self.response.setAnswerUrl(url+"io/answer/"+this.params.userId)
if userEvents.hangup
self.response.setHangupUrl(url+"io/hangup/"+this.params.userId)
if actions
for action in actions
if action instanceof SipgateResponseActionGather
action.setDataUrl(url+"io/dtmf/"+this.params.userId)
self.response.setActions(actions)
response = self.response.generateResponseXml()
this.setContentType 'application/xml'
response+"\n"
_onEvent: (eventType, call) ->
value = null
for callback in @_callEvents[eventType]
currentValue = callback call
if currentValue
value = currentValue
value
_events: ->
@_callEvents
@parsePost: (input="") ->
result = {}
parts = input.toString().split '&'
parts.forEach (part) ->
[key, value] = part.split '='
key = decodeURIComponent(key)
value = decodeURIComponent(value.replace(/\+/g," ")) #decodeURIComponent doesn't replace the +-encoded spaces :(
# There can be several user-params when calling a group
if (key == 'user[]')
if (!result['user']?)
result['user'] = []
result['user'].push(value)
else
result[key] = value
result
events: (events) ->
for key, value of events
@_callEvents[key] ?= []
@_callEvents[key].push value