bfc3743108506a64a4b19c04ed8d19c552032886
[motion.git] / server / config / kue.fax.js
1 'use strict';
2
3 var _ = require('lodash');
4 var config = require('./environment');
5 var async = require('async');
6 var sockets = {};
7 var User = require('../models').User;
8 var Event = require('../models').Event;
9 var FaxQueue = require('../models').FaxQueue;
10
11 function invite(data, i, j, io, done) {
12
13   var elapsed = 0;
14   var timeout = 0;
15   var body = [];
16   var users = [];
17
18   if (i === data.applications.length) {
19     body.push({
20       name: 'UNASSIGNED',
21       channel: 'FAX',
22       FaxRoomId: data.roomId,
23       FaxAccountId: data.accountId
24     });
25
26     traceEvent(body, function() {});
27
28     done(new Error('DialPlan ended..'));
29     return;
30   }
31
32   if (data.applications[i].FaxQueue) {
33
34     timeout = (((data.applications[i].timeout - elapsed) > data.applications[i].FaxQueue.timeout) ?
35       data.applications[i].FaxQueue.timeout : (data.applications[i].timeout - elapsed));
36
37     switch (data.applications[i].FaxQueue.strategy) {
38       case 'rrmemory':
39         body.push({
40           name: 'ATTEMPT',
41           channel: 'FAX',
42           timeout: timeout,
43           UserId: data.applications[i].users[j].id,
44           FaxRoomId: data.roomId,
45           FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
46           FaxAccountId: data.accountId,
47           FaxApplicationId: data.applications[i].id
48         });
49         users.push(data.applications[i].users[j].id);
50         break;
51       case 'beepall':
52         data.applications[i].users.forEach(function(user) {
53           var item = {
54             name: 'ATTEMPT',
55             channel: 'FAX',
56             timeout: timeout,
57             UserId: user.id,
58             FaxRoomId: data.roomId,
59             FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
60             FaxAccountId: data.accountId,
61             FaxApplicationId: data.applications[i].id
62           }
63           body.push(item);
64           users.push(user.id);
65         });
66         break;
67       default:
68         console.log('Strategy unknown..');
69     }
70
71     traceEvent(body, function() {
72       emitEvent(users, 'FAX:QUEUE:' + data.applications[i].FaxQueue.id, {
73         timeout: timeout,
74         roomId: data.roomId
75       }, function(userId) {
76         clearInterval(qInterval);
77         clearTimeout(aTimeout);
78         var body = [{
79           name: 'ASSIGNED',
80           channel: 'FAX',
81           timeout: timeout,
82           UserId: userId,
83           FaxRoomId: data.roomId,
84           FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
85           FaxAccountId: data.accountId,
86           FaxApplicationId: data.applications[i].id
87         }];
88         traceEvent(body, function() {
89           done();
90         });
91       });
92     });
93
94   } else {
95     // SET AGENT APPLICATION TIMEOUT
96     timeout = data.applications[i].timeout;
97
98     users.push(data.applications[i].users[j].id);
99     body = [{
100       name: 'ATTEMPT',
101       channel: 'FAX',
102       timeout: timeout,
103       UserId: data.applications[i].users[j].id,
104       FaxRoomId: data.roomId,
105       FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
106       FaxAccountId: data.accountId,
107       FaxApplicationId: data.applications[i].id
108     }];
109     traceEvent(body, function() {
110       emitEvent(users, 'FAX:AGENT:' + data.applications[i].users[j].id, {
111         timeout: data.applications[i].timeout,
112         roomId: data.roomId
113       }, function(userId) {
114         clearInterval(qInterval);
115         clearTimeout(aTimeout);
116         var body = [{
117           name: 'ASSIGNED',
118           channel: 'FAX',
119           timeout: timeout,
120           UserId: userId,
121           FaxRoomId: data.roomId,
122           FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
123           FaxAccountId: data.accountId,
124           FaxApplicationId: data.applications[i].id
125         }];
126         traceEvent(body, function() {
127           done();
128         });
129       });
130     });
131
132   }
133
134   var qInterval = setInterval(function() {
135     var timeout = 0;
136     // NEXT AGENT
137     j++;
138
139     if (j === data.applications[i].users.length) {
140       j = 0;
141     }
142
143     if (data.applications[i].FaxQueue) {
144
145       elapsed += data.applications[i].FaxQueue.timeout;
146
147       timeout = (((data.applications[i].timeout - elapsed) > data.applications[i].FaxQueue.timeout) ?
148         data.applications[i].FaxQueue.timeout : (data.applications[i].timeout - elapsed));
149
150       var body = [];
151       var users = [];
152
153       switch (data.applications[i].FaxQueue.strategy) {
154         case 'rrmemory':
155           var item = {
156             name: 'ATTEMPT',
157             channel: 'FAX',
158             timeout: timeout,
159             UserId: data.applications[i].users[j].id,
160             FaxRoomId: data.roomId,
161             FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
162             FaxAccountId: data.accountId,
163             FaxApplicationId: data.applications[i].id
164           };
165           body.push(item);
166           users.push(data.applications[i].users[j].id);
167           break;
168         case 'beepall':
169           data.applications[i].users.forEach(function(user) {
170             var item = {
171               name: 'ATTEMPT',
172               channel: 'FAX',
173               timeout: timeout,
174               UserId: user.id,
175               FaxRoomId: data.roomId,
176               FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
177               FaxAccountId: data.accountId,
178               FaxApplicationId: data.applications[i].id
179             }
180             body.push(item);
181             users.push(user.id);
182           });
183           break;
184         default:
185           console.log('Strategy unknown..');
186       }
187
188       traceEvent(body, function() {
189         emitEvent(users, 'FAX:QUEUE:' + data.applications[i].FaxQueue.id, {
190           timeout: timeout,
191           roomId: data.roomId
192         }, function(userId) {
193           console.log('userId', userId);
194           clearInterval(qInterval);
195           clearTimeout(aTimeout);
196           var body = [{
197             name: 'ASSIGNED',
198             channel: 'FAX',
199             timeout: timeout,
200             UserId: userId,
201             FaxRoomId: data.roomId,
202             FaxQueueId: data.applications[i].FaxQueue ? data.applications[i].FaxQueue.id : null,
203             FaxAccountId: data.accountId,
204             FaxApplicationId: data.applications[i].id
205           }];
206           traceEvent(body, function() {
207             done();
208           });
209         });
210       });
211
212     }
213   }, data.applications[i].FaxQueue ? data.applications[i].FaxQueue.timeout * 1000 : data.applications[i].timeout * 1000);
214
215   var aTimeout = setTimeout(function() {
216     clearInterval(qInterval);
217     invite(data, ++i, 0, io, done);
218   }, data.applications[i].timeout * 1000);
219 }
220
221 function processing(job, done, io) {
222   var elapsed = 0;
223   var applications = [
224     // INIT
225     function(callback) {
226       callback(null, job.data, done, io);
227     },
228     // BUILDING APPLICATION STRUCTURE
229     function(data, done, io, callback) {
230       for (var i = 0; i < data.applications.length; i++) {
231         switch (data.applications[i].app) {
232           case 'agent':
233             if (!data.applications[i].users) {
234               data.applications[i].users = [];
235             }
236
237             data.applications[i].users.push(data.applications[i].User);
238             break;
239           case 'queue':
240
241             for (var j = 0; j < data.applications[i].FaxQueue.Users.length; j++) {
242
243               if (!data.applications[i].users) {
244                 data.applications[i].users = [];
245               }
246
247               data.applications[i].users.push(
248                 data.applications[i].FaxQueue.Users[j]
249               );
250             }
251
252             break;
253           default:
254
255         }
256       }
257
258       callback(null, data, done, io);
259     }
260   ];
261
262   async.waterfall(applications,
263     // optional callback
264     function(err, data, done, io) {
265       invite(data, 0, 0, io, done);
266     });
267 }
268
269 function traceEvent(body, cb) {
270   Event
271     .bulkCreate(body)
272     .then(function() {
273       if (cb) {
274         cb();
275       }
276     })
277     .catch(function(err) {
278       console.error(err);
279     });
280 }
281
282 function emitEvent(users, event, params, cb) {
283   users.forEach(function(user) {
284     console.log(event, user);
285     if (sockets[user]) {
286       sockets[user].emit(event, params, cb);
287     }
288   });
289 }
290
291 module.exports = function(io, kue) {
292
293   var kueFax = kue.createQueue();
294
295   /**
296    * Queue processing statement
297    */
298   kueFax.process('fax', 20, function(job, done) {
299     processing(job, done, io);
300   });
301
302   require('../api/fax_room/fax_room.kue').register(kueFax);
303
304   io.on('connection', function(socket) {
305
306     if (socket.handshake.query.userId) {
307       sockets[socket.handshake.query.userId] = socket;
308     }
309
310     socket.on('disconnect', function() {
311       if (sockets[socket.handshake.query.userId]) {
312         delete sockets[socket.handshake.query.userId];
313       }
314     });
315   });
316 }