fix: generate api_key, api_secret on update of twilio settings
This commit is contained in:
parent
9723f8a0db
commit
4af919db11
@ -28,12 +28,14 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "api_key",
|
"fieldname": "api_key",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "API Key"
|
"label": "API Key",
|
||||||
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "api_secret",
|
"fieldname": "api_secret",
|
||||||
"fieldtype": "Password",
|
"fieldtype": "Password",
|
||||||
"label": "API Secret"
|
"label": "API Secret",
|
||||||
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_idds",
|
"fieldname": "column_break_idds",
|
||||||
@ -49,7 +51,8 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "twiml_sid",
|
"fieldname": "twiml_sid",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "TwiML SID"
|
"label": "TwiML SID",
|
||||||
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_ssqj",
|
"fieldname": "section_break_ssqj",
|
||||||
@ -69,7 +72,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-28 00:44:24.942914",
|
"modified": "2023-09-20 16:42:17.025651",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "FCRM",
|
"module": "FCRM",
|
||||||
"name": "Twilio Settings",
|
"name": "Twilio Settings",
|
||||||
|
|||||||
@ -1,9 +1,88 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
# import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
from twilio.rest import Client
|
||||||
|
|
||||||
class TwilioSettings(Document):
|
class TwilioSettings(Document):
|
||||||
pass
|
friendly_resource_name = "Frappe CRM" # System creates TwiML app & API keys with this name.
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.validate_twilio_account()
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
# Single doctype records are created in DB at time of installation and those field values are set as null.
|
||||||
|
# This condition make sure that we handle null.
|
||||||
|
if not self.account_sid:
|
||||||
|
return
|
||||||
|
|
||||||
|
twilio = Client(self.account_sid, self.get_password("auth_token"))
|
||||||
|
self.set_api_credentials(twilio)
|
||||||
|
self.set_application_credentials(twilio)
|
||||||
|
self.reload()
|
||||||
|
|
||||||
|
def validate_twilio_account(self):
|
||||||
|
try:
|
||||||
|
twilio = Client(self.account_sid, self.get_password("auth_token"))
|
||||||
|
twilio.api.accounts(self.account_sid).fetch()
|
||||||
|
return twilio
|
||||||
|
except Exception:
|
||||||
|
frappe.throw(_("Invalid Account SID or Auth Token."))
|
||||||
|
|
||||||
|
def set_api_credentials(self, twilio):
|
||||||
|
"""Generate Twilio API credentials if not exist and update them.
|
||||||
|
"""
|
||||||
|
if self.api_key and self.api_secret:
|
||||||
|
return
|
||||||
|
new_key = self.create_api_key(twilio)
|
||||||
|
self.api_key = new_key.sid
|
||||||
|
self.api_secret = new_key.secret
|
||||||
|
frappe.db.set_value('Twilio Settings', 'Twilio Settings', {
|
||||||
|
'api_key': self.api_key,
|
||||||
|
'api_secret': self.api_secret
|
||||||
|
})
|
||||||
|
|
||||||
|
def set_application_credentials(self, twilio):
|
||||||
|
"""Generate TwiML app credentials if not exist and update them.
|
||||||
|
"""
|
||||||
|
credentials = self.get_application(twilio) or self.create_application(twilio)
|
||||||
|
self.twiml_sid = credentials.sid
|
||||||
|
frappe.db.set_value('Twilio Settings', 'Twilio Settings', 'twiml_sid', self.twiml_sid)
|
||||||
|
|
||||||
|
def create_api_key(self, twilio):
|
||||||
|
"""Create API keys in twilio account.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return twilio.new_keys.create(friendly_name=self.friendly_resource_name)
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error(title=_("Twilio API credential creation error."))
|
||||||
|
frappe.throw(_("Twilio API credential creation error."))
|
||||||
|
|
||||||
|
def get_twilio_voice_url(self):
|
||||||
|
url_path = "/api/method/crm.twilio.api.voice"
|
||||||
|
return get_public_url(url_path)
|
||||||
|
|
||||||
|
def get_application(self, twilio, friendly_name=None):
|
||||||
|
"""Get TwiML App from twilio account if exists.
|
||||||
|
"""
|
||||||
|
friendly_name = friendly_name or self.friendly_resource_name
|
||||||
|
applications = twilio.applications.list(friendly_name)
|
||||||
|
return applications and applications[0]
|
||||||
|
|
||||||
|
def create_application(self, twilio, friendly_name=None):
|
||||||
|
"""Create TwilML App in twilio account.
|
||||||
|
"""
|
||||||
|
friendly_name = friendly_name or self.friendly_resource_name
|
||||||
|
application = twilio.applications.create(
|
||||||
|
voice_method='POST',
|
||||||
|
voice_url=self.get_twilio_voice_url(),
|
||||||
|
friendly_name=friendly_name
|
||||||
|
)
|
||||||
|
return application
|
||||||
|
|
||||||
|
def get_public_url(path: str=None):
|
||||||
|
from frappe.utils import get_url
|
||||||
|
return get_url().split(":8", 1)[0] + path
|
||||||
@ -60,7 +60,6 @@ def twilio_incoming_call_handler(**kwargs):
|
|||||||
resp = IncomingCall(args.From, args.To).process()
|
resp = IncomingCall(args.From, args.To).process()
|
||||||
return Response(resp.to_xml(), mimetype='text/xml')
|
return Response(resp.to_xml(), mimetype='text/xml')
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def create_call_log(call_details: TwilioCallDetails):
|
def create_call_log(call_details: TwilioCallDetails):
|
||||||
call_log = frappe.get_doc({**call_details.to_dict(),
|
call_log = frappe.get_doc({**call_details.to_dict(),
|
||||||
'doctype': 'CRM Call Log',
|
'doctype': 'CRM Call Log',
|
||||||
@ -71,7 +70,6 @@ def create_call_log(call_details: TwilioCallDetails):
|
|||||||
call_log.save()
|
call_log.save()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def update_call_log(call_sid, status=None):
|
def update_call_log(call_sid, status=None):
|
||||||
"""Update call log status.
|
"""Update call log status.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -418,7 +418,6 @@ async function makeOutgoingCall(number) {
|
|||||||
title: '',
|
title: '',
|
||||||
content: '',
|
content: '',
|
||||||
}
|
}
|
||||||
// update_call_log(conn)
|
|
||||||
})
|
})
|
||||||
_call.value.on('cancel', () => {
|
_call.value.on('cancel', () => {
|
||||||
log.value = `Call ended from makeOutgoing call cancel.`
|
log.value = `Call ended from makeOutgoing call cancel.`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user