From b6b4ecc58d4909fb12e3ba08d96d129ef25e2893 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Sat, 11 Jan 2025 16:34:19 +0530 Subject: [PATCH] feat: added api to make a call --- .../crm_exotel_settings.json | 18 ++--- crm/integrations/exotel/handler.py | 72 +++++++++++++++++++ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/crm/fcrm/doctype/crm_exotel_settings/crm_exotel_settings.json b/crm/fcrm/doctype/crm_exotel_settings/crm_exotel_settings.json index a0cb41dc..5495c846 100644 --- a/crm/fcrm/doctype/crm_exotel_settings/crm_exotel_settings.json +++ b/crm/fcrm/doctype/crm_exotel_settings/crm_exotel_settings.json @@ -7,7 +7,7 @@ "field_order": [ "enabled", "column_break_uxtz", - "record_calls", + "record_call", "section_break_kfez", "account_sid", "section_break_iuct", @@ -53,25 +53,25 @@ "fieldname": "column_break_uxtz", "fieldtype": "Column Break" }, - { - "default": "0", - "depends_on": "enabled", - "fieldname": "record_calls", - "fieldtype": "Check", - "label": "Record Calls" - }, { "fieldname": "api_token", "fieldtype": "Password", "in_list_view": 1, "label": "API Token", "mandatory_depends_on": "enabled" + }, + { + "default": "0", + "depends_on": "enabled", + "fieldname": "record_call", + "fieldtype": "Check", + "label": "Record Call" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-01-08 16:12:34.335490", + "modified": "2025-01-11 16:08:48.251477", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Exotel Settings", diff --git a/crm/integrations/exotel/handler.py b/crm/integrations/exotel/handler.py index df32020f..77d8f077 100644 --- a/crm/integrations/exotel/handler.py +++ b/crm/integrations/exotel/handler.py @@ -1,8 +1,13 @@ +import json + +import bleach import frappe +import requests from frappe import _ from frappe.integrations.utils import create_request_log +# Incoming Call @frappe.whitelist(allow_guest=True) def handle_request(**kwargs): if not is_integration_enabled(): @@ -47,6 +52,72 @@ def handle_request(**kwargs): frappe.db.commit() +# Outgoing Call +@frappe.whitelist() +def make_a_call(from_number, to_number, caller_id=None, link_to_document=None): + if not is_integration_enabled(): + frappe.throw(_("Please setup Exotel intergration"), title=_("Integration Not Enabled")) + + endpoint = get_exotel_endpoint("Calls/connect.json?details=true") + if not from_number: + from_number = frappe.get_value("CRM Exotel Agent", {"user": frappe.session.user}, "mobile_no") + + if not from_number: + frappe.throw( + _("You do not have mobile number set in your Exotel Agent"), title=_("Mobile Number Missing") + ) + + record_call = frappe.db.get_single_value("CRM Exotel Settings", "record_call") + + try: + response = requests.post( + endpoint, + data={ + "From": from_number, + "To": to_number, + "CallerId": caller_id, + "Record": "true" if record_call else "false", + "StatusCallback": get_status_updater_url(), + "StatusCallbackEvents[0]": "terminal", + }, + ) + response.raise_for_status() + except requests.exceptions.HTTPError: + if exc := response.json().get("RestException"): + frappe.throw(bleach.linkify(exc.get("Message")), title=_("Exotel Exception")) + else: + res = response.json() + call_payload = res.get("Call", {}) + if link_to_document: + link_to_document = json.loads(link_to_document) + create_call_log( + call_id=call_payload.get("Sid"), + from_number=call_payload.get("From"), + to_number=call_payload.get("To"), + medium=call_payload.get("PhoneNumberSid"), + call_type="Outgoing", + link_to_document=link_to_document, + ) + + return response.json() + + +def get_exotel_endpoint(action): + settings = get_exotel_settings() + return "https://{api_key}:{api_token}@api.exotel.com/v1/Accounts/{sid}/{action}".format( + api_key=settings.api_key, + api_token=settings.get_password("api_token"), + sid=settings.account_sid, + action=action, + ) + + +def get_status_updater_url(): + from frappe.utils.data import get_url + + return get_url("api/method/crm.integrations.exotel.handler.handle_request") + + def get_exotel_settings(): return frappe.get_single("CRM Exotel Settings") @@ -72,6 +143,7 @@ def create_call_log( call_log.medium = medium call_log.type = call_type call_log.status = status + call_log.telephony_medium = "Exotel" setattr(call_log, "from", from_number) if link_to_document: call_log.append("links", link_to_document)