Javascript multiple fetch calls inside a Cloudflare Worker - javascript

I am trying to parse responses back from the following fetch api calls. I am able to display the response as a string, but I would like to get specific properties from the json blob and I am struggling to do so. I am not sure how to access the json object properties inside the Response Object.
This is for a cloudflare worker using ES6.
The Json structure is here: json response
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "699d98642c564d2e855e9661899b7252",
"created_on": "2014-01-01T05:20:00.12345Z",
"modified_on": "2014-01-01T05:20:00.12345Z",
"name": "server-1",
"description": "Health check for www.example.com",
"suspended": false,
"notification": {
"suspended": false,
"email_addresses": [
"alert#example.com",
"oncall#example.com"
],
"trigger": "FAIL"
},
"check_regions": [
"WEU",
"ENAM"
],
"type": "HTTPS",
"consecutive_successes": 1,
"consecutive_fails": 1,
"http_config": {
"method": "GET",
"port": 80,
"path": "/health",
"expected_codes": [
"2xx",
"302"
],
"expected_body": "success",
"follow_redirects": false,
"allow_insecure": false,
"header": {
"Host": [
"example.com"
],
"X-App-ID": [
"abc123"
]
}
},
"tcp_config": {
"method": "connection_established",
"port": 80
},
"timeout": 5,
"retries": 2,
"interval": 60,
"address": "www.example.com",
"status": "healthy",
"failure_reason": ""
}
}
const fw1aUrl = "https://api.cloudflare.com/client/v4/zones/<>/healthchecks/<>"
const fw1bUrl = "https://api.cloudflare.com/client/v4/zones/<>/healthchecks/<>"
let temp = {}
async function handleRequest() {
const init = {
headers: {
"content-type": "application/json;charset=UTF-8",
"X-AUTH-EMAIL": CLOUDFLARE_API_EMAIL,
"X-AUTH-KEY": CLOUDFLARE_API_KEY,
},
}
const [fw1aResponse, fw1bResponse] = await Promise.all([
fetch(fw1aUrl,init),
fetch(fw1bUrl,init)
]);
const fw1aresult = await fw1aResponse.json()
const fw1bresult = await fw1bResponse.json()
temp.fw1a = await fw1aresult
temp.fw1b =await fw1bresult
const jsonobj = await JSON.parse(temp)
console.log(jsonobj)
return jsonobj
}
addEventListener("fetch", event => {
const obj = handleRequest()
console.log(obj.fw1a.result)
console.log(obj.fw1b.result)
return event.respondWith(new Response("hello"))
})
})

Related

Why are asset attributes missing from Imgix Management API?

