Solved

How do I use an API-Uploaded File as an E-Mail Attachment using the API?


Userlevel 7
Badge +6

Hi doers!

This will be a rather lengthy explanation of my problem, whose TLDR is: Uploading Files via API leads to URLs containing a “org/”, which seems to make it impossible to set them as attachment sources using the GraphQL API.

 

Here the full explanation:

 

I am trying to send E-Mails using Pipefy GraphQL API. In general, I do not have any problems with this. I can send E-Mails even with attachments. BUT: only if the attachments were uploaded manually. I am not able to do the attachment when using files uploaded via GraphQL API.

 

Step 1: Upload (works)

The upload works as described on this page:

First, I request the URL to upload to:

mutation {
createPresignedUrl(input: { organizationId: 123, fileName: "MyDocument.pdf" }){
clientMutationId
url
}
}

Then, I do the upload:

curl --request PUT
--url 'https://pipefy-production.s3-sa-east-1.amazonaws.com/orgs/ce63-a26b-412f-9d27-3a5776e16e/uploads/45da74d3-0e92-4e1c-a04e-2acc97169a3/SampleFile.pdf?...Signature=fa76e8bf28f88d8ceec1df8219912e103ad15f5ab4668f0fc9cea69109991aa'
--header 'Content-Type: application/pdf'
--data 'BINARY_DATA'

curl -v --upload-file SampleFile.pdf 'https://pipefy-production.s3-sa-east-1.amazonaws.com/orgs/ce63-a26b-412f-9d27-3a5776e16e/uploads/45da74d3-0e92-4e1c-a04e-2acc97169a3/SampleFile.pdf?...Signature=fa76e8bf28f88d8ceec1df8219912e103ad15f5ab4668f0fc9cea69109991aa'

Then, I assign the file to a card field:

mutation {
updateCardField(input: {card_id: 123, field_id: "attachment_field", new_value: ["orgs/8bd9ce63-a26b-412f-9d27-3a5776e3e16e/uploads/45da74d5-0e92-4e1c-a04e-26acc97169a3/SampleFile.pdf"]}) {
clientMutationId
success
}
}

At this point, I can view the attachment and download it without problems in Pipefy, indicating that this is the correct way to do it. No problems occur.

 

Step 2: Create E-Mail (works)

 

To create the E-Mail, I first fetch the URL again to make sure it did not change:

query {
card(id: 123) {
attachments { url createdAt }
}
}

Then, I use the url of the card to create the E-Mail:

mutation {
createInboxEmail(input: {
card_id: "123",
from: "[email protected]",
subject: "TEST",
to: "[email protected]",
html: "Sehr geehrte Tim<br />
<br />
This is a Test",
emailAttachments: [{
fileUrl: "orgs/8bd9c63-a26b-412f-9d27-3a5776e3e16e/uploads/45da74d5-0e92-4e1c-a04e-26acc97169a3/File.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=BKIA6QQUS4NUNAO6IA%2F20180705%2Fsa-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180705T215845Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&x-amz-acl=public-read&X-Amz-Signature=fa76e8bf28f88d8ceec1df8219912e103ad15f5ab4668f0fc9cea69109991aa",

publicUrl: "https://pipefy-production.s3-sa-east-1.amazonaws.com/orgs/8bd9c63-a26b-412f-9d27-3a5776e3e16e/uploads/45da74d5-0e92-4e1c-a04e-26acc97169a3/File.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=BKIA6QQUS4NUNAO6IA%2F20180705%2Fsa-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180705T215845Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&x-amz-acl=public-read&X-Amz-Signature=fa76e8bf28f88d8ceec1df8219912e103ad15f5ab4668f0fc9cea69109991aa",
fileName: "test.pdf"
}],
repo_id: "123"
}) {
inbox_email {
id
state
}
}
}

This too works without problems. I can go to Pipefy, open the card, look into the E-Mail as well as its attachments.

 

Step 3: Send E-Mail (does not work)

 

Finally, I use the returned inbox_email id to try to send the E-Mail:

mutation {
sendInboxEmail(input: {
id: "323876369"
}) {
clientMutationId
success
}
}

 

This is where it fails with the following Error:

{"data":{"sendInboxEmail":null},"errors":[{"message":"Invalid attachment files","locations":[{"line":3,"column":5}],"path":["sendInboxEmail"],"code":30000,"type":"PipefyRuntimeError"}]}

 

What is the problem in my approach? What do I have to do differently? Why does the URL contain the “orgs/” part (which is not the case when uploading the file manually into Pipefy)?

Leaving the “orgs/” part away in either step 1 or 2 does not lead to files that could be opened, neither in the E-Mail nor the card, depending on where I make the change.

icon

Best answer by Marcos Carvalho 28 April 2021, 21:22

View original

