Skip to content

Commit

Permalink
feat: phone call (testing)
Browse files Browse the repository at this point in the history
  • Loading branch information
shariquerik committed Aug 17, 2023
1 parent 4f4c156 commit b3abc00
Show file tree
Hide file tree
Showing 17 changed files with 676 additions and 6 deletions.
Empty file.
9 changes: 9 additions & 0 deletions crm/crm/doctype/twilio_agents/test_twilio_agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestTwilioAgents(FrappeTestCase):
pass
8 changes: 8 additions & 0 deletions crm/crm/doctype/twilio_agents/twilio_agents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Twilio Agents", {
// refresh(frm) {

// },
// });
78 changes: 78 additions & 0 deletions crm/crm/doctype/twilio_agents/twilio_agents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:user",
"creation": "2023-08-17 19:59:56.239729",
"default_view": "List",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"user",
"user_name",
"call_receiving_device",
"column_break_ljne",
"twilio_number"
],
"fields": [
{
"fieldname": "user",
"fieldtype": "Link",
"in_list_view": 1,
"label": "User",
"options": "User",
"unique": 1
},
{
"fieldname": "column_break_ljne",
"fieldtype": "Column Break"
},
{
"fieldname": "twilio_number",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Twilio Number",
"options": "Phone"
},
{
"fetch_from": "user.full_name",
"fieldname": "user_name",
"fieldtype": "Data",
"label": "User Name",
"read_only": 1
},
{
"default": "Computer",
"fieldname": "call_receiving_device",
"fieldtype": "Select",
"label": "Device",
"options": "Computer\nPhone"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-08-17 22:21:00.606384",
"modified_by": "Administrator",
"module": "CRM",
"name": "Twilio Agents",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
9 changes: 9 additions & 0 deletions crm/crm/doctype/twilio_agents/twilio_agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class TwilioAgents(Document):
pass
Empty file.
9 changes: 9 additions & 0 deletions crm/crm/doctype/twilio_settings/test_twilio_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestTwilioSettings(FrappeTestCase):
pass
8 changes: 8 additions & 0 deletions crm/crm/doctype/twilio_settings/twilio_settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Twilio Settings", {
// refresh(frm) {

// },
// });
76 changes: 76 additions & 0 deletions crm/crm/doctype/twilio_settings/twilio_settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2023-08-17 18:38:02.655918",
"default_view": "List",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"account_sid",
"api_key",
"api_secret",
"column_break_idds",
"auth_token",
"twiml_sid"
],
"fields": [
{
"fieldname": "account_sid",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Account SID",
"reqd": 1
},
{
"fieldname": "api_key",
"fieldtype": "Data",
"label": "API Key"
},
{
"fieldname": "api_secret",
"fieldtype": "Password",
"label": "API Secret"
},
{
"fieldname": "column_break_idds",
"fieldtype": "Column Break"
},
{
"fieldname": "auth_token",
"fieldtype": "Password",
"in_list_view": 1,
"label": "Auth Token",
"reqd": 1
},
{
"fieldname": "twiml_sid",
"fieldtype": "Data",
"label": "TwiML SID"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-08-17 18:38:02.655918",
"modified_by": "Administrator",
"module": "CRM",
"name": "Twilio Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
9 changes: 9 additions & 0 deletions crm/crm/doctype/twilio_settings/twilio_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class TwilioSettings(Document):
pass
105 changes: 105 additions & 0 deletions crm/twilio/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from werkzeug.wrappers import Response

import frappe
from twilio.rest import Client
from .twilio_handler import Twilio, IncomingCall

@frappe.whitelist()
def generate_access_token():
"""Returns access token that is required to authenticate Twilio Client SDK.
"""
twilio = Twilio.connect()
if not twilio:
return {}

from_number = frappe.db.get_value('Twilio Agents', frappe.session.user, 'twilio_number')
if not from_number:
return {
"ok": False,
"error": "caller_phone_identity_missing",
"detail": "Phone number is not mapped to the caller"
}

token=twilio.generate_voice_access_token(identity=frappe.session.user)
return {
'token': frappe.safe_decode(token)
}

@frappe.whitelist(allow_guest=True)
def voice(**kwargs):
"""This is a webhook called by twilio to get instructions when the voice call request comes to twilio server.
"""
def _get_caller_number(caller):
identity = caller.replace('client:', '').strip()
user = Twilio.emailid_from_identity(identity)
return frappe.db.get_value('Twilio Agents', user, 'twilio_number')

args = frappe._dict(kwargs)
twilio = Twilio.connect()
if not twilio:
return

assert args.AccountSid == twilio.account_sid
assert args.ApplicationSid == twilio.application_sid

# Generate TwiML instructions to make a call
from_number = _get_caller_number(args.Caller)
resp = twilio.generate_twilio_dial_response(from_number, args.To)

# call_details = TwilioCallDetails(args, call_from=from_number)
# create_call_log(call_details)
return Response(resp.to_xml(), mimetype='text/xml')

@frappe.whitelist(allow_guest=True)
def twilio_incoming_call_handler(**kwargs):
args = frappe._dict(kwargs)
# call_details = TwilioCallDetails(args)
# create_call_log(call_details)

resp = IncomingCall(args.From, args.To).process()
return Response(resp.to_xml(), mimetype='text/xml')

















# @frappe.whitelist(allow_guest=True)
# def twilio_incoming_call_handler(**kwargs):
# args = frappe._dict(kwargs)
# resp = VoiceResponse()

# resp.say("Thank you for calling! Have a great day.", voice='Polly.Amy')

# todo = frappe.get_doc({
# "doctype": "ToDo",
# "description": "Call from {0} to {1} is {2}".format(args.From, args.To, args.CallStatus),
# })
# todo.insert(ignore_permissions=True)


@frappe.whitelist()
def make_call(to, from_='+13134748669'):
application_sid = 'APa7a85c103b7477c8eb25e9a8aafae055'
account_sid = 'AC1a65d630772fbdb3a9a977c46aacef61'
auth_token = '1eb29b621c6a60f4afdde18160bc1e2d'
client = Client(account_sid, auth_token)

call = client.calls.create(
url='http://demo.twilio.com/docs/voice.xml',
to=to,
from_=from_
)

print(call.sid)
Loading

0 comments on commit b3abc00

Please sign in to comment.