Hal De vor 3 Jahren
Ursprung
Commit
0762114717
1 geänderte Dateien mit 61 neuen und 7 gelöschten Zeilen
  1. 61 7
      app/app.py

+ 61 - 7
app/app.py

@@ -250,7 +250,7 @@ async def celCallback(mngr: Manager, msg: Message):
         cid = app.cache['usermap'][firstMessage.CallerIDnum]
     uid = firstMessage.LinkedID
     if (msg.EventName == 'CHAN_START') and (lid != msg.UniqueID) and (not msg.Channel.startswith('Local/')):
-        if (True or (firstMessage.Context == 'from-pstn') or (firstMessage.get('groupCall',False))):#all calls 
+        if (msg.CallerIDnum!=''): # or (firstMessage.Context == 'from-pstn') or (firstMessage.get('groupCall',False))):#all calls 
            device = msg.CallerIDnum
            user = app.cache['usermap'][device]
            did = firstMessage.Exten
@@ -357,6 +357,17 @@ async def celCallback(mngr: Manager, msg: Message):
       if (lid in app.cache['calls']):
         app.cache['calls'][lid][varname]=value
 
+    if (msg.EventName == 'USER_DEFINED') and (msg.UserDefType == 'CALLBACK_POSTFIX'):
+      callback_type = msg.AppData.split(',')[1]
+      postfix = msg.AppData.split(',')[2]
+      values = msg.AppData.split(',')[3:]
+      _cb = {'asteriskCallId':msg.LinkedID}
+      for value in values:
+        vn,vv = value.split('=')
+        _cb[vn] = vv
+      reply = await doCallbackPostfix(callback_type,postfix, _cb)
+      
+
 async def getCDR(start=None,
                  end=None,
                  table='cdr',
@@ -482,6 +493,22 @@ async def doCallback(entity, msg):
     app.logger.warning('No callback url defined for {}'.format(entity))
   return None
 
+async def doCallbackPostfix(entity,postfix, msg):
+  row = await db.fetch_one(query='SELECT url FROM callback_urls WHERE device = :device', values={'device': entity})
+  if ((row is not None) and (row['url'].startswith('http')) and ('blackhole' not in row['url'])):
+    url = row["url"]+'/'+postfix
+    app.logger.warning(f'''POST {url} data: {str(msg)}''')
+    if not 'HTTP_CLIENT' in app.config:
+      await initHttpClient()
+    try:
+      reply = await app.config['HTTP_CLIENT'].post(url, json=msg)
+      return reply
+    except Exception as e:
+      app.logger.warning('callback error {}'.format(url))
+  else:
+    app.logger.warning('No callback url defined for {}'.format(entity))
+  return None
+
 @app.before_first_request
 async def initHttpClient():
   app.config['HTTP_CLIENT'] = aiohttp.ClientSession(loop=main_loop,
@@ -1095,11 +1122,12 @@ class Originate(Resource):
     #  else:
     #    return errorReply(reply.message)
 
-@app.route('/autocall1/<numberA>/<numberB>')
-class Autocall1(Resource):
+@app.route('/autocall/<numberA>/<numberB>')
+class Autocall(Resource):
   @authRequired
   @app.param('numberA', 'User calling first', 'path')
   @app.param('numberB', 'user calling after numberA enter DTMF 2', 'path')
+  @app.param('callid', 'callid to be returned in callback', 'query')
   @app.response(HTTPStatus.OK, 'Json reply')
   @app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
   async def get(self, numberA, numberB):
@@ -1107,14 +1135,16 @@ class Autocall1(Resource):
     '''
     if  (not request.admin):
       abort(401)
-
+    callid = request.args.get('callid', None)
     _act = { 'Action':'Originate',
-             'Channel':'Local/{}@autocall1-legA'.format(numberA),
-             'Context':'autocall1-legB',
+             'Channel':'Local/{}@autocall-legA'.format(numberA),
+             'Context':'autocall-legB',
              'Exten':numberB,
              'Priority': '1',
              'Async':'true',
-             'Callerid': '{} <{}>'.format(2898, 2898)}
+             'Callerid': '{} <{}>'.format(1000, 1000),
+             'Variable': '__callid={}'.format(callid)
+             }
     app.logger.warning(_act)
     await manager.send_action(_act)
     return successfullyOriginated(numberA, numberB)
@@ -1557,5 +1587,29 @@ class QueueLeaveCallback(Resource):
         url = row['url']
     return successCommonCallbackURL('queueLeave', url)
 
+
+@app.route('/callback/<type>')
+class CommonCallback(Resource):
+  @authRequired
+  @app.param('type', 'Callback type', 'path')
+  @app.param('url', 'used to set the Callback url for the autocall', 'query')
+  @app.response(HTTPStatus.OK, 'JSON data {"url":url}')
+  @app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
+  async def get(self,type):
+    '''Returns and sets Autocall callback url.
+    '''
+    if not request.admin:
+      abort(401)
+    url = request.args.get('url', None)
+    if url is not None:
+      await db.execute(query='REPLACE INTO callback_urls (device, url) VALUES (:device, :url)',
+                       values={'device': type,'url': url})
+    else:
+      row = await db.fetch_one(query='SELECT url FROM callback_urls WHERE device = :device',
+                               values={'device': type})
+      if row is not None:
+        url = row['url']
+    return successCommonCallbackURL(type, url)
+
 manager.connect()
 app.run(loop=main_loop, host='0.0.0.0', port=app.config['PORT'])