mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-05 20:41:34 +08:00
110 lines
2.8 KiB
JavaScript
110 lines
2.8 KiB
JavaScript
const _ = require('lodash');
|
|
const moment = require('moment');
|
|
const fs = require('./fs');
|
|
const control = require('./control');
|
|
const debug = require('debug')('cc-switch:dialplan');
|
|
const { access } = require('fs');
|
|
const minio = require('./minio');
|
|
|
|
class Dialplan {
|
|
constructor(id, concurrency, sips) {
|
|
this.id = id;
|
|
this.concurrency = concurrency;
|
|
this.tasks = [];
|
|
this.sips = sips;
|
|
this.state = 'create';
|
|
}
|
|
|
|
start(cb) {
|
|
debug('开始呼叫计划: %o', this.id);
|
|
this.time = setInterval(() => this.loop(), 1000);
|
|
this.start = 'start';
|
|
this.cb = cb;
|
|
}
|
|
|
|
callTask(to, channel) {
|
|
debug('呼叫目标号码: %s', to);
|
|
|
|
let message = { to, channel, dialplan: this.id, type: 'callout' };
|
|
let call = fs.call(to);
|
|
call.sips = this.sips;
|
|
let removeThisCall = () => _.remove(this.tasks, call);
|
|
|
|
call.on('channel_answer', uuid => {
|
|
debug('用户接听 %s', to);
|
|
message.uuid = uuid;
|
|
message.from = call.sip;
|
|
message.ops = 'answer';
|
|
message.createtime = moment().valueOf();
|
|
control.sendEvent(message);
|
|
});
|
|
|
|
call.on('channel_hangup', () => {
|
|
debug('用户挂机 %s', to);
|
|
message.ops = 'hangup';
|
|
message.createtime = moment().valueOf();
|
|
removeThisCall();
|
|
|
|
if (call.state != 'call') {
|
|
let file = `/usr/recordings/archive/${call.uuid}.wav`;
|
|
message.record = `${moment().format('YYYY-MM-DD')}/${call.uuid}.wav`;
|
|
|
|
access(file, err => {
|
|
if (err) {
|
|
debug('录音文件不存在: %s', call.uuid);
|
|
} else {
|
|
debug('上传录音: %s', call.uuid);
|
|
|
|
setTimeout(() => {
|
|
minio.fPutObject('chatopera', message.record, file).catch(err => {
|
|
debug('上传录音失败 %s error: %o', call.uuid, err);
|
|
});
|
|
}, 5000);
|
|
}
|
|
});
|
|
}
|
|
|
|
control.sendEvent(message);
|
|
});
|
|
|
|
call.on('error', () => {
|
|
debug('呼叫错误 %s', to);
|
|
message.ops = 'hangup';
|
|
removeThisCall();
|
|
control.sendEvent(message);
|
|
});
|
|
|
|
return call;
|
|
}
|
|
|
|
async loop() {
|
|
// debug('呼叫计划循环: %s', this.id);
|
|
while (this.tasks.length < this.concurrency) {
|
|
let info = await control.getNextCall(this.id);
|
|
|
|
if (info) {
|
|
let { to, channel } = info;
|
|
let call = this.callTask(to, channel);
|
|
this.tasks.push(call);
|
|
} else {
|
|
debug('完成呼叫计划: %s', this.id);
|
|
this.start = 'finish';
|
|
clearInterval(this.time);
|
|
if (this.cb) {
|
|
this.cb();
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
async stop() {
|
|
debug('停止呼叫计划: %s', this.id);
|
|
clearInterval(this.time);
|
|
// await Promise.all(this.tasks);
|
|
}
|
|
}
|
|
|
|
module.exports = exports = Dialplan;
|