Dynamic creation of JSON for API input body

I’m working with the Microsoft Graph API, but I’ve run into a problem. I simply want to send emails through the API. I’m calling the API from a function, and from that function, I’m passing the email addresses of the people I want to receive the email. With just one person, it’s easy: a string input and that’s it.

The problem arises when more than one person needs to receive the email. Simply passing all the strings isn’t enough, since the API request body has a specific structure for each email address.

My question is, how can I pass an array of strings with the email addresses and be able to “repeat” that structure for each email address? I need to do this in the Data Connection section of the API request.

Below, I’m sharing the request body.

{
    "message": {
        "subject": Subject,
        "body": {
            "contentType": "Text",
            "content": Content
        },
        "toRecipients": [
            {
                "emailAddress": {
                    "address": Recipients (This is what I need to repeat for each recipient)
                }
            }
        ]
    },
    "saveToSentItems": "True"
}

Thanks,
Mateo

Hi Mateo,

Hope you are well.

This sounds like a super solvable problem, but some more information would be super helpful to properly form a solution.

If you could detail what the whole function script looks like + how the Graph API is configured in Data Connection, that would be great.

My initial idea would be to form the JSON request body inside your function logic, iterate over the list of emails and hit the Data Connection webhook for each email with the custom formed JSON body.

thanks,
Azeem

Hello @azeemaf, thanks for your reply.

Essentially, after much testing, I’ve realized that the only way is to work with all of this directly from the Data Connection, manipulating the input fields and passing it an array of emails.

Then I simply call the connection from a function so I can call the webhook from Workshop and make the request.

The problem is that I am unable to replicate using the input, the request body.

I’ve also tried unsuccessfully to pass the body created by a script from the code repository as a string, and it hasn’t worked.

Regards,
Mateo

Hey Mateo,

Thanks for the info. I just want to confirm that the following solution is not working for you:

I am using Typescript V2 functions for this demo, but both TsV1 and Python will work for this.

Having set up a source and allowing for exports:


The following script iterates over the array of emails, forms the body of the request with the given email and makes the request:

import { getSource, getHttpsConnection, getFetch } from "@palantir/functions-sources";

export const config = {
    sources: ["Httpbin"]
}

async function aafAPITest(emailArray: string[]): Promise<string> {
    const source = await getSource("Httpbin");
    const { url } = getHttpsConnection(source)!;
    const fetch = await getFetch(source);

    for (const email of emailArray) {

        const formBody = {
            "email": email
        }

        const response = await fetch(`${url}/post`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(formBody)
        });

        console.log(JSON.parse((await response.text())).json)
    }

    return "ok"
}

export default aafAPITest;

Please let me know if this achieves the workflow you are looking for

Thanks,
Azeem

Hello again, thank you very much for your reply.

Your code help me a lot to call the source from the code repo, but one thing that I need to use, is the webhook, there I have the api url and the authentication for the request.

What I need if its possible is, put the body with my emails in the webhook to do the request.

Could you help me with this?

Regards,
Mateo

Hey Mateo

To use webhooks directy within code, you will need to setup a Typescript V1 Functions Repo

Here is a notional example of how you would use TSv1 and webhooks to pass a custom JSON body into the request:

I have setup a webhook to hit the endpoint, crucially the entire body of the request is represented by a string input parameter (we will form the JSON body in the code repo):

I have also setup the output of the webhook (see docs for more info)

Once this webhook has been setup, we can call it from the TSv1 repo:

import { OntologyEditFunction, isOk } from "@foundry/functions-api";
import { Httpbin } from "@foundry/external-systems/sources";

export class MyFunctions {

    @OntologyEditFunction()
    public async testAPI(emailArray: string[]): Promise<void> {

        for (const email of emailArray) { 

            const requestBody = { "email": email };
            const result = await Httpbin.webhooks.BinEcho.call({
                bodyJSON: JSON.stringify(requestBody)
            });

            if (isOk(result)) {
                console.log(result.value.output.json);
            }

        }

        return;
    }

}

Hope this makes sense, please let me know if you need further clarification