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.
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 have two API calls, one is an input for the second, I'm defining them as two actions now, but I wonder if I can merge them together in one action, I couldn't find that in the documentation, is that possible? and how?
My case is that I have an action that creates an invoice and returns back its id, the id then is being passed to another API to confirm that invoice and returns back a pdf.
Should I encapsulate the APIs from the back-end? or does it work if I called the second API inside the "then" method:
const options = {
url: 'https://my.fastbill.com/api/1.0/api.php',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
params: {
},
body: {
'SERVICE': 'invoice.complete',
'DATA' : {
'INVOICE_ID': bundle.inputData.INVOICE_ID
}
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;
// Call the second API here
return results;
});
Yes you can use a hidden trigger to call the first action and pass the input into a dynamic dropdown , then use it along the other inputs to submit the final action.
https://platform.zapier.com/cli_tutorials/dynamic-dropdowns
i'm trying to post some data with fetch medthod in my api
export const CREATE_MATCH = 'CREATE_MATCH'
export function createMatch(user) {
const request = fetch("/api/matches", {
// Adding method type
method: "POST",
// Adding headers to the request
headers: {
"Content-type": "application/json",
"X-User-Token": user.authentication_token,
"X-User-Email": user.email
}
})
return {
type: CREATE_MATCH,
payload: request
}
}
but the i only get the response and not the data created
Response {type: "basic", url: "http://localhost:3000/api/matches", redirected: false, status: 200, ok: true, …}
i dont know how to get the data created.
in rails this is what i have, i dont have any data in a Match, only id and timestamps
def create
#match = Match.new
authorize #match
if #match.save
render json: #match
else
render_error
end
end
i've just find an answer with async / await function
export async function createMatch(user) {
const request = await fetch("/api/matches", {
// Adding method type
method: "POST",
// Adding body or contents to send
// body: JSON.stringify(),
// Adding headers to the request
headers: {
"Content-type": "application/json",
"X-User-Token": user.authentication_token,
"X-User-Email": user.email
}
})
const match = await request.json();
console.log(match)
return {
type: CREATE_MATCH,
payload: match
}
}
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.
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).