Help with sending attachments API
Collapse
X
-
Thanks a lot! Below code that works for me. It returns file content coded to Base64. Hope it will be usefull for other.
.../espo/custom/Espo/Custom/FormulaFunctions/FileContent.php
PHP Code:<?php
namespace Espo\Custom\FormulaFunctions;
use Espo\Core\Formula\Exceptions\TooFewArguments;
use Espo\Core\Formula\Func;
use Espo\Core\Formula\EvaluatedArgumentList;
use Espo\Core\FileStorage\Manager;
use Espo\ORM\EntityManager;
use Espo\Entities\Attachment;
class FileContent implements Func
{
public function __construct(
private Manager $fileStorageManager,
private EntityManager $entityManager,
) {}
public function process(EvaluatedArgumentList $arguments): string
{
if (count($arguments) < 1) {
throw TooFewArguments::create(1);
}
$id = $arguments[0];
$attachment = $this->entityManager->getRDBRepositoryByClass(Attachment::class)->getById($id);
if (!$attachment) {
throw new \RuntimeException("No attachment $id.");
}
$content = $this->fileStorageManager->getContents($attachment);
return base64_encode($content);
}
}
.../espo/custom/Espo/Custom/Resources/metadata/app/formula.json
PHP Code:{
"functionClassNameMap": {
"fileContent": "Espo\\Custom\\FormulaFunctions\\FileContent"
},
"functionList": [
"__APPEND__",
{
"name": "fileContent",
"insertText": "fileContent(ID)"
}
]
}
Last edited by jacao; 10-04-2024, 08:30 AM.Leave a comment:
-
You need something like this. Not tested.
Code:<?php namespace Espo\Custom\FormulaFunctions; use Espo\Core\Formula\Exceptions\TooFewArguments; use Espo\Core\Formula\Func; use Espo\Core\Formula\EvaluatedArgumentList; use Espo\Core\FileStorage\Manager; use Espo\ORM\EntityManager; use Espo\Entities\Attachment; class AttachmentContents implements Func { public function __construct( private Manager $fileStorageManager, private EntityManager $entityManager, ) {} public function process(EvaluatedArgumentList $arguments): string { if (count($arguments) < 1) { throw TooFewArguments::create(1); } $id = $arguments[0]; $attachment = $this->entityManager->getRDBRepositoryByClass(Attachment::class)->getById($id); if (!$attachment) { throw new \RuntimeException("No attachment $id."); } return $this->fileStorageManager->getContents($attachment); } }
Last edited by yuri; 10-03-2024, 10:20 AM.Leave a comment:
-
It might be a custom function. You can add custom functions. https://docs.espocrm.com/development...on-in-formula/Leave a comment:
-
This thread is exactly what I've been looking for. However, I have a question - how did you manage to get the ext\file\contents() function shown in the screenshot from the first post? I can't seem to find it in my environment (Espo 8.4.1, Advanced Pack 3.4.6).Leave a comment:
-
How your sub process looks like? Can you expand it and provide a screenshot. You need to add a Task with Send HTTP Request there. And use the same formula you used before but with $inputItem variable instead of the attachment ID.Leave a comment:
-
-
You can use multi-instance Sub-Process. If you have an array of attachments (or ids), pass them to each instance of the Sub-Process. That Sub Process will have Task that sends one attachment. It maybe bit tricky to figure out how to use it. But it's feasible.Leave a comment:
-
Thank you, Davidjuan, but I want to use BPM. I want to extract the attachments from the email and send each attachment to my API individually, as I want to receive a single response for each attachment. With the method yuri explained to me, it works, but it retrieves all the attachments at once instead of each attachment separately.
For example, if I have an email with 4 attachments, I want to extract all 4 and send each one individually to the API with the following format:
```json
{
"name": "{$$name}",
"type": "{$$type}",
"file": "{$$content}"
}
```
This way, I will receive a separate response for each attachment.Leave a comment:
-
Hello,
I'd be happy to help with that. Here’s a general approach you can follow to retrieve email attachments and send them to an API:
1. Retrieve the Email Attachments:
- Use an email client library (e.g., `imaplib` for IMAP or `smtplib` for SMTP in Python) to connect to your email server.
- Authenticate and search for the email containing the attachments.
- Retrieve and download the attachments to your local system.
2. Send Attachments to the API:
- Use a library like `requests` in Python to send HTTP requests.
- Open each attachment file and send it to the API endpoint.
Here is an example in Python:
```python
import imaplib
import email
import requests
# Connect to the email server and log in
mail = imaplib.IMAP4_SSL('imap.your-email.com')
mail.login('your-email@example.com', 'your-password')
# Select the mailbox and search for the email
mail.select('inbox')
status, messages = mail.search(None, 'ALL')
email_ids = messages[0].split()
# Fetch the email by ID
status, msg_data = mail.fetch(email_ids[-1], '(RFC822)')
msg = email.message_from_bytes(msg_data[0][1])
# Loop through the email parts to find attachments
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename:
# Save the attachment
with open(filename, 'wb') as f:
f.write(part.get_payload(decode=True))
# Send the attachment to the API
with open(filename, 'rb') as f:
response = requests.post('https://your-api-endpoint.com/upload', files={'file': f})
print(f'Uploaded {filename}, Response: {response.status_code}')
# Close the connection to the mail server
mail.logout()
```
Replace the placeholders (`imap.your-email.com`, `your-email@example.com`, `your-password`, `https://your-api-endpoint.com/upload`) with your actual email server details, credentials, and API endpoint.
This script:
1. Connects to your email server and logs in.
2. Searches for emails and retrieves the latest one.
3. Extracts attachments and saves them locally.
4. Sends each attachment to the specified API endpoint.
Make sure you have the necessary libraries installed (`imaplib`, `email`, `requests`). You can install `requests` using `pip install requests`.
I hope this helps! Let me know if you need further assistance.Leave a comment:
-
yes, but this sends all the attachments at once, I want to extract them and send one by oneLeave a comment:
-
You already have the $file variable which is an object. Use it by specifying 'file' in 'Payload from variable'. Erase the Payload textboxLeave a comment:
Leave a comment: