feat: failed lead sync log
This commit is contained in:
parent
eb0b189d4c
commit
45bc5925d1
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
// frappe.ui.form.on("Failed Lead Sync Log", {
|
||||||
|
// refresh(frm) {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// });
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2025-10-19 17:29:10.261307",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"type",
|
||||||
|
"lead_data"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"default": "Failure",
|
||||||
|
"fieldname": "type",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Type",
|
||||||
|
"options": "Duplicate\nFailure",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "lead_data",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Lead Data",
|
||||||
|
"options": "JSON",
|
||||||
|
"read_only": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
|
"in_create": 1,
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2025-10-19 17:41:28.640446",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Lead Syncing",
|
||||||
|
"name": "Failed Lead Sync Log",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
|
"rows_threshold_for_grid_search": 20,
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class FailedLeadSyncLog(Document):
|
||||||
|
# begin: auto-generated types
|
||||||
|
# This code is auto-generated. Do not modify anything in this block.
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from frappe.types import DF
|
||||||
|
|
||||||
|
lead_data: DF.Code | None
|
||||||
|
type: DF.Literal["Duplicate", "Failure"]
|
||||||
|
# end: auto-generated types
|
||||||
|
|
||||||
|
pass
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests import IntegrationTestCase
|
||||||
|
|
||||||
|
|
||||||
|
# On IntegrationTestCase, the doctype test records and all
|
||||||
|
# link-field test record dependencies are recursively loaded
|
||||||
|
# Use these module variables to add/remove to/from that list
|
||||||
|
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IntegrationTestFailedLeadSyncLog(IntegrationTestCase):
|
||||||
|
"""
|
||||||
|
Integration tests for FailedLeadSyncLog.
|
||||||
|
Use this class for testing interactions between multiple components.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
@ -17,9 +17,9 @@ def sync_leads_from_facebook(access_token: str, lead_form_id: str) -> None:
|
|||||||
last_synced_at = frappe.db.get_value(
|
last_synced_at = frappe.db.get_value(
|
||||||
"Lead Sync Source", {"facebook_lead_form": lead_form_id}, "last_synced_at"
|
"Lead Sync Source", {"facebook_lead_form": lead_form_id}, "last_synced_at"
|
||||||
)
|
)
|
||||||
timestamp = frappe.utils.data.get_timestamp(last_synced_at)
|
|
||||||
filtering = f"filtering=[{{'field':'time_created','operator':'GREATER_THAN','value':{timestamp}}}]"
|
|
||||||
if last_synced_at:
|
if last_synced_at:
|
||||||
|
timestamp = frappe.utils.data.get_timestamp(last_synced_at)
|
||||||
|
filtering = f"filtering=[{{'field':'time_created','operator':'GREATER_THAN','value':{timestamp}}}]"
|
||||||
url = f"{url}?{filtering}"
|
url = f"{url}?{filtering}"
|
||||||
|
|
||||||
leads = make_get_request(
|
leads = make_get_request(
|
||||||
@ -57,13 +57,20 @@ def sync_leads_from_facebook(access_token: str, lead_form_id: str) -> None:
|
|||||||
).insert(ignore_permissions=True)
|
).insert(ignore_permissions=True)
|
||||||
except frappe.UniqueValidationError:
|
except frappe.UniqueValidationError:
|
||||||
# Skip duplicate leads based on facebook_lead_id
|
# Skip duplicate leads based on facebook_lead_id
|
||||||
frappe.log_error("Duplicate lead skipped")
|
# TODO: de-duplication based on field values
|
||||||
continue
|
frappe.get_doc(
|
||||||
|
{"doctype": "Failed Lead Sync Log", "type": "Duplicate", "lead_data": frappe.as_json(lead)}
|
||||||
|
).insert(ignore_permissions=True)
|
||||||
|
except Exception:
|
||||||
|
frappe.get_doc(
|
||||||
|
{"doctype": "Failed Lead Sync Log", "type": "Failure", "lead_data": frappe.as_json(lead)}
|
||||||
|
).insert(ignore_permissions=True)
|
||||||
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Lead Sync Source", {"facebook_lead_form": lead_form_id}, "last_synced_at", frappe.utils.now()
|
"Lead Sync Source", {"facebook_lead_form": lead_form_id}, "last_synced_at", frappe.utils.now()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def fetch_and_store_pages_from_facebook(access_token: str) -> list[dict]:
|
def fetch_and_store_pages_from_facebook(access_token: str) -> list[dict]:
|
||||||
if not access_token:
|
if not access_token:
|
||||||
@ -85,6 +92,7 @@ def fetch_and_store_pages_from_facebook(access_token: str) -> list[dict]:
|
|||||||
|
|
||||||
return pages
|
return pages
|
||||||
|
|
||||||
|
|
||||||
def get_fb_account_details(access_token: str) -> dict:
|
def get_fb_account_details(access_token: str) -> dict:
|
||||||
url = get_fb_graph_api_url("me")
|
url = get_fb_graph_api_url("me")
|
||||||
try:
|
try:
|
||||||
@ -140,12 +148,11 @@ def create_facebook_lead_form_in_db(form: dict, page_id: str) -> None:
|
|||||||
)
|
)
|
||||||
form_doc.insert(ignore_permissions=True)
|
form_doc.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pages_with_forms() -> list[dict]:
|
def get_pages_with_forms() -> list[dict]:
|
||||||
pages = frappe.db.get_all("Facebook Page", fields=["id", "name"])
|
pages = frappe.db.get_all("Facebook Page", fields=["id", "name"])
|
||||||
for page in pages:
|
for page in pages:
|
||||||
forms = frappe.db.get_all(
|
forms = frappe.db.get_all("Facebook Lead Form", filters={"page": page["id"]}, fields=["id", "name"])
|
||||||
"Facebook Lead Form", filters={"page": page["id"]}, fields=["id", "name"]
|
|
||||||
)
|
|
||||||
page["forms"] = forms
|
page["forms"] = forms
|
||||||
return pages
|
return pages
|
||||||
|
|||||||
@ -53,7 +53,8 @@ class LeadSyncSource(Document):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def sync_leads(self):
|
def sync_leads(self):
|
||||||
frappe.enqueue_doc(self.doctype, self.name, "_sync_leads", queue="long")
|
self._sync_leads()
|
||||||
|
# frappe.enqueue_doc(self.doctype, self.name, "_sync_leads", queue="long")
|
||||||
|
|
||||||
def _sync_leads(self):
|
def _sync_leads(self):
|
||||||
if self.type == "Facebook" and self.access_token:
|
if self.type == "Facebook" and self.access_token:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user