I am querying the Imgix Management API with no issue. I can retrieve an individual asset and a list of assets. However, most of the data properties are null. It looks like this:
{
"data": {
"attributes": {
"analyzed_content_warnings": null,
"analyzed_faces": null,
"analyzed_tags": null,
"categories": null,
"color_model": null,
"color_profile": null,
"colors": null,
"content_type": "image/jpeg",
"custom_fields": null,
"date_created": 1667935028,
"date_modified": null,
"description": null,
"dpi_height": null,
"dpi_width": null,
"face_count": null,
"file_size": 1016205,
"has_frames": null,
"media_height": null,
"media_kind": "IMAGE",
"media_width": null,
"name": null,
"origin_path": "/test/roses.jpeg",
"source_id": "XXXXXXXXXXXXXXXXXXXX",
"tags": null,
"uploaded_by": null,
"uploaded_by_api": false,
"warning_adult": null,
"warning_medical": null,
"warning_racy": null,
"warning_spoof": null,
"warning_violence": null
},
"id": "XXXXXXXXXXXXXXXXXXX/test/roses.jpeg",
"type": "assets"
},
"included": [],
"jsonapi": {
"version": "1.0"
},
"meta": {
"authentication": {
"authorized": true,
"clientId": null,
"mode": "PUBLIC_APIKEY",
"modeTitle": "Public API Key",
"tag": "XXXXXXXXXXXXXXX",
"user": null
},
"server": {
"commit": "7c78ee15",
"status": {
"healthy": true,
"read_only": false,
"tombstone": false
},
"version": "3.187.0"
}
}
}
I'm missing data.colors, data.media_height, data.media_width.
My code is very basic:
import fetch from 'node-fetch'
const imgix_key = 'xxxxxxxx'
const imgix_source_id = 'xxxxxxxx'
const imgix_url = `https://api.imgix.com/api/v1/assets/${imgix_source_id}/test/roses.jpeg`
async function init() {
const method = 'get'
const headers = {
Authorization: `Bearer ${imgix_key}`,
'Content-Type': 'application/x-www-form-urlencoded',
}
const response = await fetch(imgix_url, { headers, method })
const body = await response.text()
console.log(body)
}
init()
I can access data.colors if I request this image from the rendering API with the palette=json parameter, so I know the property theoretically exists.
Request to https://xxxxxxx.imgix.net/test/roses.jpeg?palette=json:
{
"colors":[
{
"red":0.960784,
"hex":"#f5ece9",
"blue":0.913725,
"green":0.92549
},
{
"red":0.843137,
"hex":"#d7cb99",
"blue":0.6,
"green":0.796078
},
{
"red":0.768627,
"hex":"#c44535",
"blue":0.207843,
"green":0.270588
},
{
"red":0.670588,
"hex":"#aba544",
"blue":0.266667,
"green":0.647059
},
{
"red":0.454902,
"hex":"#746a4f",
"blue":0.309804,
"green":0.415686
},
{
"red":0.227451,
"hex":"#3a452f",
"blue":0.184314,
"green":0.270588
}
],
"average_luminance":0.387471,
"dominant_colors":{
"vibrant":{
"red":0.698039,
"hex":"#b2524d",
"blue":0.301961,
"green":0.321569
},
"muted_light":{
"red":0.823529,
"hex":"#d2b3aa",
"blue":0.666667,
"green":0.701961
},
"muted":{
"red":0.698039,
"hex":"#b2524d",
"blue":0.301961,
"green":0.321569
},
"vibrant_dark":{
"red":0.368627,
"hex":"#5e220c",
"blue":0.0470588,
"green":0.133333
},
"vibrant_light":{
"red":0.898039,
"hex":"#e5c699",
"blue":0.6,
"green":0.776471
},
"muted_dark":{
"red":0.305882,
"hex":"#4e3529",
"blue":0.160784,
"green":0.207843
}
}
}
I've tried adding a fields parameter, like this:
https://api.imgix.com/api/v1/assets/xxxxxxxxxxxxxx/test/roses.jpeg?fields[assets]=name,origin_path,colors,media_width,media_height
I get the specified properties, but they're still null.
Could anyone help me understand why these properties are coming back null?
I would like to write a prebuild script to cache the image metadata so I can set image dimensions and colorful placeholder blocks.
Thanks
I would encourage you to write into our support team (support#imgix.com) with this issue. The reason these fields return null is likely tied to your account/Source settings, which they can help you navigate. Hope that helps.

Property 'data' does not exist on type 'Promise<any>'

I try to type a Promise.
Funcrion's code:
const getActivityLists = async () => {
try {
//let res: Promise<Item[]>
let res: Promise<any>
if (currentPlanValue !== null) {
res = await getPlanActivityList(currentPlanValue.id)
} else {
res = await getActivitiesLists()
}
console.log(res)
createCodesList(res.data)
} catch (error) {
console.log(error)
}
}
The problem is in the 'res.data'.
The network output looks like array of objects that I need.
But if I output 'res' to console, I have this:
{
"data": [
{
"id": "f62b5c25-0d98-4b49-9706-8516875e5527",
"name": "Стажировка 2",
"description": "Как проходить стажировки",
"archive": false,
"activites": [
{
"directionId": "edf8c771-3b01-49c8-84a0-6cf4ed900370",
"activeId": "62b4c56b-3863-4373-8255-3cca6e70d478",
"order": 1,
"name": "DKO"
},
{
"directionId": "4765d688-bc40-4c4f-b039-2dc4b16d3b7c",
"activeId": "cb11db28-d7eb-413a-9348-f253a113c137",
"order": 2,
"name": "STAZH"
},
{
"directionId": "cd5bb29d-c17d-47cb-9a05-ae121c7958fc",
"activeId": "fa547f06-b00a-49fa-b647-0186b8cd3931",
"order": 3,
"name": "REGION"
}
],
"createdAt": "2022-10-28T11:04:28.924Z",
"updatedAt": "2022-10-28T11:04:28.947Z",
"activeId": "27718a9e-706d-4e23-940b-dbd10da3c5b8",
"userId": null,
"historyId": null
}
],
"status": 200,
"statusText": "OK",
"headers": {
"content-length": "4584",
"content-type": "application/json; charset=utf-8"
},
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {
"FormData": null
},
"headers": {
"Accept": "application/json, text/plain, */*"
},
"method": "get",
"url": "http://localhost:3000/activitesList/list"
},
"request": {} }
My array is inside 'data', so I have to pass res.data into function 'createCodesList'.
When I try to type my 'res', I get error:
Property 'data' does not exist on type 'Promise'
How to fix it?
I don't have any idea why Promise doesn't work.
'any' means that inside promise can be anything, doesn't it?
But of course in future I want to type 'res' by my oun type Item[]. It also don't work now.
Type of your response is actual response not a promise as you already awaiting the result so
let res: Promise<any>
should be changed to
let res: any
Or as T.J. Crowder in the comment change it to actual response type
let res:{data:any} //any should be replace with actual model and other properties should be added alongwith data

