您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automates environment selection, discards changes, and approves for specific environments.
// ==UserScript== // @name IDP - Auto Approve Stack // @namespace http://tampermonkey.net/ // @version 2025-04-02 // @description Automates environment selection, discards changes, and approves for specific environments. // @match https://*.cloudfront.net/* // @grant GM_log // @run-at document-idle // @license MIT // ==/UserScript== (function () { 'use strict'; GM_log("Auto-Environment-Clicker script running..."); const params = new URLSearchParams(window.location.search); const environment = params.get('environment'); if (!environment) { console.warn("No 'environment' parameter found in the URL."); return; } GM_log(`Environment parameter found: ${environment}`); function notify(message) { const stackName = document.querySelector("body > app-root > div > stack-home > div > div:nth-child(1) > h1") .innerText.replace(" STACK", "").toLowerCase(); // Get the current time in a human-readable format const currentTime = new Date().toLocaleString('en-US', { weekday: 'short', // Short day name year: 'numeric', month: 'short', // Short month name day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true // AM/PM format }); // Format the message const m = `${currentTime}: ${message}`; // Send the message to the ntfy topic fetch('https://ntfy.sh/' + stackName, { method: 'POST', body: m }) .then(response => { if (response.ok) { GM_log(`Notification sent successfully: ${message}`); } else { console.error('Failed to send notification.', response.statusText); } }) .catch(error => { console.error('Error while sending notification:', error); }); } function findAndClickEnvironmentSpan() { GM_log("running findAndClickEnvironmentSpan"); const span = [...document.querySelectorAll('span.title')].find(el => el.textContent.trim().toLowerCase() === environment); const current_environment = document.querySelector("body > app-root > div > stack-home > div > div.card-container > div.environments > div").children[0].children[0].children[0].children[1].children[0].children[0].innerText.trim().toLowerCase() GM_log(current_environment, environment) if (current_environment == environment) { GM_log(`Skipping clicking on span as environment is already on ${environment}`) clearInterval(environmentCheckInterval); waitForApproveButton(); } else if (span) { GM_log(`Found environment span: ${span.textContent}. Clicking it...`); span.click(); clearInterval(environmentCheckInterval); // waitForDiscardDiaGM_log(); waitForApproveButton(); } else { GM_log(`Looking for span with environment name: ${environment}`); } } /*function waitForDiscardDiaGM_log() { GM_log("running waitForDiscardDialog") const discardCheckInterval = setInterval(() => { const yesButton = [...document.querySelectorAll('button')].find(btn => btn.textContent.trim() === 'Yes'); if (yesButton) { GM_log("Found 'Yes' button in discard changes dialog. Clicking it..."); yesButton.click(); clearInterval(discardCheckInterval); waitForApproveButton(); } else { GM_log("Looking for 'Yes' button in discard changes dialog..."); } }, 1000); }*/ function waitForApproveButton() { GM_log("running waitForApproveButton"); const approveInterval = setInterval(() => { const approveButton = Array.from(document.querySelectorAll("button")) .find(button => button.textContent.trim().toUpperCase() === "APPROVE"); if (approveButton) { GM_log("Found 'Approve' button. Clicking and stopping script..."); approveButton.click(); clearInterval(approveInterval); waitForOKButton(); notify("APPROVED") } else { GM_log("Approve button not found yet ... waiting 1 sec"); } }, 1000); } function waitForOKButton() { GM_log("running waitForOKButton"); const okButtonInterval = setInterval(() => { const okButton = Array.from(document.querySelectorAll(".mat-focus-indicator.mat-stroked-button.mat-button-base.ng-star-inserted")) .find(button => button.innerText.trim() === "OK"); if (okButton) { GM_log("Found 'OK' button. Clicking it..."); okButton.click(); clearInterval(okButtonInterval); waitForStackStatus(); } else { GM_log("Looking for 'OK' button..."); } }, 1000); } function waitForStackStatus() { GM_log("running waitForStackStatus"); const stackStatusInterval = setInterval(() => { const stackStatusElement = document.querySelector(".mat-card-content.ng-star-inserted")?.children[0]; const statusText = stackStatusElement ? stackStatusElement.innerText.trim() : ""; if (statusText === "Stack Status: READY" || statusText === "Stack Status: FAILED") { GM_log(`Stack Status updated: ${statusText}. Stopping script.`); notify(statusText) clearInterval(stackStatusInterval); window.close(); } else { GM_log(`Current Stack Status: ${statusText}. Waiting for it to change to READY or FAILED...`); } }, 1000); } const environmentCheckInterval = setInterval(findAndClickEnvironmentSpan, 1000); })();