| 1 |
import { useLaunchDataStore } from '@auto-launch/state/launch-data'; |
| 2 |
import { INSIGHTS_HOST } from '@constants'; |
| 3 |
import { reqDataBasics } from '@shared/lib/data'; |
| 4 |
import apiFetch from '@wordpress/api-fetch'; |
| 5 |
|
| 6 |
const headers = { |
| 7 |
'Content-type': 'application/json', |
| 8 |
Accept: 'application/json', |
| 9 |
'X-Extendify': 'true', |
| 10 |
}; |
| 11 |
|
| 12 |
const { urlParams, activeTests } = window.extLaunchData; |
| 13 |
export const checkIn = ({ |
| 14 |
stage, |
| 15 |
description, |
| 16 |
siteProfile = {}, |
| 17 |
sitePlugins = [], |
| 18 |
siteStyle = {}, |
| 19 |
} = {}) => { |
| 20 |
const { type, category, structure, objective } = siteProfile; |
| 21 |
const { siteId, partnerId, homeUrl, wpLanguage } = reqDataBasics; |
| 22 |
const attempt = useLaunchDataStore.getState()?.attempt || 1; |
| 23 |
|
| 24 |
const payload = JSON.stringify({ |
| 25 |
...reqDataBasics, |
| 26 |
autoLaunch: true, |
| 27 |
stage, |
| 28 |
description, |
| 29 |
attempt, |
| 30 |
activeTests: Object.keys(activeTests ?? {}).length |
| 31 |
? JSON.stringify(activeTests) |
| 32 |
: undefined, |
| 33 |
skippedDescription: Boolean(urlParams?.title || urlParams?.description), |
| 34 |
insightsId: siteId, |
| 35 |
hostpartner: partnerId, |
| 36 |
siteURL: homeUrl, |
| 37 |
language: wpLanguage, |
| 38 |
sitePlugins: sitePlugins?.map((p) => p?.name), |
| 39 |
urlParameters: urlParams, |
| 40 |
siteStyle, |
| 41 |
style: siteStyle?.colorPalette, |
| 42 |
siteProfile, |
| 43 |
siteType: type, |
| 44 |
siteCategory: category, |
| 45 |
siteStructure: structure, |
| 46 |
siteObjective: objective, |
| 47 |
extra: { |
| 48 |
userAgent: window?.navigator?.userAgent, |
| 49 |
vendor: window?.navigator?.vendor || 'unknown', |
| 50 |
platform: |
| 51 |
window?.navigator?.userAgentData?.platform || |
| 52 |
window?.navigator?.platform || |
| 53 |
'unknown', |
| 54 |
mobile: window?.navigator?.userAgentData?.mobile, |
| 55 |
width: window.innerWidth, |
| 56 |
height: window.innerHeight, |
| 57 |
screenHeight: window.screen.height, |
| 58 |
screenWidth: window.screen.width, |
| 59 |
orientation: window.screen.orientation?.type, |
| 60 |
touchSupport: 'ontouchstart' in window || navigator.maxTouchPoints > 0, |
| 61 |
}, |
| 62 |
}); |
| 63 |
|
| 64 |
return fetch(`${INSIGHTS_HOST}/api/v1/launch`, { |
| 65 |
method: 'POST', |
| 66 |
headers, |
| 67 |
body: payload, |
| 68 |
keepalive: true, |
| 69 |
}); |
| 70 |
}; |
| 71 |
|
| 72 |
const probeFailureReason = async () => { |
| 73 |
try { |
| 74 |
// parse:false so we get the raw Response and can read the HTTP status — the |
| 75 |
// default JSON parse throws `invalid_json` on a blocked API's HTML error page. |
| 76 |
await apiFetch({ path: '/extendify/v1/shared/ping', parse: false }); |
| 77 |
return null; |
| 78 |
} catch (error) { |
| 79 |
if (error?.status === 403) return '403'; |
| 80 |
if (error?.status === 404) return '404'; |
| 81 |
// Any other status means the request reached the REST API and errored |
| 82 |
// upstream (our ping only ever 200s) — reachable, so not "unreachable". |
| 83 |
if (error?.status) return null; |
| 84 |
return 'network'; |
| 85 |
} |
| 86 |
}; |
| 87 |
|
| 88 |
export const reportRestApiStatus = async () => { |
| 89 |
const reason = await probeFailureReason(); |
| 90 |
if (!reason) return; |
| 91 |
const { siteId, partnerId, homeUrl, siteCreatedAt } = reqDataBasics; |
| 92 |
return fetch(`${INSIGHTS_HOST}/api/v1/event`, { |
| 93 |
method: 'POST', |
| 94 |
headers, |
| 95 |
body: JSON.stringify({ |
| 96 |
insightsId: siteId, |
| 97 |
key: 'rest_api_unreachable', |
| 98 |
payload: { reason }, |
| 99 |
partnerId, |
| 100 |
siteURL: homeUrl, |
| 101 |
siteCreatedAt, |
| 102 |
}), |
| 103 |
keepalive: true, |
| 104 |
}); |
| 105 |
}; |
| 106 |
|