11 replies

Userlevel 5
Badge +6

hey @genietim

 

I believe the error is happening in your step 2.

 

In the query 

query {
card(id: 123) {
attachments { url createdAt }
}
}

Change for this one: 

{
card(id: 123) {
attachments {
createdAt
path
url
}
}
}

 

Are you sure that the url in query payload has the pipefy-production.s3-sa-east-1.amazonaws.com domain?

 

Because is must return a url and path like these from our storage-service: 

 

{
"data": {
"card": {
"attachments": [
{
"createdAt": null,
"path": "uploads/7dad8421-2726-4e06-a740-835abe81d085/Ruby1.pdf",
"url": "https://app-storage-service.pipefy.com/v1/signed/uploads/7dad8421-2726-4e06-a740-835abe81d085/Ruby1.pdf?expires_on=1619638284&signature=I5jsrbvBnOFVC%2F3dPTijC4jGe0CPajNKOBVOhdFpSVY%3D"
}
]
}
}
}

 

 

Then using it with this address you will sucessfully create and send the inbox email: 

mutation {
createInboxEmail(input: {card_id: "123", from: "[email protected]", subject: "TEST", to: "[email protected]", html: " Hey there <br/> <br/> This is a Test", emailAttachments: [{fileUrl: "orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89c4ba72-886d-484c-9176-435e7f81e078/Ruby.pdf", publicUrl: "https://app-storage-service.pipefy.com/v1/signed/orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89c4ba72-886d-484c-9176-435e7f81e078/Ruby.pdf?expires_on=1619637926&signature=rWPx1IguSuqHydjnnUlkxKw6fx63zpKVCMB00i71xQw%3D", fileName: "Ruby.pdf"}], repo_id: "9876543"}) {
inbox_email {
id
state
}
}
}

and

 

 

 

Please check this URL and path in you query payload and if you need anything else, please let me know :relaxed:

Userlevel 7
Badge +6

Hi @Marcos Carvalho ,

thank you so much for your response. You are right, the query I mention above are copy-paste mistakes when I tried to get rid of any personal information. Unfortunately though, no, the return value is different for me.

The corrected return value in step 2 if I do as described above looks like this:

{
"data": {
"card": {
"attachments": [
{
"createdAt": null,
"path": "orgs/abcabcab-c2ed-4bb2-83f5-a841b0cb1e62/uploads/abcabcab-c410-455c-a1cd-3c271149640b/invoice.pdf",
"url":"https://app-storage-service.pipefy.com/v1/signed/orgs/abcabcab-c2ed-4bb2-83f5-a841b0cb1e62/uploads/765a741d-c410-455c-a1cd-3c271149640b/invoice.pdf?expires_on=1619639473&signature=cbBuiK1n%2Fr7ZHVmaIRIQZEr84iuxkomVrTtWg3Iq0cY%3D
}
]
}
}
}

when I use the full “https://pipefy-prd-us-east-1.s3.amazonaws.com/orgs/...” URL and as path one including the “orgs/…” when setting the field value (this is the way how I can open the uploaded file in Pipefy). Tell me if you want a live example to prove that this is the case.

The mutation I talk about is the following:

mutation {
updateCardField(input: {card_id: 123, field_id: "attachment_field", new_value: ["orgs/with-or-without-the-part-till-here/uploads/45da74d5-0e92-4e1c-a04e-26acc97169a3/SampleFile.pdf"]}) {
clientMutationId
success
}
}

The return value when fetching is different if I cut the URL before the “uploads/” instead when setting the field value in the mutation above. It would look just as you say:

{
"data": {
"card": {
"attachments": [
{
"createdAt": null,
"path": "uploads/abcabcab-c410-455c-a1cd-3c271149640b/invoice.pdf",
"url":"https://app-storage-service.pipefy.com/v1/signed/uploads/765a741d-c410-455c-a1cd-3c271149640b/invoice.pdf?expires_on=1619639473&signature=cbBuiK1n%2Fr7ZHVmaIRIQZEr84iuxkomVrTtWg3Iq0cY%3D
}
]
}
}
}

This way though, I cannot open the file in Pipefy.

 

And, as I said, in both cases, the E-Mail sending results in “Invalid attachments”.

 

Is it possible, that my organization or region is still on some elder Pipefy version or something, where the URL is not yet changed? Note that my URL for uploading is indeed different than the one you describe also in the main subdomain.

Userlevel 7
Badge +6

