I’ve been having trouble with requestUrl()
and thought I’d post here to see if anyone can help. First, a little background on the idea.
I have a family-only forum setup. One of my cousins likes to use Obsidian (I’ve been using obsidian for a while now as well, but just as a simple note taking app. I was not aware of how robust the software is). He has been creating a vault for containing log data and general descriptions of our equipment. When he compiles these notes, he’s in a location which has no internet. So reaching the Discourse server is impossible.
My thought was, why not create a plugin that syncs data to the server using an API key. The trouble comes when handling images. Now, I realize this isn’t a Discourse API forum, but maybe someone here is smarter than me and might be able to help with my issue.
Here’s my post over at Discourse forum that describes the issue.
Here’s my repo in its current state.
Briefly, the issue that I’m having is that I can’t simply use FormData() to create a packet and use fetch() to upload images to the API. So what I tried was creating my own Uint8Array. But so far, that hasn’t worked. I’m not sure if my packet is malformed, or the parameters are incorrect, or maybe the image is in the wrong place in the home-brewed FormData. Here’s the function I currently have and the error code associated:
async uploadImages(imageReferences: string[]): Promise<string[]> {
const imageUrls = [];
for (const ref of imageReferences) {
const filePath = this.app.metadataCache.getFirstLinkpathDest(ref, this.activeFile.name)?.path;
if (filePath) {
const file = this.app.vault.getAbstractFileByPath(filePath) as TFile;
if (file) {
try {
const imgfile = await this.app.vault.readBinary(file);
const boundary = genBoundary();
const sBoundary = '--' + boundary + '\r\n';
let body = '';
body += `${sBoundary}Content-Disposition: form-data; name="type"\r\n\r\ncomposer\r\n`;
body += `${sBoundary}Content-Disposition: form-data; name="synchronous"\r\n\r\ntrue\r\n`;
body += `${sBoundary}Content-Disposition: form-data; name="files[]"; filename="${file.name}"\r\nContent-Type: image/jpg\r\n`;
const eBoundary = '\r\n--' + boundary + '--\r\n';
const bodyArray = new TextEncoder().encode(body);
const endBoundaryArray = new TextEncoder().encode(eBoundary);
const formDataArray = new Uint8Array(bodyArray.length + imgfile.byteLength + endBoundaryArray.length);
formDataArray.set(bodyArray, 0);
formDataArray.set(new Uint8Array(imgfile), bodyArray.length);
formDataArray.set(endBoundaryArray, bodyArray.length + imgfile.byteLength);
const url = `${this.settings.baseUrl}/uploads.json`;
const headers = {
"Api-Key": this.settings.apiKey,
"Api-Username": this.settings.disUser,
"Content-Type": `multipart/form-data; boundary=${boundary}`
};
const response = await requestUrl({
url: url,
method: "POST",
body: formDataArray,
throw: false,
headers: headers,
});
if (response.status == 200) {
const jsonResponse = response.json();
console.log(`Upload Image jsonResponse: ${JSON.stringify(jsonResponse)}`);
imageUrls.push(jsonResponse.url);
} else {
new NotifyUser(this.app, `Error uploading image: ${response.status}`).open();
console.error(`Error uploading image: ${JSON.stringify(response.json)}`);
}
} catch (error) {
new NotifyUser(this.app, `Exception while uploading image: ${error}`).open();
console.error("Exception while uploading image:", error);
}
} else {
new NotifyUser(this.app, `File not found in vault: ${ref}`).open();
console.error(`File not found in vault: ${ref}`);
}
} else {
new NotifyUser(this.app, `Unable to resolve file path for: ${ref}`).open();
console.error(`Unable to resolve file path for: ${ref}`);
}
}
return imageUrls;
}
Here’s the genBoundary()
function:
const genBoundary = (): string => {
return '----WebKitFormBoundary' + Math.random().toString(36).substring(2, 15);
}
Error code:
Error uploading image: {“errors”:[“You supplied invalid parameters to the request: Discourse::InvalidParameters”],“error_type”:“invalid_parameters”}
Any help would be appreciated!
Also, I found this repo, but I wasn’t able to take that and make it work either…