How to get whole okhttp3 json response and print data?

I'm trying to get account information from site. I am not sure even how to do that. Am using okhttp3.
I would like to retrieve the whole json object and print it out to see the data. I'd liek to see the whole object first but also retrieve only pieces too.
am told to make use GET using this
app.get("/account", async (req, res) => {
console.log(">>>Retrieving");
const account = await stripe.accounts.retrieve(
'acct_1234'
);
});
Then should get object like this
{
"id": "acct_1234",
"object": "account",
"business_profile": {
"mcc": null,
"name": null,
"product_description": null,
"support_address": null,
"support_email": null,
"support_phone": null,
"support_url": null,
"url": null
},
"business_type": null,
"capabilities": {
"card_payments": "active",
"transfers": "active"
},
"charges_enabled": false,
"country": "CA",
"created": 1599337777,
"default_currency": "cad",
"details_submitted": false,
"email": "email#gmail.com",
"external_accounts": {
"object": "list",
"data": [],
"has_more": false,
"url": "/v1/accounts/acct_1234/external_accounts"
},
"metadata": {},
"payouts_enabled": false,
"requirements": {
"current_deadline": null,
"currently_due": [
"business_profile.product_description",
"business_profile.support_phone",
"business_profile.url",
"external_account",
"tos_acceptance.date",
"tos_acceptance.ip"
],
"disabled_reason": "requirements.past_due",
"errors": [],
"eventually_due": [
"business_profile.product_description",
"business_profile.support_phone",
"business_profile.url",
"external_account",
"tos_acceptance.date",
"tos_acceptance.ip"
],
"past_due": [],
"pending_verification": []
},
"settings": {
"bacs_debit_payments": {},
"branding": {
"icon": null,
"logo": null,
"primary_color": null,
"secondary_color": null
},
"card_payments": {
"decline_on": {
"avs_failure": false,
"cvc_failure": true
},
"statement_descriptor_prefix": null
},
"dashboard": {
"display_name": null,
"timezone": "America/Toronto"
},
"payments": {
"statement_descriptor": "",
"statement_descriptor_kana": null,
"statement_descriptor_kanji": null
},
"payouts": {
"debit_negative_balances": true,
"schedule": {
"delay_days": 7,
"interval": "daily"
},
"statement_descriptor": null
}
},
"tos_acceptance": {
"date": null,
"ip": null,
"user_agent": null
},
"type": "custom"
}
Am using Stripe Api here >>>https://stripe.com/docs/api/accounts/create
I've looked around but am not really understanding, am pretty new at using nodejs and okhttp3. Any advice helps. Thank you
I figured it all out. First i had to change the nodejs to\
app.get("/account", async (req, res) => {
console.log(">>>Retrieving");
res.json(await stripe.accounts.retrieve(
'acct_1234'
));
});
And the http request to display all the data and specific values
public void sendGetRequest(String url){
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(30, TimeUnit.SECONDS);
builder.writeTimeout(30, TimeUnit.SECONDS);
httpClient = builder.build();
Request request = new Request.Builder().url(url).build();
try (Response response = httpClient.newCall(request).execute()) {
String responseBody = response.body().string();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String perfectJSON = gson.toJson(JsonParser.parseString(responseBody));
JSONObject json = new JSONObject(perfectJSON);
JSONObject business = json.getJSONObject("business_profile");
String phone = business.getString("support_phone");
String id = json.getString("id");
this.displayAlert(id+" > "+phone,perfectJSON);
}catch (Exception e){
e.printStackTrace();
}
}