(to clarify what I mean by “my URL for uploading is indeed different”: the URL I get to upload from Amazon is something “https://pipefy-prd-us-east-1.s3.amazonaws.com/orgs/...”, not “https://pipefy-production.s3-sa-east-1.amazonaws.com/...”. I have the other URL above as I copy-pasted from the upload-documentation to, again, get rid of the personal information)

Userlevel 5
Badge +6

Hey Tim, 

 

It seems to be correct. 

I’m also fetching card data and it returns (with the orgs/… prefix) 

{
"data": {
"card": {
"attachments": [
{
"createdAt": null,
"path": "orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89cc28f1-5bb0-4b63-b81d-946aaa8893d6/Ruby.pdf",
"url": "https://app-storage-service.pipefy.com/v1/signed/orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89cc28f1-5bb0-4b63-b81d-946aaa8893d6/Ruby.pdf?expires_on=1619720179&signature=%2BM8aCLJvIlU9pY5Rm4y8o0YNMM3qNAUKBglhMAnM1FI%3D"
}
]
}
}
}

 

 

Could you please create a test Org and try to generate the link from there? 

 

If this error persists, I believe it will be necessary to have a deeper look by Support Team. 

 

Please let us know

Userlevel 7
Badge +6

Hey @Marcos Carvalho ,

 

Thank you for staying with me. I just created a new organisation to check, and yes, the links stay the same, including “orgs/” prefix if I include the “orgs/” prefix on upload & field setting. If I don’t I cannot open the file. The behaviour is the same as in my “main” organisation.

How can I help triage this issue?

Userlevel 7
Badge +6

@Juliana Spinardi  could you please remove the “marked as answer” mark? This question/problem still persists and is not solved. The now accepted answer merely points out an error in my question, unfortunately, nothing I can do different...

Userlevel 7
Badge +6

@Juliana Spinardi  could you please remove the “marked as answer” mark? This question/problem still persists and is not solved. The now accepted answer merely points out an error in my question, unfortunately, nothing I can do different...

Sure. It wasn't intentional!

Userlevel 7
Badge +6

I am happy to report that my E-Mails are finally sent.


I do not know why though, not like I changed anything (I am doing what I reported above), and I will have to check whether this success persists, but well, I am happy it worked at least once.

Userlevel 1

hey @genietim

 

I believe the error is happening in your step 2.

 

In the query 

query {
card(id: 123) {
attachments { url createdAt }
}
}

Change for this one: 

{
card(id: 123) {
attachments {
createdAt
path
url
}
}
}

 

Are you sure that the url in query payload has the pipefy-production.s3-sa-east-1.amazonaws.com domain?

 

Because is must return a url and path like these from our storage-service: 

 

{
"data": {
"card": {
"attachments": [
{
"createdAt": null,
"path": "uploads/7dad8421-2726-4e06-a740-835abe81d085/Ruby1.pdf",
"url": "https://app-storage-service.pipefy.com/v1/signed/uploads/7dad8421-2726-4e06-a740-835abe81d085/Ruby1.pdf?expires_on=1619638284&signature=I5jsrbvBnOFVC%2F3dPTijC4jGe0CPajNKOBVOhdFpSVY%3D"
}
]
}
}
}

 

 

Then using it with this address you will sucessfully create and send the inbox email: 

mutation {
createInboxEmail(input: {card_id: "123", from: "[email protected]", subject: "TEST", to: "[email protected]", html: " Hey there <br/> <br/> This is a Test", emailAttachments: [{fileUrl: "orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89c4ba72-886d-484c-9176-435e7f81e078/Ruby.pdf", publicUrl: "https://app-storage-service.pipefy.com/v1/signed/orgs/abcf59db-49a5-419e-bd3c-40f781d7cdcc/uploads/89c4ba72-886d-484c-9176-435e7f81e078/Ruby.pdf?expires_on=1619637926&signature=rWPx1IguSuqHydjnnUlkxKw6fx63zpKVCMB00i71xQw%3D", fileName: "Ruby.pdf"}], repo_id: "9876543"}) {
inbox_email {
id
state
}
}
}

and

 

 

 

Please check this URL and path in you query payload and if you need anything else, please let me know :relaxed:

 

Hi! I’m trying to do the upload file by using Integromat. Do your know how can I do it?

Userlevel 7
Badge +6

Hi @tobiasbaco : to upload a file using Integromat, you can actually just follow the steps I took / describe above. Instead of running the queries from PHP or JavaScript, you can use the “Run Custom GraphQL Query” in Integromat:

 

Custom GraphQL Query in Integromat

 

Userlevel 1

Hi @tobiasbaco : to upload a file using Integromat, you can actually just follow the steps I took / describe above. Instead of running the queries from PHP or JavaScript, you can use the “Run Custom GraphQL Query” in Integromat:

 

Custom GraphQL Query in Integromat

 

Hi! Thanks a lot for your reply.

I’ve managed to get it working by using the Custom GraphQL Query and a HTTP PUT module using curl file uploading.

Anyway, thank you for giving this matter your attencion!

Cheers from Brazil!

Have a nice week. 

Reply