# Convert a binary to base64 or send multipart/form-data

**URL:** <https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269>\
**Category:** API & Programming\
**Created:** [June 5, 2024, 4:09am UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269 "2024-06-05T04:09:25Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [June 5, 2024, 4:09am UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/1 "2024-06-05T04:09:25Z")

</div>

Hello dear friends,

is there a way to convert a binary file which I’ve retrieved inside a **Action Button Script** using the Fibery File API to a Base64 format, also inside the same Script?

Or, another option for me, would be to send this binary file through the http.postAsync using a “multipart/form-data” content-type

See the two options bellow, please

```auto
// OPTION 1 - send a binary file to a external API using a multipart/form-data Content-type

for (const file of files['Files']) {

	const fileWithSecret = await fibery.getEntityById("fibery/file", file['id'], ["Secret", "Name", "Content Type"]);
	const fileUrl = "http://<mydomain>.fibery.io/api/files/" + fileWithSecret["Secret"];

	const f = await http.getAsync(fileUrl, { 'headers': { 'Authorization': 'Token mytoken' } });
	
	// here is the external API to where I need to send the file 
	const responseArquivo = await http.postAsync('https://myexternalapi', {
		body: // HOW DO I PASS multipart/form-data HERE? ... let's say I have two keys here: file_name and file (the binary itself)
			
		,
		headers: {
			'Content-type': 'multipart/form-data',
			'apikey': 'xxxxx'
		}
	});

}

// OPTION 2 - send a BASE64 to a external API using a application/json Content-type

for (const file of files['Files']) {

	const fileWithSecret = await fibery.getEntityById("fibery/file", file['id'], ["Secret", "Name", "Content Type"]);
	const fileUrl = "http://<mydomain>.fibery.io/api/files/" + fileWithSecret["Secret"];

	const f = await http.getAsync(fileUrl, { 'headers': { 'Authorization': 'Token mytoken' } });
	
	// here is the external API to where I need to send the file 
	const responseArquivo = await http.postAsync('https://myexternalapi', {
		body: {
			filename: fileWithSecret["Name"],
			file: // HERE I NEED A BASE64 string representation of the file
		}
		,
		headers: {
			'Content-type': 'application/json',
			'apikey': 'xxxxx'
		}
	});

}

```

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [June 5, 2024, 7:27pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/2 "2024-06-05T19:27:52Z")

</div>

To get base64, you can use the [javascript btoa function](https://developer.mozilla.org/en-US/docs/Web/API/btoa).

---

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [June 5, 2024, 10:04pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/3 "2024-06-05T22:04:52Z")

</div>

I tryed but it didn’t work.

![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/b/ba15f1ced6800be24286e2e2ca6edb32520fbc65.png)

![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/7/7de9efe82f6e99fb5e8822ce44ed6b62be1ae74e.png)

---

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [June 14, 2024, 3:55pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/4 "2024-06-14T15:55:16Z")

</div>

Hi guys, so far I wasn’t able to accomplish this.

I even look for some plain algortims to convert to base64 but it didnt work too ☹

---

<div class="post-metadata">

**Author:** ![derbenoo](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/derbenoo/32/11540_2.png) [@derbenoo](https://community.fibery.io/u/derbenoo)\
**Post date:** [June 15, 2024, 11:06am UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/5 "2024-06-15T11:06:06Z")

</div>

Hey @adrielmoro,

the function `btoa` does not exist in the reduced Fibery sandbox environment for the Script action. An alternative is the `Buffer.from` function available in Node, however the `Buffer` keyword is also not part of the Fibery script environment. You therefore have to paste the following code into your script action, which implements base64 encoding from scratch.

I took it from an npm package and adjusted it so that it can run inside the Fibery Script action:

```js
const base64Characters =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

function textToBinary(text) {
  let binaries = "";

  for (let i = 0; i < text.length; i++) {
    const letterBinary = text.charCodeAt(i).toString(2);
    const letterBinary8Bits = letterBinary.padStart(8, "0");
    binaries += letterBinary8Bits;
  }

  return binaries;
}

function groupBinariesByNumberOfBits(binary, quantityOfBits) {
  const regex = new RegExp(`.{1,${quantityOfBits}}`, "g");
  const groupedBinaries = binary.match(regex);
  const binariesWithQuantityOfBits = groupedBinaries.map((binary) =>
    binary.padEnd(quantityOfBits, "0")
  );

  return binariesWithQuantityOfBits;
}

function binaryToDecimal(binary) {
  const decimal = parseInt(binary, 2);
  return decimal;
}

function binaryToBase64(binary) {
  const groupedBinaries = groupBinariesByNumberOfBits(binary, 6);
  const base64 = groupedBinaries.map((binary) => {
    const decimal = binaryToDecimal(binary);
    return base64Characters[decimal];
  });

  const base64ArrayAsString = base64.join("");
  return base64ArrayAsString;
}

function addEndChar(text, base64) {
  const remainderMultipleOf3 = {
    0: "",
    1: "==",
    2: "=",
  };

  const remainder = text.length % 3;
  const base64WithEndChar = base64.concat(remainderMultipleOf3[remainder]);
  return base64WithEndChar;
}

function base64Encode(text) {
  if (!text) return text;

  let data = "";
  data = text;
  const binary = textToBinary(data);
  const base64 = binaryToBase64(binary);
  const base64WithEndChar = addEndChar(data, base64);
  return base64WithEndChar;
}

// Example: this correctly prints 'dGVzdA=='
console.log(base64Encode("test"));

```

You can now use the function `base64Encode` to base64 encode any string inside your Script action 👍

 ![Screenshot 2024-06-15 at 13.07.48](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/6/637fc344493e525067a832fccf2f3883b4e437da.png)

---

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [July 15, 2024, 3:16pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/6 "2024-07-15T15:16:25Z")

</div>

Hi there @derbenoo … thanks a lot for your attention on this.

Sorry for the delayed answer, got some other issues here and only now I’m returning on this.

I’ve tested the script you’ve shared and it works well with text data 🙂.

But I’m downloading a binary file, like in the code below.

I’ve also tested with others scripts I’ve found on the internet that deals with binary ones. It didn’t work too. I’m suspecting the function “**await http.getAsync(fileUrl, { ‘headers’: { ‘Authorization’: ‘Token mytoken’ } });**” is somehow messing the content up before returning the result, perhaps forcing it to a string type. I’m not sure. I couldn’t figure it out.

```auto

for (const entity of args.currentEntities) {

    try {

        const files = await fibery.getEntityById(entity.type, entity.id, ['Files']);

        for (const file of files['Files']) {

            const fileWithSecret = await fibery.getEntityById("fibery/file", file['id'], ["Secret", "Name", "Content Type"]);
            const fileUrl = "http://mydomain.fibery.io/api/files/" + fileWithSecret["Secret"];

            // download file (perhaps here the things are getting wrong)
            const f = await http.getAsync(fileUrl, { 'headers': { 'Authorization': 'Token mytoken' } });

            const base64EncodedFile = base64Encode(f) // here your original function expects a text instead of a binary

            //console.log(['tipo', Object.prototype.toString.call(f)]);
            console.log(['File in b64', base64EncodedFile]);

        }
    } catch (e) {
        console.error(e)
        throw (e)
    }

}

```

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [July 15, 2024, 6:49pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/7 "2024-07-15T18:49:36Z")

</div>

> [@adrielmoro](#):
>
> `http.getAsync`

Did you log the result you got from `http.getAsync()` ?

---

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [July 16, 2024, 2:55pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/8 "2024-07-16T14:55:55Z")

</div>

Yes… this is a print of the console.

 ![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/2/2fce453a2426dad69e6b53a0dd6676c915fce462.png)

And here a print of the file as I opened it on Notepad ++

 ![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/b/b715219ab07aaba1e693180a18dc0d2e06f178e1.png)

This is a link for the file I’m running the tests:  
[Test Document.pdf](https://drive.google.com/file/d/11OekNO8pWyCesH6h_GZLZUMvLLNk67Uo/view?usp=sharing)

And here a link to the full copy of the console log:  
[ConsoleLog.txt](https://drive.google.com/file/d/1xF-VcAWr9eBC2MBWxjIPAYvnv3_1mUcU/view?usp=sharing)

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [July 16, 2024, 5:20pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/9 "2024-07-16T17:20:39Z")

</div>

Please double check the type of the return value from `http.getAsync()`, so you know exactly what you’re dealing with – e.g. [is it a String, ArrayBuffer, etc](https://www.perplexity.ai/search/javascript-arraybuffer-LaqG7.DdR32sDha8exU1Eg).

---

<div class="post-metadata">

**Author:** ![adrielmoro](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/adrielmoro/32/8107_2.png) [@adrielmoro](https://community.fibery.io/u/adrielmoro)\
**Post date:** [July 25, 2024, 6:52pm UTC](https://community.fibery.io/t/convert-a-binary-to-base64-or-send-multipart-form-data/6269/10 "2024-07-25T18:52:37Z")

</div>

Hi there, I’m back 🙂

this is how I’ve tested the type.

```auto
            const f = await http.getAsync(fileUrl, { 'headers': { 'Authorization': 'Token mytoken' } });

            console.log(['Type: ', Object.prototype.toString.call(f)])
            console.log(['Type: ', typeof f])

```

and it returns

![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/8/8ec54e35d38828f304813f90faa8164a00dc11d4.png)

So, it seems the method http.getAsync is designed for text responses only. I suppose this convertion is corrupting the file content.

I’ve also came across with the following issue with this method (it has a limit size in response)

 ![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/c/c769efdfff1d941f8a14340892defabcbd368e63.png)