Mapping JSON response to using JS

I have a JSON response coming in and I need to map it into an Object and return only the specific fields using js.
Here I have created an example response:
{
"Header": {
"SenderId": "IDMAN",
},
"Shipments": {
"Shipment": [
{
"ShipmentNumber": "KIOKLIOS32",
"Product": {
"value": "1234",
"description": "example desc"
},
"Services": {
"Service": [
{
"value": "0234",
"amount": null,
"unit": null,
}
]
},
...
}
There will be multiple Service's and I need the fields shipments.shipment.product.value and shipments.shipment.services.service.value (all of them from the list).
One of my ideas was to first try create a const:
if (response.status === 200) {
let data = await response.text();
const shipmentData = JSON.parse(data);
const destination = {
"Header": {
"SenderId": _.get(shipmentData, 'Header.SenderId'),
}
};
res.status(200)
.send(destination);
}
This way I can get the senderId but I cannot access the array.
In which way do I have to create my object to map all of this?

Unable to iterate the response body and manipulate/filter the response object using node JS

I have below code which is going to invoke REST endpoint and return response back. I just tried to print the response.body in the console and It works perfectly fine.
var express = require('express');
var app = express();
var PORT = 8001;
var request = require('request');
var HashMap = require('hashmap');
var endPoint="http://sandbox.dev.amazon.com/idsearch/environment/amazon/";
app.get('/productId/:proId',async (req,res) => {
try
{
var headers ={
"accept":"application/json"
}
var options = {
url:endPoint.concat(req.params.proId),
headers:headers
}
request(options, (error,response,body)=> {
console.log(response.body) // It returned response as below output JSON file
res.send("STATUS CODE : 200");
});
}
catch(error)
{
throw error;
}
});
Output:
{
"<Some dynamic Content>": {
"type": "PROD-ID",
"environment": "amazon",
"tags": [
{
"name": "EC-6S0005704A8324S98020",
"source": "amazonstage2ma_paymentapiplatserv#TOKEN",
"flags": [
"FLAG_DYNAMIC_VALUE",
"FLAG_ID_LOOKUP_SUPPORTED"
]
}
],
"callSummary": [
{
"pool": "slingshotrouter",
"machine": "stage21007",
"apiName": "GET",
"status": "0",
"duration": 13400.0,
"link": "https://www.amazon.qa.pilot.com/Tid-942342192424j2j234"
},
{
"pool": "slingshot",
"machine": "stage21029",
"apiName": "GET",
"status": "1",
"duration": 13368.0,
"link": "https://www.amazon.qa.pilot.com/Tid-12342342i842424j2j234"
},
{
"pool": "devstage_userbridgedomainserv",
"machine": "amazon1int-g_userbridgedomainserv_22",
"apiName": "POST",
"status": "1",
"duration": 15.0,
"link": "https://www.amazon.qa.pilot.com/Tid-02341723424i842424j2j290"
}
],
"partial": false
}
}
The above output contains all the responses with respective Endpoint URL which is expected. But I just want to fetch only the object contains "Status: 1". I'm just wondering that How can I manipulate the response.body object to get the below JSON as output.
Expected Output:
{
"callSummary":[
{
"pool": "slingshot",
"machine": "stage21029",
"apiName": "GET",
"status": "1",
"duration": 13368.0,
"link": "https://www.amazon.qa.pilot.com/Tid-12342342i842424j2j234"
},
{
"pool": "devstage_userbridgedomainserv",
"machine": "amazon1int-g_userbridgedomainserv_22",
"apiName": "POST",
"status": "1",
"duration": 15.0,
"link": "https://www.amazon.qa.pilot.com/Tid-02341723424i842424j2j290"
}
]
}
I just want to iterate the response.body obj and check the status as 1 if it's then I need to fetch all the details and form it as above payload. This is dynamic content but the template format is static.
I tried the below code to iterate the response.body but no luck.
var string = JSON.stringify(response.body);
var objectValue = JSON.parse(string);
var obj = objectValue.callSummary;
console.log(obj.length); // It returned undefined.
Please lead me to achieve this.
To return that json, just
res.json(response.body['<Some dynamic Content>'].callSummary);
Adding some validation and error handling would be a good idea before sending the response.
In case your key is just an example and you never know your first key value, and you always want the values of the first key
res.json(Object.values(response.body)[0].callSummary);
Object.values returns an array, so you can iterate the values if you want manage more than the first one

Categories