fix(email-api): Implement robust content upload and activity-based workaround
This commit is contained in:
25
connector-superoffice/EMAIL_WORKAROUND_REPORT.md
Normal file
25
connector-superoffice/EMAIL_WORKAROUND_REPORT.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Status Report: Email Sending Workaround (Feb 28, 2026)
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
The automated dispatch of emails via the SuperOffice API (using `/Shipment` or `/Mailing` endpoints) is currently blocked by a **500 Internal Server Error** in the `Cust26720` tenant environment. Additionally, created Documents often throw a "Cannot check out" error when users try to open them directly, likely due to missing Web Tools or strict SharePoint integration policies for API-generated files.
|
||||||
|
|
||||||
|
## Solution / Workaround
|
||||||
|
We have implemented a robust "Activity-Based" workaround that ensures the email content is visible and actionable for the user.
|
||||||
|
|
||||||
|
1. **Draft Creation:** The system creates a Document (Template: "Ausg. E-Mail") via API.
|
||||||
|
2. **Content Upload:** The email body is uploaded as a binary stream to prevent "0kb file" errors.
|
||||||
|
3. **Activity Mirroring:** Crucially, a linked **Appointment (Task)** is created. The full email body is copied into the `Description` field of this appointment.
|
||||||
|
4. **Direct Access:** The user is provided with a direct link to the **Appointment**, bypassing the problematic Document checkout process.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
* **Target:** Person ID 193036 (Christian Test2 / floke.com@gmail.com)
|
||||||
|
* **Document ID:** 334055 (Content uploaded successfully)
|
||||||
|
* **Activity ID:** 992236 (Contains full text)
|
||||||
|
* **Result:** The user can open the Activity link, copy the pre-generated text, and send it via their standard mail client or SuperOffice MailLink.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Run the test script to generate a new draft for any person:
|
||||||
|
```bash
|
||||||
|
python3 connector-superoffice/create_email_test.py <PersonID>
|
||||||
|
```
|
||||||
|
The script outputs the "Safe Link" to the Activity.
|
||||||
@@ -97,18 +97,35 @@ RoboPlanet"""
|
|||||||
print(f"✅ Document Created Successfully!")
|
print(f"✅ Document Created Successfully!")
|
||||||
print(f" ID: {doc_id}")
|
print(f" ID: {doc_id}")
|
||||||
print(f" Recipient: {email_address}")
|
print(f" Recipient: {email_address}")
|
||||||
print(f" Subject: {subject}")
|
print(f" Template: {doc.get('DocumentTemplate', {}).get('Name')}")
|
||||||
|
|
||||||
|
# 3b. Upload Content (Critical Step to avoid 'Checkout Error')
|
||||||
|
print(f"📤 Uploading content stream to Document {doc_id}...")
|
||||||
|
try:
|
||||||
|
content_bytes = body.encode('utf-8')
|
||||||
|
|
||||||
|
# Manual request because _request_with_retry assumes JSON
|
||||||
|
headers = client.headers.copy()
|
||||||
|
headers["Content-Type"] = "application/octet-stream"
|
||||||
|
|
||||||
|
res = requests.put(
|
||||||
|
f"{client.base_url}/Document/{doc_id}/Content",
|
||||||
|
data=content_bytes,
|
||||||
|
headers=headers
|
||||||
|
)
|
||||||
|
if res.status_code in [200, 204]:
|
||||||
|
print("✅ Content uploaded successfully.")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Content upload failed: {res.status_code} {res.text}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Content upload error: {e}")
|
||||||
|
|
||||||
# Construct direct link
|
# Construct direct link
|
||||||
env = settings.SO_ENVIRONMENT
|
env = settings.SO_ENVIRONMENT
|
||||||
cust_id = settings.SO_CONTEXT_IDENTIFIER
|
cust_id = settings.SO_CONTEXT_IDENTIFIER
|
||||||
link = f"https://{env}.superoffice.com/{cust_id}/default.aspx?document_id={doc_id}"
|
|
||||||
print(f"\n--- WICHTIG ---")
|
doc_link = f"https://{env}.superoffice.com/{cust_id}/default.aspx?document_id={doc_id}"
|
||||||
print(f"Das Dokument wurde im Archiv von {contact.get('Name')} angelegt.")
|
|
||||||
print(f"Da der automatisierte Versand via API in diesem Mandanten (500 Error) blockiert ist,")
|
|
||||||
print(f"muss der Versand aktuell MANUELL über diesen Link gestartet werden:")
|
|
||||||
print(f"🔗 {link}")
|
|
||||||
print(f"----------------\n")
|
|
||||||
|
|
||||||
# 4. Create Linked Appointment (Activity)
|
# 4. Create Linked Appointment (Activity)
|
||||||
print("📅 Creating Linked Appointment (Email Sent Activity)...")
|
print("📅 Creating Linked Appointment (Email Sent Activity)...")
|
||||||
@@ -123,7 +140,19 @@ RoboPlanet"""
|
|||||||
try:
|
try:
|
||||||
appt = client._post("Appointment", appt_payload)
|
appt = client._post("Appointment", appt_payload)
|
||||||
if appt:
|
if appt:
|
||||||
print(f"✅ Appointment Created: {appt.get('AppointmentId')}")
|
appt_id = appt.get('AppointmentId')
|
||||||
|
print(f"✅ Appointment Created: {appt_id}")
|
||||||
|
|
||||||
|
appt_link = f"https://{env}.superoffice.com/{cust_id}/default.aspx?appointment_id={appt_id}"
|
||||||
|
|
||||||
|
print(f"\n--- WICHTIG: NUTZEN SIE DIESEN LINK ---")
|
||||||
|
print(f"Da das Dokument selbst ('Cannot check out') oft blockiert,")
|
||||||
|
print(f"öffnen Sie bitte die AKTIVITÄT. Dort steht der Text im Beschreibungsfeld:")
|
||||||
|
print(f"🔗 {appt_link}")
|
||||||
|
print(f"---------------------------------------\n")
|
||||||
|
|
||||||
|
print(f"(Backup Link zum Dokument: {doc_link})")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("⚠️ Failed to create appointment (None response).")
|
print("⚠️ Failed to create appointment (None response).")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user