Aggiunge IMAP bounce e flag email non valide nel CRM.
CI / scan_ruby (push) Failing after 13m27s
CI / scan_js (push) Successful in 11m45s
CI / lint (push) Failing after 12m4s

Permette di leggere i bounce dalla stessa MailIdentity SMTP, aggiornare le email in anagrafica e saltare gli indirizzi invalidi nei mailing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-08 19:46:04 +02:00
co-authored by Cursor
parent 353ace4d99
commit 36b3ffe507
26 changed files with 922 additions and 12 deletions
+78 -1
View File
@@ -254,6 +254,81 @@ module EminuxCrmMcp
end
end
end
class UpdateOrganizationEmail < MCP::Tool
description "Aggiorna email organizzazione/contatto: marca bounce, sostituisci indirizzo, annota timeline."
input_schema(
properties: {
project_code: { type: "string" },
organization_id: { type: "integer" },
email: { type: "string", description: "Nuova email se trovata" },
email_invalid: { type: "boolean" },
bounced_email: { type: "string" },
bounce_reason: { type: "string" },
contact_id: { type: "integer" },
website: { type: "string" },
activity_subject: { type: "string" },
activity_description: { type: "string" }
},
required: %w[project_code organization_id]
)
class << self
def call(project_code:, organization_id:, email: nil, email_invalid: nil, bounced_email: nil,
bounce_reason: nil, contact_id: nil, website: nil, activity_subject: nil,
activity_description: nil, server_context: nil)
body = Client.compact(
organization_id: organization_id,
email: email,
bounced_email: bounced_email,
bounce_reason: bounce_reason,
contact_id: contact_id,
website: website,
activity_subject: activity_subject,
activity_description: activity_description
)
body[:email_invalid] = email_invalid unless email_invalid.nil?
Client.request(
:patch,
"/api/v1/p/#{Today.encode(project_code)}/organizations/#{organization_id}/email",
body: body
)
end
end
end
class CheckMailBounces < MCP::Tool
description "Legge bounce IMAP dall'account email CRM (credenziali SMTP). Matcha le società del progetto."
input_schema(
properties: {
project_code: { type: "string" },
from_email: { type: "string", description: "es. info@matchlivetv.it" },
mail_identity_id: { type: "integer" },
since_days: { type: "integer" },
mailbox: { type: "string" },
limit: { type: "integer" }
},
required: %w[project_code]
)
class << self
def call(project_code:, from_email: nil, mail_identity_id: nil, since_days: nil,
mailbox: nil, limit: nil, server_context: nil)
query = URI.encode_www_form(
Client.compact(
from_email: from_email,
mail_identity_id: mail_identity_id,
since_days: since_days,
mailbox: mailbox,
limit: limit
)
)
path = "/api/v1/p/#{Today.encode(project_code)}/mail_bounces"
path = "#{path}?#{query}" if query.present?
Client.request(:get, path)
end
end
end
end
server = MCP::Server.new(
@@ -267,7 +342,9 @@ server = MCP::Server.new(
EminuxCrmMcp::CreateTask,
EminuxCrmMcp::CompleteTask,
EminuxCrmMcp::CreateActivity,
EminuxCrmMcp::UpdateOpportunityStage
EminuxCrmMcp::UpdateOpportunityStage,
EminuxCrmMcp::UpdateOrganizationEmail,
EminuxCrmMcp::CheckMailBounces
]
)