Обработка API в сценарии приложений Google не использует ключ APIHtml

Программисты Html
Ответить
Anonymous
 Обработка API в сценарии приложений Google не использует ключ API

Сообщение Anonymous »

Я новичок, пробую свои силы в обработке данных API в реальном времени для небольшого проекта.
Я пытаюсь создать HTML-страницу (для iframe позже), которая предоставляет мне данные в реальном времени для одной конкретной остановки метро здесь, в Брюсселе. Проблема в том, что что бы я ни пробовал, мой ключ API не используется, а просто проходит через общедоступный API, у которого очень маленькая квота. Я перепробовал все, что мог придумать (и что мог придумать ИИ 😂), но безуспешно.
Вот мой последний файл code.gs (без ключа API), если вы хотите попробовать, вы можете легко создать его на https://api-management-opendata-product ... i.net/apis, мои параметры — этоwhere=pointid: 8271 и 8272.

Код: Выделить всё

const POINT_IDS = ["8271", "8272"];
const BASE_URL = "https://api-management-discovery-production.azure-api.net/api/datasets/stibmivb/rt/WaitingTimes";
const API_KEY = "--------";
const CACHE_KEY = "stib_arrivals";

function doGet(e) {
if (e && e.parameter && e.parameter.data === "1") {
const cache = CacheService.getScriptCache();
const cached = cache.get(CACHE_KEY);
const data = cached || "[]";
return ContentService
.createTextOutput(data)
.setMimeType(ContentService.MimeType.JSON);
} else {
return HtmlService.createTemplateFromFile("Page").evaluate()
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
}

function refreshCache() {
const allArrivals = [];
const cache = CacheService.getScriptCache();

for (const pointId of POINT_IDS) {
const url = `${BASE_URL}?where=pointid%3D%22${pointId}%22&limit=10`;

let response;
try {
response = UrlFetchApp.fetch(url, {
headers: {
"bmc-partner-key": API_KEY  // Custom header name
},
muteHttpExceptions: true
});
} catch (err) {
Logger.log(`Fetch error ${pointId}: ${err.message}`);
continue;
}

if (response.getResponseCode() !== 200) {
Logger.log(`HTTP ${response.getResponseCode()} ${pointId}: ${response.getContentText()}`);
continue;
}

let json;
try {
json = JSON.parse(response.getContentText());
} catch (err) {
Logger.log(`JSON parse error ${pointId}: ${err.message}`);
continue;
}

const records = json.results || [];

for (const record of records) {
let times;
try {
// From curl: \\\"destination\\\" → replace \\\" → "
const cleanTimes = record.passingtimes.replace(/\\\"/g, '"');
times = JSON.parse(cleanTimes);
} catch (err) {
Logger.log(`passingtimes error ${pointId}: ${err.message}`);
continue;
}

for (const pt of times) {
if (!pt?.destination) continue;
allArrivals.push({
line: pt.lineId || "?",
dest: pt.destination.fr || pt.destination.nl || "—",
arrival: pt.expectedArrivalTime,
pointid: pointId
});
}
}
}

Logger.log(`Cached ${allArrivals.length} arrivals`);
cache.put(CACHE_KEY, JSON.stringify(allArrivals), 120);
}
А вот моя страница.html (не думаю, что проблема здесь, но на всякий случай разместил ее здесь)

Код: Выделить всё






* { box-sizing: border-box; }
body {
margin: 0;
padding: 10px;
font-family: sans-serif;
background: #1c1c1c;
color: #e1e1e1;
}
h4 {
margin: 10px 0 6px 0;
font-size: 0.78em;
text-transform: uppercase;
letter-spacing: 0.1em;
opacity: 0.5;
font-weight: normal;
}
h4:first-of-type { margin-top: 0; }
table {
width: 100%;
border-collapse: collapse;
font-size: 0.92em;
margin-bottom: 14px;
}
th {
text-align: left;
padding: 4px 8px;
font-weight: normal;
opacity: 0.45;
font-size: 0.82em;
}
td { padding: 7px 8px; }
tr:not(:last-child) td {
}
.badge {
display: inline-block;
border-radius: 5px;
padding: 2px 8px;
font-weight: bold;
font-size: 0.88em;
min-width: 22px;
text-align: center;
color: #fff;
}
.line-1 { background: #B9378D; }
.line-5 { background: #FFB537; color: #1c1c1c; }
.normal { font-weight: bold; }
.soon   { font-weight: bold; color: #f28b31; }
.asap   { font-weight: bold; color: #e05c5c;  }
.divider {
border: none;
border-top: 1px solid rgba(255,255,255,0.1);
margin: 4px 0 12px 0;
}
#footer {
font-size: 0.68em;
opacity: 0.3;
text-align: right;
margin-top: 4px;
}





LigneDirectionDans






LigneDirectionDans



—


const PROXY_URL = "?data=1";

const DEST_A = ["ERASME", "GARE DE L'OUEST"];
const DEST_B = ["STOCKEL", "HERRMANN-DEBROUX"];

function showUnavailable() {
["tbody-a", "tbody-b"].forEach(id => {
document.getElementById(id).innerHTML =
`🚧 Service indisponible`;
});
}

function renderTable(tbodyId, arrivals) {
const tbody = document.getElementById(tbodyId);
if (arrivals.length === 0) {
tbody.innerHTML = `Aucun passage prévu.`;
return;
}
tbody.innerHTML = arrivals.map(a => {
const mins = Math.floor(a.diffMs / 60000);
const secs = Math.floor((a.diffMs % 60000) / 1000);
let label, cls;
if (mins < 1)      { label = `${secs} sec`; cls = "asap"; }
else if (mins < 3) { label = `${mins} min`; cls = "soon"; }
else               { label = `${mins} min`; cls = "normal"; }

const badgeCls = `badge line-${a.line}`;
return `
${a.line}
${a.dest}
${label}
`;
}).join("");
}

async function refresh() {
const footer = document.getElementById("footer");
try {
const res = await fetch(PROXY_URL);
const arrivals = await res.json();
const now = new Date();

// API is up but returning no data — service outage
if (!Array.isArray(arrivals) || arrivals.length === 0) {
showUnavailable();
footer.textContent = "API hors service – " + now.toLocaleTimeString("fr-BE");
return;
}

const upcoming = arrivals
.map(a => ({ ...a, diffMs: new Date(a.arrival) - now }))
.filter(a => a.diffMs > 0)
.sort((a, b) => a.diffMs - b.diffMs);

const groupA = upcoming.filter(a => DEST_A.includes(a.dest.toUpperCase()));
const groupB = upcoming.filter(a => DEST_B.includes(a.dest.toUpperCase()));

renderTable("tbody-a", groupA);
renderTable("tbody-b", groupB);

footer.textContent = "Mis à jour : " + now.toLocaleTimeString("fr-BE");

} catch (err) {
["tbody-a","tbody-b"].forEach(id => {
document.getElementById(id).innerHTML =
`⚠️ Erreur : ${err.message}`;
});
footer.textContent = "Échec – " + new Date().toLocaleTimeString("fr-BE");
}
}

refresh();
setInterval(refresh, 20000);




Если вы найдете, где я ошибаюсь, я буду очень признателен.
Спасибо!!!

Подробнее здесь: https://stackoverflow.com/questions/798 ... ng-api-key
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Html»