@jcolp here is the code snippet
#!/usr/bin/python3
import asyncio
import aioari
import logging
import speech_recognition as sr
import random
import time
import math
import json
import requests
import logging
from text2speech import *
from check_keys import *
from bot_logger_config import *
from db_logger import *
from datetime import datetime
from aiohttp.web_exceptions import HTTPError, HTTPNotFound
import os
ast_url = os.getenv(“AST_URL”,“http://localhost:8088/”)
ast_user = os.getenv(“AST_USR”,“ariuser”)
ast_pass = os.getenv(“AST_PASS”,“aripass”)
define an endpoint for originating call and patching it to caller
ast_outgoing = os.getenv(“AST_OUTGOING”, ‘PJSIP/102’)
Define your ARI application
ast_app = os.getenv(“AST_APP”, “voice_bot_app”)
#log to file function
log_me = bot_logger_config(ast_app)
#bot name hard coded for now
bot_name = ‘bot_sample_1’
holding_bridge = None
now = datetime.now()
digits = [i for i in range(0, 10)]
random_str = “”
for i in range(6):
index = math.floor(random.random() *10)
random_str += str(digits[index])
Function to handle the ARI StasisStart event
async def stasis_start(objs, event):
channel = objs[‘channel’]
print(f"StasisStart: {channel.json}")
channel_name = channel.json
chan_name = json.dumps(channel_name)
chan_name1 = json.loads(chan_name)
global chan_call_id
global chan_fin_name
global chan_fin_num
chan_call_id = chan_name1['id']
chan_fin_name = chan_name1['name']
chan_fin_num = chan_name1['caller']['number']
logger_message = 'Incoming Call from'+chan_fin_num
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message= 'Channel Created'+chan_fin_name
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message='Call ID'+chan_call_id
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
# Answer the incoming call
await channel.answer()
logging.warning('Call Answered by bot')
tts_text = 'Welcome to Acme financial Services, I am your virtual assistant, How may I help you today'
get_t2sp = create_text_2_speech(tts_text)
#print(get_t2sp)
logger_message = 'Bot Playing Welcome Prompt' + get_t2sp
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
menu_select_prompt = 'Please let me know from the options , Credit Card, Home Loan, Car Loan, Over Draft, Loan Transfer'
get_menu_t2sp = create_text_2_speech_selection(menu_select_prompt)
logger_message = 'Bot Playing Menu Prompt '+ get_menu_t2sp
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
# Play a prompt asking the user to speak
playback = await channel.play(media="sound:"+get_t2sp)
#playback selection menu for caller
playback = await channel.play(media="sound:"+get_menu_t2sp)
time.sleep(14)
logger_message = 'Awating callers response'
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
# Record the user's voice
audio_file = random_str
global fin_audio
fin_audio ='/var/spool/asterisk/recording/'+audio_file+'.wav'
print(fin_audio)
logger_message = 'Caller Recording stored at' + fin_audio
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
await channel.record(
name=audio_file,
format='wav',
ifExists='overwrite',
maxDurationSeconds='10',
maxSilenceSeconds='5',
beep='false',
terminateOn='*',
)
time.sleep(15)
## create a global bridge
## used to transfer call to live agent
global holding_bridge
bridges = [b for b in (await client.bridges.list())
if b.json['bridge_type'] == 'holding']
if bridges:
holding_bridge = bridges[0]
print ("Using bridge %s" % holding_bridge.id)
else:
holding_bridge = await client.bridges.create(type='holding')
print ("Created bridge %s" % holding_bridge.id)
async def safe_hangup(channel):
try:
await channel.hangup()
except HTTPError as e:
if e.response.status_code != HTTPNotFound.status_code:
raise
async def transfer_to_queue():
print('Transferring to Live Agent')
logging.warning('Transferring to Live Agent')
eve_args = event['args']
if event['args'] == ['dialed']:
return
logging.warning('received event %s'% eve_args)
incoming = objs['channel']
print('I am here %s'% incoming)
await incoming.answer()
p = await incoming.play(media="sound:pls-wait-connect-call")
print(p)
await asyncio.sleep(2)
h = await holding_bridge.addChannel(channel=incoming.id)
print(h)
# Originate the outgoing channel
outgoing = await client.channels.originate(endpoint=ast_outgoing, app=ast_app, appArgs="dialed")
print("OUT:",outgoing)
outgoing.on_event('ChannelDestroyed',lambda *args: safe_hangup(incoming))
#print("Bridging",channel)
print('Bridging', outgoing)
#bridge = holding_bridge
bridge = await client.bridges.create(type='mixing')
await outgoing.answer()
print(incoming.id)
print(outgoing.id)
incom_add = await bridge.addChannel(channel=incoming.id)
print(incom_add)
logging.warning('adding incoming channel ', incom_add)
#await bridge.addChannel(channel=[incoming.id, outgoing.id])
print('Bridged',incoming,outgoing)
async def bot_2_human():
menu_un = 'I am unable to understand you, please wait while I transfer your call to my Human partner'
mn_un = create_text_2_speech_general(menu_un)
playback = await channel.play(media='sound:'+mn_un)
#t2q = await transfer_to_queue()
t2q = await transfer_to_queue()
async def go_to_menus(gtext):
##get_menus = create_text_2_speech_menu(gtext)
menu_ok = 'Ok, I can help you with'+ gtext
get_menus_ok = create_text_2_speech_menu(menu_ok)
playback = await channel.play(media='sound:'+get_menus_ok)
if(gtext == "home loan"):
hl = await home_loans()
hl_msg = create_text_2_speech_general(hl)
playback = await channel.play(media='sound:'+hl_msg)
logger_message = 'Bot Response for Selection ' + gtext +':'+ hl
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message = 'Bot Call Hangup' + log_time
logging.warning(logger_message)
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
time.sleep(10)
await channel.hangup()
elif(gtext == "credit card"):
ccr = await credit_card()
cc_msg = create_text_2_speech_general(ccr)
playback = await channel.play(media='sound:'+cc_msg)
logger_message = 'Bot Response for Selection ' + gtext +':'+ ccr
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message = 'Bot Call Hangup' + log_time
logging.warning(logger_message)
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
time.sleep(10)
await channel.hangup()
elif(gtext == "car loan"):
crln = await car_loan()
crln_msg = create_text_2_speech_general(crln)
playback = await channel.play(media='sound:'+crln_msg)
logger_message = 'Bot Response for Selection ' + gtext +':'+ crln
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message = 'Bot Call Hangup' + log_time
logging.warning(logger_message)
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
time.sleep(10)
await channel.hangup()
elif(gtext == "over draft"):
ovdr = await over_draft()
od_msg = create_text_2_speech_general(ovdr)
playback = await channel.play(media='sound:'+od_msg)
logger_message = 'Bot Response for Selection ' + gtext +':'+ ovdr
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message = 'Bot Call Hangup' + log_time
logging.warning(logger_message)
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
time.sleep(10)
await channel.hangup()
elif(gtext == "loan transfer"):
lntr = await loan_transfer()
lntr_msg = create_text_2_speech_general(lntr)
playback = await channel.play(media='sound:'+lntr_msg)
logger_message = 'Bot Response for Selection ' + gtext +':'+ lntr
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
logger_message = 'Bot Call Hangup' + log_time
logging.warning(logger_message)
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
time.sleep(10)
await channel.hangup()
else:
bt2h = await bot_2_human()
async def recognize_speech(final_audio):
recognizer = sr.Recognizer()
with sr.AudioFile(final_audio) as source:
audio_data = recognizer.record(source)
try:
text = recognizer.recognize_google(audio_data)
logger_message = 'Caller Spoke ' + text
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
gt_key = await bot_keys(text)
if gt_key != text:
logger_message = 'No Response defined, Bot will transfer call to Human'
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
hum_tr = await bot_2_human()
elif gt_key == text:
logger_message='Valid Response , Bot will proceed for Menus'
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
await go_to_menus(text)
except sr.UnknownValueError:
print("Speech Recognition could not understand audio")
logger_message = 'Speech Recognition could not understand audio'
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
except sr.RequestError as e:
print("Unknown exception")
logger_message="Unknown exception"
logging.warning(logger_message)
log_time = now.strftime(("%d/%m/%Y %H:%M:%S"))
getdb_bot_logger_events(bot_name,chan_fin_num,logger_message,log_time,chan_call_id)
recspeech = await recognize_speech(fin_audio)
Function to handle the ARI StasisEnd event
async def stasis_end(channel, event):
#print(“END”, channel, event)
print(f"StasisEnd: {channel.json}")
await holding_bridge.destroy()
sessions = {}
loop = asyncio.get_event_loop()
client = loop.run_until_complete(aioari.connect(ast_url,ast_user,ast_pass))
client.on_channel_event(“StasisStart”,stasis_start)
client.on_channel_event(“StasisEnd”, stasis_end)
loop.run_until_complete(client.run(apps=ast_app))