I found the overall documentation around media handling quite confusing.
We have a specific Workshop widget for media upload, however it is written:
“For single item uploads to media sets, configure an Action in Ontology Manager and use the Button Group widget to invoke it.”
So for a single media, do not use Media upload widget but a button + Ontology action?
As well, selecting Media set in this Media upload widget:
“Uploads to media sets are the preferred upload type for supported file formats. If selecting an action that creates an object, please set up the object using string as the property type, rather than media reference.”
A .PNG, for example is a supported file format of Media Set, so should I use this or not ?
As well, if I do use this widget, do not use media reference type in my object but a string?
As you’ve indentified, we do recommend setting up an Ontology action that takes a media reference parameter and then using a button in workshop to invoke that action. This will work for single file uploads, or uploading multiple files if you use the action table UI instead.
There are some cases where you may need to use the media uploader widget - for example, if you are uploading media to a legacy format (eg. a dataset).
Hopefully you can use an ontology action instead though, as it should be easier to set up and configure. However, we will definitely look into improving the documentation to make it less confusing.
Upload a document (.PNG, .JPG or .PDF) to an object backed by a mediaset, have it available in the Media viewer widget immediately (which I believe is not an issue for a transactionless mediaset?), the user will add some object properties (Document name, schema, …) and confirm the object properties update to apply the change to the object.
First issue I am encountering with using a Button+Action is that it seems to only accept .PDF file type. I understand that non PDF are automatically converted as PDF on upload.
The upload workflow in actions will accept any media type/format that the backing media set (ie. the media set that backs the media reference property) supports. So if your backing media set is a Document type and allows .png, .jpg and .pdf files, the action will allow all of those to be uploaded.
We’re shipping a change to make sure all of these formats get listed in UI, as it currently only lists one format and not all the supported formats as you’ve pointed out.
It very much sounds like you should be able to use the action for this workflow and we’d recommend using that! But if there are any issues, please do let me know
You should be able to pass in a media reference to your TypeScript function as the type MediaItem. From there, you can read the bytes and use them as you wish
For example this would be how you could read a PDF file:
@Function()
public async myFunction(mediaItem: MediaItem): Promise<void> {
if (MediaItem.isDocument(mediaItem)) {
const media = await mediaItem.readAsync();
...
}
}
But, I found a workaround for my use-case. I can just convert the PDF in Base64 withour error and forward it to my model. The conversion from Base64 to PDF/Image is done on the live deployed model side.
It is not optimum but it is working until Model Adapters can handle Media Item directly.
import { Function, MediaItem } from "@foundry/functions-api";
import { myObject } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public async pdfToBase64(mediaItem: myObject ): Promise<string> {
// Ensure the media reference exists
if (!mediaItem.mediaReference) {
throw new Error("Media reference is missing.");
}
// Fetch raw media data
const blob = await mediaItem.mediaReference.readAsync();
// Convert Blob to base64 string
const base64String = await this.blobToBase64(blob);
// Add the prefix for PDF Base64 data
const prefixedBase64String = `data:application/pdf;base64,${base64String}`;
return prefixedBase64String;
}
// Helper function to convert Blob to base64 string using Buffer (Node.js)
private async blobToBase64(blob: Blob): Promise<string> {
// Convert Blob to ArrayBuffer
const arrayBuffer = await blob.arrayBuffer();
// Convert ArrayBuffer to Buffer (Node.js)
const buffer = Buffer.from(arrayBuffer);
// Convert Buffer to base64 string
return buffer.toString('base64');
}
}