Skip to content

Commit

Permalink
- Fix conversation lookups in twilio
Browse files Browse the repository at this point in the history
- Modify Conversation model to include twilio_call_sid in indexes
- Update TwilioVoice handler to not create a conversation entry for missed calls
- Simplify logic for determining if call will be rejected
- rename TwilioVoice.from_data -> TwilioVoice.from_webhook_data
  • Loading branch information
devxpy committed Aug 28, 2024
1 parent 95161a6 commit af62097
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
1 change: 1 addition & 0 deletions bots/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"twilio_username",
"twilio_password",
"twilio_use_missed_call",
"twilio_fresh_conversation_per_call",
"twilio_initial_text",
"twilio_initial_audio_url",
"twilio_waiting_text",
Expand Down
17 changes: 15 additions & 2 deletions bots/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,9 @@ class Meta:
"slack_channel_is_personal",
],
),
models.Index(fields=["bot_integration", "twilio_phone_number"]),
models.Index(
fields=["bot_integration", "twilio_phone_number", "twilio_call_sid"]
),
models.Index(fields=["-created_at", "bot_integration"]),
]

Expand All @@ -1121,7 +1123,18 @@ def __str__(self):
def get_display_name(self):
return (
(self.wa_phone_number and self.wa_phone_number.as_international)
or (self.twilio_phone_number and self.twilio_phone_number.as_international)
or " | ".join(
filter(
None,
[
(
self.twilio_phone_number
and self.twilio_phone_number.as_international
),
self.twilio_call_sid,
],
)
)
or self.ig_username
or self.fb_page_name
or " in #".join(
Expand Down
25 changes: 17 additions & 8 deletions daras_ai_v2/twilio_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ def __init__(self, data: dict):
twilio_account_sid=account_sid, twilio_phone_number=data["To"][0]
)
self.convo = Conversation.objects.get_or_create(
bot_integration=bi, twilio_phone_number=data["From"][0]
bot_integration=bi,
twilio_phone_number=data["From"][0],
twilio_call_sid="",
)[0]

self.bot_id = bi.twilio_phone_number.as_e164
Expand Down Expand Up @@ -86,7 +88,7 @@ class TwilioVoice(BotInterface):
platform = Platform.TWILIO

@classmethod
def from_data(cls, data: dict):
def from_webhook_data(cls, data: dict):
## data samples:
# {'AccountSid': ['XXXX'], 'ApiVersion': ['2010-04-01'], 'CallSid': ['XXXX'], 'CallStatus': ['ringing'], 'CallToken': ['XXXX'], 'Called': ['XXXX'], 'CalledCity': ['XXXX'], 'CalledCountry': ['XXXX'], 'CalledState': ['XXXX'], 'CalledZip': ['XXXX'], 'Caller': ['XXXX'], 'CallerCity': ['XXXX'], 'CallerCountry': ['XXXX'], 'CallerState': ['XXXX'], 'CallerZip': ['XXXX'], 'Direction': ['inbound'], 'From': ['XXXX'], 'FromCity': ['XXXX'], 'FromCountry': ['XXXX'], 'FromState': ['XXXX'], 'FromZip': ['XXXX'], 'StirVerstat': ['XXXX'], 'To': ['XXXX'], 'ToCity': ['XXXX'], 'ToCountry': ['XXXX'], 'ToState': ['XXXX'], 'ToZip': ['XXXX']}
# {'AccountSid': ['XXXX'], 'ApiVersion': ['2010-04-01'], 'CallSid': ['XXXX'], 'CallStatus': ['in-progress'], 'Called': ['XXXX'], 'CalledCity': ['XXXX'], 'CalledCountry': ['XXXX'], 'CalledState': ['XXXX'], 'CalledZip': ['XXXX'], 'Caller': ['XXXX'], 'CallerCity': ['XXXX'], 'CallerCountry': ['XXXX'], 'CallerState': ['XXXX'], 'CallerZip': ['XXXX'], 'Confidence': ['0.9128386'], 'Direction': ['inbound'], 'From': ['XXXX'], 'FromCity': ['XXXX'], 'FromCountry': ['XXXX'], 'FromState': ['XXXX'], 'FromZip': ['XXXX'], 'Language': ['en-US'], 'SpeechResult': ['Hello.'], 'To': ['XXXX'], 'ToCity': ['XXXX'], 'ToCountry': ['XXXX'], 'ToState': ['XXXX'], 'ToZip': ['XXXX']}
Expand All @@ -96,34 +98,41 @@ def from_data(cls, data: dict):
if account_sid == settings.TWILIO_ACCOUNT_SID:
account_sid = ""
call_sid = data["CallSid"][0]
caller_number = data["Caller"][0]
user_number, bot_number = data["From"][0], data["To"][0]
try:
# cases where user is calling the bot
bi = BotIntegration.objects.get(
twilio_account_sid=account_sid, twilio_phone_number=bot_number
)
will_be_missed = bi.twilio_use_missed_call
except BotIntegration.DoesNotExist:
# cases where bot is calling the user
user_number, bot_number = bot_number, user_number
bi = BotIntegration.objects.get(
twilio_account_sid=account_sid, twilio_phone_number=bot_number
)
will_be_missed = False

will_be_missed = caller_number == user_number and bi.twilio_use_missed_call
if will_be_missed:
# for call_sids that we will reject and re-call, the convo is not used, so we don't want to create a new one
convo = None
if bi.twilio_fresh_conversation_per_call and not will_be_missed:
# for calls that we will reject and callback, the convo is not used so we don't want to create one
convo = Conversation(
bot_integration=bi,
twilio_phone_number=user_number,
twilio_call_sid=call_sid,
)
elif bi.twilio_fresh_conversation_per_call:
convo = Conversation.objects.get_or_create(
bot_integration=bi,
twilio_phone_number=user_number,
twilio_call_sid=call_sid,
)[0]
else:
convo = Conversation.objects.get_or_create(
bot_integration=bi, twilio_phone_number=user_number
bot_integration=bi,
twilio_phone_number=user_number,
twilio_call_sid="",
)[0]

return cls(
convo,
text=data.get("SpeechResult", [None])[0],
Expand Down
4 changes: 2 additions & 2 deletions routers/twilio_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def twilio_voice_call(
"""Handle incoming Twilio voice call."""

try:
bot = TwilioVoice.from_data(data)
bot = TwilioVoice.from_webhook_data(data)
except BotIntegration.DoesNotExist as e:
logger.debug(f"could not find bot integration for {data=} {e=}")
resp = VoiceResponse()
Expand Down Expand Up @@ -198,7 +198,7 @@ def twilio_voice_call_asked(
):
"""After the initial call, the user has asked a question via Twilio/Gooey ASR. Handle their question."""

bot = TwilioVoice.from_data(data)
bot = TwilioVoice.from_webhook_data(data)
resolve_twilio_tts_voice(bot)
background_tasks.add_task(msg_handler, bot)

Expand Down

0 comments on commit af62097

Please sign in to comment.