]>
git.r.bdr.sh - rbdr/dead-drop/blob - lib/controllers/recordings.js
3 const Joi
= require('joi');
4 const Pify
= require('pify');
5 const Redis
= require('redis');
6 const Twilio
= require('twilio');
10 internals
.kContentType
= 'application/xml'; // The content type used to respond
11 internals
.kLanguage
= 'es-mx'; // the language to use
12 internals
.kMaxMessageLength
= 30; // max message length in seconds
13 internals
.kRecordingsSet
= 'recordings';
14 internals
.kRecordMessage
= 'Graba tu mensaje despues del bip y ' +
15 'presiona cualquier tecla para finalizar. '; // the recording message
16 internals
.kConfirmationMessage
= 'Gracias. Tu mensaje es el número: ';
17 internals
.kNotFoundMessage
= 'Mensaje no encontrado. Adiós!';
19 internals
.kRecordingSchema
= Joi
.object().keys({
20 url: Joi
.string().required()
24 * Handles the HTTP requests for the recording menu
26 * @class RecordingsController
27 * @param {DeadDrop.tConfiguration} config The configuration to
30 module
.exports
= internals
.RecordingsController
= class RecordingsController
{
33 this._redis
= Redis
.createClient(config
.redis
);
35 // Log an error if it happens.
36 this._redis
.on('error', (err
) => {
43 * Start recording process
45 * @function startRecording
46 * @memberof RecordingsController
48 * @return {generator} a koa compatible handler generator function
52 return function * () {
54 const response
= new Twilio
.TwimlResponse();
56 // the action will default to post in the same URL, so no change
58 response
.say(internals
.kRecordMessage
, { language: internals
.kLanguage
})
60 maxLength: internals
.kMaxMessageLength
63 this.type
= internals
.kContentType
;
64 this.body
= response
.toString();
69 * Saves the recording for later use
71 * @function saveRecording
72 * @memberof RecordingsController
74 * @return {generator} a koa compatible handler generator function
80 return function * () {
82 const zadd
= Pify(self
._redis
.zadd
.bind(self
._redis
));
84 const response
= new Twilio
.TwimlResponse();
86 const id
= Date
.now().toString().substr(2,10);
87 const url
= this.request
.body
.RecordingUrl
;
88 const separatedId
= id
.split('').join('. ');
93 yield self
._validate(recording
).catch((err
) => {
95 this.throw(err
.message
, 422);
98 // Add to ordered set for quick fetches, and set for random fetches
99 yield zadd(internals
.kRecordingsSet
, parseInt(id
), url
);
101 response
.say(`${internals.kConfirmationMessage}${separatedId}`, { language: internals
.kLanguage
});
103 this.type
= internals
.kContentType
;
104 this.body
= response
.toString();
111 * @function getRecording
112 * @memberof RecordingsController
114 * @return {generator} a koa compatible handler generator function
120 return function * (id
) {
124 const zcard
= Pify(self
._redis
.zcard
.bind(self
._redis
));
125 const zrange
= Pify(self
._redis
.zrange
.bind(self
._redis
));
126 const zscore
= Pify(self
._redis
.zscore
.bind(self
._redis
));
127 const zrangebyscore
= Pify(self
._redis
.zrangebyscore
.bind(self
._redis
));
129 const response
= new Twilio
.TwimlResponse();
133 const maxNumber
= yield zcard(internals
.kRecordingsSet
);
134 const index
= Math
.floor(Math
.random() * maxNumber
); // get random between 0 and cardinality
135 location
= yield zrange(internals
.kRecordingsSet
, index
, index
);
138 location
= yield zrangebyscore(internals
.kRecordingsSet
, id
, id
);
141 if (location
&& location
.length
> 0) {
143 id
= yield zscore(internals
.kRecordingsSet
, location
[0]);
146 const separatedId
= id
.toString().split('').join('. ');
147 response
.play(location
[0]).say(separatedId
, { language: internals
.kLanguage
});
150 response
.say(internals
.kNotFoundMessage
, { language: internals
.kLanguage
});
153 this.type
= internals
.kContentType
;
154 this.body
= response
.toString();
158 // Validates the post schema
162 const validate
= Pify(Joi
.validate
.bind(Joi
));
163 return validate(post
, internals
.kRecordingSchema
);