feat: add signature tools for digital signature integration
Adds 4 Python tool registrations that call EspoCRM's SmartAssistant executeTool endpoint with the DigitalSignature plugin tools: - send_for_signature — send document for signing with auto-resolved signers - check_signature_status — query status of signature requests - remind_signers — send WhatsApp reminders to pending signers - list_pending_signatures — show all awaiting signature requests Tools are registered under the "signature" toolset, enabled by default. Requires DigitalSignature extension v2.0.0+ on the EspoCRM side. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
"""Signature tools: send_for_signature, check_signature_status, remind_signers, list_pending_signatures."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp_server.espocrm_client import EspoCrmClient
|
||||
|
||||
from mcp_server.tools._helpers import ok, fail
|
||||
|
||||
|
||||
def register_signature_tools(
|
||||
tools: dict,
|
||||
crm: "EspoCrmClient",
|
||||
case_id: str | None,
|
||||
user_id: str | None,
|
||||
context: dict,
|
||||
):
|
||||
"""Register digital signature tools."""
|
||||
|
||||
async def send_for_signature(
|
||||
documentId: str | None = None,
|
||||
documentName: str | None = None,
|
||||
signerContactIds: list[str] | None = None,
|
||||
signingMode: str = "Parallel",
|
||||
message: str | None = None,
|
||||
notifyViaWhatsApp: bool = True,
|
||||
) -> str:
|
||||
"""Send a document for digital signature. Resolves signers from case contacts automatically."""
|
||||
if not documentId and not documentName:
|
||||
return fail("יש לציין שם מסמך או מזהה מסמך")
|
||||
|
||||
params = {
|
||||
"signingMode": signingMode,
|
||||
"notifyViaWhatsApp": notifyViaWhatsApp,
|
||||
}
|
||||
if documentId:
|
||||
params["documentId"] = documentId
|
||||
if documentName:
|
||||
params["documentName"] = documentName
|
||||
if signerContactIds:
|
||||
params["signerContactIds"] = signerContactIds
|
||||
if message:
|
||||
params["message"] = message
|
||||
|
||||
try:
|
||||
result = await crm.post("SmartAssistant/action/executeTool", {
|
||||
"tool": "send_for_signature",
|
||||
"params": params,
|
||||
"caseId": case_id,
|
||||
"userId": user_id,
|
||||
})
|
||||
if result.get("success"):
|
||||
return ok(result.get("message", "המסמך נשלח לחתימה"))
|
||||
return fail(result.get("message", "שגיאה בשליחה לחתימה"))
|
||||
except Exception as e:
|
||||
return fail(f"שגיאה בשליחה לחתימה: {e}")
|
||||
|
||||
async def check_signature_status(
|
||||
signatureRequestId: str | None = None,
|
||||
documentName: str | None = None,
|
||||
) -> str:
|
||||
"""Check the status of a signature request. Can look up by ID or by document name."""
|
||||
params = {}
|
||||
if signatureRequestId:
|
||||
params["signatureRequestId"] = signatureRequestId
|
||||
if documentName:
|
||||
params["documentName"] = documentName
|
||||
|
||||
try:
|
||||
result = await crm.post("SmartAssistant/action/executeTool", {
|
||||
"tool": "check_signature_status",
|
||||
"params": params,
|
||||
"caseId": case_id,
|
||||
"userId": user_id,
|
||||
})
|
||||
if result.get("success"):
|
||||
return ok(result.get("message", "אין מידע"))
|
||||
return fail(result.get("message", "שגיאה בבדיקת סטטוס"))
|
||||
except Exception as e:
|
||||
return fail(f"שגיאה בבדיקת סטטוס חתימה: {e}")
|
||||
|
||||
async def remind_signers(signatureRequestId: str) -> str:
|
||||
"""Send reminder to pending signers on a signature request via WhatsApp and email."""
|
||||
try:
|
||||
result = await crm.post("SmartAssistant/action/executeTool", {
|
||||
"tool": "remind_signers",
|
||||
"params": {"signatureRequestId": signatureRequestId},
|
||||
"caseId": case_id,
|
||||
"userId": user_id,
|
||||
})
|
||||
if result.get("success"):
|
||||
return ok(result.get("message", "תזכורות נשלחו"))
|
||||
return fail(result.get("message", "שגיאה בשליחת תזכורות"))
|
||||
except Exception as e:
|
||||
return fail(f"שגיאה בשליחת תזכורות: {e}")
|
||||
|
||||
async def list_pending_signatures(status: str | None = None) -> str:
|
||||
"""List all pending signature requests. Optionally filter by status."""
|
||||
params = {}
|
||||
if status:
|
||||
params["status"] = status
|
||||
|
||||
try:
|
||||
result = await crm.post("SmartAssistant/action/executeTool", {
|
||||
"tool": "list_pending_signatures",
|
||||
"params": params,
|
||||
"caseId": case_id,
|
||||
"userId": user_id,
|
||||
})
|
||||
if result.get("success"):
|
||||
return ok(result.get("message", "אין חתימות ממתינות"))
|
||||
return fail(result.get("message", "שגיאה בשליפת חתימות"))
|
||||
except Exception as e:
|
||||
return fail(f"שגיאה בשליפת חתימות ממתינות: {e}")
|
||||
|
||||
# Register all tools
|
||||
tools["send_for_signature"] = {
|
||||
"fn": send_for_signature,
|
||||
"description": "שלח מסמך לחתימה דיגיטלית. מזהה חותמים אוטומטית מאנשי הקשר בתיק. שולח הודעת WhatsApp עם קישור לחתימה.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documentId": {"type": "string", "description": "מזהה מסמך (Document ID)"},
|
||||
"documentName": {"type": "string", "description": "שם המסמך (חיפוש חלקי)"},
|
||||
"signerContactIds": {"type": "array", "items": {"type": "string"}, "description": "רשימת מזהי אנשי קשר ספציפיים לחתימה (אופציונלי — ברירת מחדל: כל אנשי הקשר בתיק)"},
|
||||
"signingMode": {"type": "string", "enum": ["Parallel", "Sequential"], "description": "מצב חתימה (ברירת מחדל: Parallel)"},
|
||||
"message": {"type": "string", "description": "הודעה אישית לחותמים"},
|
||||
"notifyViaWhatsApp": {"type": "boolean", "description": "שלח הודעת WhatsApp (ברירת מחדל: true)"},
|
||||
},
|
||||
"required": [],
|
||||
},
|
||||
"agentic": False,
|
||||
}
|
||||
|
||||
tools["check_signature_status"] = {
|
||||
"fn": check_signature_status,
|
||||
"description": "בדוק סטטוס חתימה. חיפוש לפי מזהה בקשה או שם מסמך. מציג מי חתם ומי ממתין.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"signatureRequestId": {"type": "string", "description": "מזהה בקשת חתימה"},
|
||||
"documentName": {"type": "string", "description": "שם מסמך לחיפוש"},
|
||||
},
|
||||
"required": [],
|
||||
},
|
||||
"agentic": False,
|
||||
}
|
||||
|
||||
tools["remind_signers"] = {
|
||||
"fn": remind_signers,
|
||||
"description": "שלח תזכורת לחותמים ממתינים בבקשת חתימה — WhatsApp ומייל.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"signatureRequestId": {"type": "string", "description": "מזהה בקשת חתימה"},
|
||||
},
|
||||
"required": ["signatureRequestId"],
|
||||
},
|
||||
"agentic": False,
|
||||
}
|
||||
|
||||
tools["list_pending_signatures"] = {
|
||||
"fn": list_pending_signatures,
|
||||
"description": "הצג רשימת בקשות חתימה ממתינות. מציג שם מסמך, חותמים וסטטוס לכל בקשה.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "enum": ["Pending", "PartiallySigned", "FieldPlacement"], "description": "סינון לפי סטטוס (אופציונלי)"},
|
||||
},
|
||||
"required": [],
|
||||
},
|
||||
"agentic": False,
|
||||
}
|
||||
Reference in New Issue
Block a user