I have a simple zapier integration built and it works perfectly. However, I'm adding dynamic fields. Again it all seems to work perfectly when I test the zap. My dynamic form fields appear just as I expected.
The problem is sending the value of those dynamic forms to my API. I am using the zapier console and when I configure the API request I am using the following:
Where body['custom_fields'] is supposed to send all my dynamic fields or even all of the fields. But when it hits my API custom_fields parameter is blank.
const options = {
url: 'https://example_url/endpoint',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${bundle.authData.auth_token}`
},
body: {
'email': bundle.inputData.email,
'custom_fields': bundle.inputData
/**
I've tried the following with no luck:
'custom_fields': bundle.inputData.fields
'custom_fields': bundle.inputData.undefined
'custom_fields': bundle.inputData
*/
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;
// You can do any parsing you need for results here before returning them
return results;
});
Ok after a few days, it's the simplest answer.
Obviously an object can't be sent over params.
so instead of having
'custom_fields': bundle.inputData
I just add the whole object to the params and it takes care of all keys and values
params: bundle.inputData
Here is the full body
const options = {
url: 'https://apiendpoint.com',
method: 'POST',
headers: {
'Authorization': `Bearer ${bundle.authData.auth_token}`
},
params: bundle.inputData,
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;
// You can do any parsing you need for results here before returning them
return results;
});
You can use the spread operator ...bundle.inputData like explained in the doc:
https://platform.zapier.com/docs/input-designer#how-to-include-dynamic-fields-in-api-calls
const options = {
url: 'https://example_url/endpoint',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${bundle.authData.auth_token}`
},
body: { ...bundle.inputData }
}
You can even namespace your request data like that:
body: {
request: { ...bundle.inputData }
}
NB : the spread operator raises a syntax error in Zapier code editor, but it works.
Related
I've created a new Zapier integration and it works okay so far. But when I turn of the Zap created using the integration, the unsubscribe webhook doesn't get called. For testing, I've used https://webhook.site as the unsubscribe url but it never gets called. Here's the code that shows in the unsubscribe code mode:
const options = {
url: 'https://webhook.site/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-KEY': bundle.authData.key
},
params: {
},
body: {
'hookUrl': bundle.subscribeData.id,
'key': bundle.authData.key
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;
// You can do any parsing you need for results here before returning them
return results;
});
I am working on a trigger where I need to pull data from two API end points. The first endpoint is a contact from a database that retrieves an email address, then to obtain the details for that contact (email) I need to use another end point. once is /Subscriber and the other is /Subsriber/ {email}/ Properties.
I am wondering if I can use a variable to obtain all the data in one trigger, as I have is set up in separate triggers right now.
Here is the code for both
Subscriber:
url: 'https://edapi.campaigner.com/v1/Subscribers?PageSize=1',
method: 'GET',
headers: {
'Accept': 'application/json',
'X-API-KEY': bundle.authData.ApiKey
},
params: {
'ApiKey': bundle.authData.ApiKey
}
};
return z.request(options).then((response) => {
response.throwForStatus();
const result = z.JSON.parse(response.content);
result.id = result.Items;
return [result];
});
And Subscriber Properties
const options = {
url: `https://edapi.campaigner.com/v1/Subscribers/${bundle.inputData.email_address}/Properties`,
method: 'GET',
headers: {
'Accept': 'application/json',
'X-API-KEY': bundle.authData.ApiKey
},
params: {
'email_address': bundle.inputData.email_address,
'ApiKey': bundle.authData.ApiKey
}
}
return z.request(options).then((response) => {
response.throwForStatus();
const result = z.JSON.parse(response.content);
result.id = result.CustomFields;
return [result];
});
Any help is appreciated.
Yes, definitely possible! Unless your subscriber data actually needs to be a separate trigger (which is unlikely, since you probably just trigger off new contacts), it can just be a function. Try something like:
const subscriberPerform = async (z, bundle) => {
const emailResponse = await z.request({
url: "https://edapi.campaigner.com/v1/Subscribers?PageSize=1",
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": bundle.authData.ApiKey, // does this need to be both places?
},
params: {
ApiKey: bundle.authData.ApiKey, // does this need to be both places?
},
});
// requires core version 10+
const email = emailResponse.data.email;
const emailDataResponse = await z.request({
url: `https://edapi.campaigner.com/v1/Subscribers/${email}/Properties`,
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": bundle.authData.ApiKey,
},
params: {
email_address: bundle.inputData.email_address, // lots of duplicated data here
ApiKey: bundle.authData.ApiKey,
},
});
return [emailDataResponse.data.SOMETHING];
};
That's the general idea. These JS functions may not need to be triggers at all, depending on how you're using them.
One last note - you don't want to perform this extra lookup every time you poll for new contacts; that's wasteful. If you're doing that, check out dehydration.
I am setting up a Zap for our application in Zapier.
However, I've run into some trouble having the Zap pass over the data in the correct format.
By default it appears Zapier passes the data as json request body, but our backend only accepts form-data.
Is it possible to configure the Zap to send over form-data instead?
In the code below, I've tried to send the data as both params and body, but my backend doesn't any of it as form-data:
const options = {
url: '${URL}',
method: 'POST',
headers: {
'Authorization': ${token},
'Content-Type': 'application/json',
'Accept': 'application/json'
},
params: {
'phone': bundle.inputData.phone,
'email': bundle.inputData.email,
'dialog': bundle.inputData.dialog,
'name': bundle.inputData.name
},
body: {
'name': bundle.inputData.name,
'email': bundle.inputData.email,
'phone': bundle.inputData.phone,
'dialog': bundle.inputData.dialog
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
// You can do any parsing you need for results here before returning them
return results;
});
Any input is greatly appreciated!
I fixed it by replacing 'Content-Type': 'application/json' with 'Content-Type': 'application/x-www-form-urlencoded'.
I wanted to send a POST request to my backend with webview. How do i get but i got the above error.
From the docs:
" headers (object) - Additional HTTP headers to send with the request. On Android, this can only be used with GET requests."
How do i get a work-around for this ?
this is my code
const data = JSON.stringify({
type: 'car',
plate_number: 'c123'
});
return (
<WebView
source={{
uri:'https://api-stg.caspian.id/user/vehicles/add',
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: '54dc3c3c*******'
},
body: data
}}
/>
);
One way to get around this limitation is by performing this POST request in the React Native side of things, waiting for this response to arrive, and then feed the response HTML into the WebView directly:
// Here using the fetch API as base, but you can use any
// library you want that is able to perform HTTP requests
constructor(props, ctx) {
super(props, ctx);
this.state = { html: null };
}
componentDidMount() {
const data = JSON.stringify({
type: 'car',
plate_number: 'c123'
});
fetch('https://api-stg.caspian.id/user/vehicles/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: '54dc3c3c*******'
},
body: data,
}).then(response => response.text()).then(text => {
this.setState({ html: text });
});
}
render() {
return this.state.html ? (
<WebView
source={{
html: this.state.html,
baseUrl: 'https://api-stg.caspian.id/user/vehicles/add',
}}
originWhitelist={['*']}
/>
) : /* loading UI */ null;
);
Here are the WebView's docs regarding the source property and how to put a static HTML in there:
https://facebook.github.io/react-native/docs/webview#source
You can use a custom extension of WebView, as described in Send Post request along with HttpHeaders on Android (see the duplicate questions for other answers).
In a react-native app, I have the following post request that goes to a rails controller
fetch(POST_PAID_UP, {
method: 'POST',
body: JSON.stringify({
receipt_num: 127,
}).replace(/{|}/gi, "")
})
In the appropriate action of my rails controller I can examine params it looks like this;
{"\"receipt_num\":127"=>nil, "controller"=>"ios/accounts", "action"=>"create"}
so the data is being received. From params I need to extract the value of 'receipt_num'. I have tried JSON.parse(params), but I receive this error;
TypeError: no implicit conversion of Array into String
So how should I parse this data?
You need to add headers that indicate that the information being sent is of type json. So add the following hash to the fetch instruction;
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
You can then remove the .replace(/{|}/gi, "") which is just a work around to overcome the fact that you were not specifying the data was json. The final code should look like this:
fetch(POST_PAID_UP, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
receipt_num: transactionIdentifier,
})
})
You can find more information about fetch here