Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to upload files? #25

Open
xeruf opened this issue Feb 24, 2023 · 12 comments
Open

How to upload files? #25

xeruf opened this issue Feb 24, 2023 · 12 comments

Comments

@xeruf
Copy link

xeruf commented Feb 24, 2023

Thanks for the great quickstart!

How do I send formdata to upload attachments to events with this library though?
The API docs are also rather unclear on this and there seem to be typos like attatchments:
https://demo.church.tools/api

@xeruf
Copy link
Author

xeruf commented Feb 24, 2023

Which type to use to upload eventFiles/attachments to an event? attachments? service?
Is service=event?

I now get Nur eine Datei darf für diesen Domain Typ hochgeladen werden. even though I am posting only one file, for any of the aforementioned types.

Responses in German are also fine, just thought I follow good internet etiquette and write understandable for anyone :)

@xeruf
Copy link
Author

xeruf commented Feb 24, 2023

And how do I download a PDF appropriately?
When I get a song arrangement and try to download its fileUrl like this, something messes up in the PDF header, maybe an encoding issue?

churchtoolsClient.get(f.fileUrl).then(file => {
  fs.createWriteStream(filename).write(file) 
})

@xeruf
Copy link
Author

xeruf commented Feb 24, 2023

Wonder what for? This: https://code.ftt.gmbh/janek/carvent

@xeruf
Copy link
Author

xeruf commented Mar 29, 2023

Hallihallo, jemand da?

@andreasmischke
Copy link
Contributor

Hey @xeruf!

Sorry for the delay.

Which type to use to upload eventFiles/attachments to an event? attachments? service?
Is service=event?

You guessed right: If you want to attach files to an event, the corresponding domainType is service (as in "church service" / "Gottesdienst").

I now get Nur eine Datei darf für diesen Domain Typ hochgeladen werden. even though I am posting only one file, for any of the aforementioned types.

I'm not sure if that problem still exists when you use the correct domainType. If so, please reach out again, then I'll take a closer look.

And how do I download a PDF appropriately?

Our client library is not yet capable of downloading files and it's currently not on the roadmap to introduce this feature.

But you can leverage the cookieJar and the http/https modules from the Node.js standard library to make that download work:

const https = require('https');
const fs = require('fs');

const cookieJar = new tough.CookieJar();
churchtoolsClient.setCookieJar(axiosCookieJarSupport.wrapper, cookieJar);

// login, get the event/agenda/song data and finally the url of the file you want to download
const url = 'https://demo.church.tools/?q=public/filedownload&id=12345&filename=abcdef...';

const file = fs.createWriteStream("file.pdf");
https.get(
    url,
    {
        headers: {
            Cookie: await cookieJar.getCookieStringSync()
        }
    },
    (response) => {
        response.pipe(file);

        file.on("finish", () => {
            file.close();
            console.log("Download Completed");
        });
    }
);

I hope I could help you a bit. If anything's missing, don't hesitate to reach out again.

Gesegnete Ostern!

– Andreas
Developer @ ChurchTools

@xeruf
Copy link
Author

xeruf commented Apr 11, 2023

Dankeschön!
See also https://forum.church.tools/topic/9299/wie-kann-ich-song-attachments-hoch-und-herunterladen-via-js

Our client library is not yet capable of downloading files and it's currently not on the roadmap to introduce this feature.

What would be the suggested way? I have no problem using another language :)

I'll try the workaround regardless.

I'm not sure if that problem still exists when you use the correct domainType. If so, please reach out again, then I'll take a closer look.

As I said, I tried all domaintypes, the current code is here, not working with service:
https://code.ftt.gmbh/janek/carvent/src/commit/f0d68dc68e3eda7a784195897bde1ad67d11e8ab/index.js#L82

@xeruf
Copy link
Author

xeruf commented Apr 30, 2023

I have tried it exactly as suggested, with cookieJar as a global constant, but I get

/home/janek/data/1-projects/1-personal/carvent/index.js:70
                    Cookie: await cookieJar.getCookieStringSync()
                                  ^^^^^^^^^

SyntaxError: Unexpected identifier 'cookieJar'

@andreasmischke
Copy link
Contributor

Our client library is not yet capable of downloading files and it's currently not on the roadmap to introduce this feature.

What would be the suggested way? I have no problem using another language :)

In a nutshell, it's not intended to download any files via the API. They should only be downloaded via a browser or similar client that has been logged in and has a valid session cookie. If you can "simulate" this in any way (e.g. with my code snippet from above) you can use whatever language you like.

As I said, I tried all domaintypes, the current code is here, not working with service:

I don't think the problem is the domaintype then. I haven't worked with file uploads myself yet, but in our frontend code, it looks like this:

const formData = new FormData();
formData.append('files[]', file);
// some more form data
churchtoolsClient.post(`/files/service/${id}`, formData);

There are two things that could be the problem with your code (just guessing):

  1. formData.append('files[]', file) instead of formDAta.append("files", [file])
  2. In the browser the file is a Blob, in your code the pdf-merger-js gives you a Buffer. Maybe you need to convert it from Buffer to Blob.

I have tried it exactly as suggested, with cookieJar as a global constant, but I get

The problem is here: https://code.ftt.gmbh/janek/carvent/src/branch/main/index.js#L60 If you want to use await inside a function, that function must be marked as async:

).then(async (result) =>

I hope this gets you further!

– Andreas
Developer @ ChurchTools

@andreasmischke
Copy link
Contributor

@xeruf I'm closing this issue for now.

If you need further assistance, feel free to reopen it.

@xeruf
Copy link
Author

xeruf commented Jul 27, 2023

Managed to successfully download, now just failing on the upload, see https://code.ftt.gmbh/janek/carvent/src/branch/main/index.js#L101

[ChurchToolsClient][Error] POST https://MYCHURCH.church.tools/api/files/service/2241
/home/janek/data/1-projects/1-personal/carvent/node_modules/@churchtools/churchtools-client/node_modules/axios/lib/core/createError.js:16
  var error = new Error(message);
              ^

Error: Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream
    at createError (/home/janek/data/1-projects/1-personal/carvent/node_modules/@churchtools/churchtools-client/node_modules/axios/lib/core/createError.js:16:15)
    at dispatchHttpRequest (/home/janek/data/1-projects/1-personal/carvent/node_modules/@churchtools/churchtools-client/node_modules/axios/lib/adapters/http.js:96:23)

I have tried Buffer, Blob and reading from file stream as suggested in https://stackoverflow.com/questions/25344879/uploading-file-using-post-request-in-node-js/25345124#25345124 but I am not getting anywhere...

@aschojz
Copy link

aschojz commented Jul 27, 2023

Have you tried something like that? IMO you don't need to save and read the file again, this should be fine with saving as a blob

const PDFMerger = require('pdf-merger-js');
const merger = new PDFMerger();
return new Promise(async (resolve) => {
  for(const file of result) {
    await merger.add(file.value);
  }

  const merged = `${date}/${date}-songs-akkorde.pdf`
  const mergedPdfBuffer = await merger.saveAsBlob();

  const data = new FormData();
  data.append("files[]", mergedPdfBuffer)

  resolve(await churchtoolsClient.post(`/files/service/${event.id}`, data))
})

@aschojz aschojz reopened this Jul 27, 2023
@xeruf
Copy link
Author

xeruf commented Jul 28, 2023

that is what I thought as well, but mergeAsBlob is not part of the nodejs version of pdf-merger-js :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants