您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Обёртка gapi с интерфейсом для HWM
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/465885/1188144/hwm_google_api_wrapper.js
- // ==UserScript==
- // @name hwm_google_api_wrapper
- // @namespace https://github.com/bonArt0/hwm_scripts
- // @version 0.1.1
- // @description Обёртка gapi с интерфейсом для HWM
- // @author bonArt
- // @license GPL-3.0-only
- // @icon https://cdn-icons-png.flaticon.com/512/2991/2991148.png
- // @match https://*.heroeswm.ru/*
- // @match https://178.248.235.15/*
- // @match https://www.lordswm.com/*
- // @match https://my.lordswm.com/*
- // @run-at document-body
- // @supportURL https://www.heroeswm.ru/sms-create.php?mailto_id=117282
- // ==/UserScript==
- /**
- * @type {GapiWrapper} _GapiWrapperInstance
- * @private
- */
- let _GapiWrapperInstance;
- class GAWCredentialsNotSetError extends Error {
- constructor() {
- super();
- this.message = 'GoogleAPI credentials not set';
- }
- }
- class GAWAlreadyInitializedError extends Error {
- constructor() {
- super();
- this.message = 'GoogleAPI Wrapper already initialized';
- }
- }
- /**
- * @see https://developers.google.com/sheets/api/quickstart/js?hl=ru
- */
- class GapiWrapper
- {
- /** Discovery doc URL for APIs used by the quickstart */
- static DISCOVERY_DOC = 'https://sheets.googleapis.com/$discovery/rest?version=v4';
- /** Authorization scopes required by the API; multiple scopes can be included, separated by spaces. */
- static SCOPE = 'https://www.googleapis.com/auth/spreadsheets';
- /**
- * @type {boolean}
- * @private
- */
- _initialized = false;
- /** @var {object} tokenClient */
- tokenClient;
- /** @var {object} gapiClient */
- gapiClient;
- /**
- * @return {GapiWrapper}
- */
- static init() {
- if (!_GapiWrapperInstance || !_GapiWrapperInstance?._initialized) {
- console.info('GoogleAPI Wrapper initialization started');
- const gapiApiKey = window.localStorage.getItem(GapiControls.GAPI_API_KEY_CONFIG_NAME);
- const gapiClientId = window.localStorage.getItem(GapiControls.GAPI_CLIENT_ID_CONFIG_NAME);
- if (!gapiApiKey || !gapiClientId) {
- throw new GAWCredentialsNotSetError();
- }
- GapiControls.init();
- try {
- _GapiWrapperInstance = new GapiWrapper(gapiApiKey, gapiClientId);
- } catch (e) {
- if (e instanceof GAWAlreadyInitializedError) {
- console.info(e.message);
- return _GapiWrapperInstance;
- }
- console.error('Something happen while GoogleAPI Wrapper initializing', e.context);
- throw e;
- }
- console.info('GoogleAPI Wrapper initialized');
- }
- return _GapiWrapperInstance;
- }
- constructor(apiKey, clientId, scope) {
- this._loadScript(
- 'https://apis.google.com/js/api.js',
- () => this._gapiLoaded(apiKey),
- );
- this._loadScript(
- 'https://accounts.google.com/gsi/client',
- () => this.tokenClient = this._gisLoaded(clientId, scope),
- );
- }
- _loadScript(src, onLoad) {
- let script = document.createElement('script');
- script.src = src;
- script.defer = true;
- script.async = true;
- script.addEventListener('load', onLoad);
- document.head.appendChild(script);
- }
- /**
- * @private
- *
- * @param {string} apiKey
- * @param {string[]} discoveryDocs
- *
- * Callback after api.js is loaded.
- */
- _gapiLoaded(apiKey, discoveryDocs = [GapiWrapper.DISCOVERY_DOC]) {
- gapi.load('client', () => {
- const result = gapi.client.init({
- apiKey: apiKey,
- discoveryDocs: discoveryDocs,
- });
- if (!result || true) { // TODO: resolve 'Pe' value and check for apiKey error
- this.gapiClient = gapi.client;
- return;
- }
- throw new Error(result.Pe.error.message);
- });
- }
- /**
- @private
- @param {string} clientId
- @param {string} scope
- @return {object}
- * Callback after Google Identity Services are loaded.
- */
- _gisLoaded(clientId, scope = GapiWrapper.SCOPE) {
- return google.accounts.oauth2.initTokenClient({
- client_id: clientId,
- scope: scope,
- callback: (resp) => console.debug(resp), // TODO: defined later
- });
- }
- }
- class GapiControls
- {
- static GAPI_API_KEY_CONFIG_NAME = 'gapi_api_key';
- static GAPI_CLIENT_ID_CONFIG_NAME = 'gapi_client_id';
- static MODAL_CLASSNAME = 'gapi_controls_modal';
- static MODAL_OPEN_BUTTON_ICON = 'https://cdn-icons-png.flaticon.com/512/2991/2991148.png';
- static MODAL_OPEN_BUTTON_CLASSNAME = 'gapi_controls_button';
- /**
- * @type {boolean}
- * @private
- */
- static _initialized = false;
- static init() {
- if (!GapiControls._initialized) {
- const controlsModal = GapiControls.buildControlsModal();
- const openModalButton = GapiControls.buildControlsModalSwitch(controlsModal);
- document.body.append(controlsModal);
- document.body.append(openModalButton);
- }
- }
- /**
- * @return {HTMLDivElement}
- */
- static buildControlsModal() {
- const modal = document.createElement('div');
- const clientIdBox = GapiControls.buildTextboxLabel(
- 'clientId',
- window.localStorage.getItem(GapiControls.GAPI_CLIENT_ID_CONFIG_NAME),
- 'Client ID',
- );
- const apiKeyBox = GapiControls.buildTextboxLabel(
- 'apiKey',
- window.localStorage.getItem(GapiControls.GAPI_API_KEY_CONFIG_NAME),
- 'API Key',
- );
- const closeButton = GapiControls.buildCloseButton(
- function () {
- window.localStorage.setItem(GapiControls.GAPI_CLIENT_ID_CONFIG_NAME, clientIdBox.lastChild.value);
- window.localStorage.setItem(GapiControls.GAPI_API_KEY_CONFIG_NAME, apiKeyBox.lastChild.value);
- // TODO: display to classname
- modal.style.display = 'none';
- }
- );
- modal.className = `${GapiControls.MODAL_CLASSNAME} wbwhite`;
- // TODO: style to css
- // TODO: display to classname
- modal.style.display = 'none';
- modal.style.position = 'absolute';
- modal.style.top = '114px';
- modal.style.right = '50px';
- modal.style.width = '200px';
- modal.style.height = '105px';
- modal.style.zIndex = '9';
- modal.append(clientIdBox);
- modal.append(apiKeyBox);
- modal.append(closeButton);
- return modal;
- }
- /**
- * @param {string} name
- * @param {string} value
- * @param {string} innerHTML
- * @returns {HTMLLabelElement}
- */
- static buildTextboxLabel(name, value, innerHTML) {
- const textbox = document.createElement('input');
- textbox.type = 'password';
- textbox.autocomplete = 'off';
- textbox.value = value;
- textbox.name = name;
- textbox.style.display = 'block';
- const label = document.createElement('label');
- label.style.display = 'block';
- label.style.margin = '10px';
- label.append(innerHTML);
- label.append(textbox);
- return label;
- }
- /**
- * @param {function} onClick
- * @return {HTMLButtonElement}
- */
- static buildCloseButton(onClick) {
- const button = document.createElement('button');
- button.textContent = '☓';
- button.style.position = 'absolute';
- button.style.top = '5px';
- button.style.right = '5px';
- button.addEventListener('click', onClick);
- return button;
- }
- /**
- * @param {HTMLDivElement} controlsModal
- * @return {HTMLImageElement}
- */
- static buildControlsModalSwitch(controlsModal) {
- const openModalButton = document.createElement('img');
- openModalButton.className = GapiControls.MODAL_OPEN_BUTTON_CLASSNAME;
- openModalButton.src = GapiControls.MODAL_OPEN_BUTTON_ICON;
- // TODO: style to css
- // TODO: display to classname
- openModalButton.style.display = 'block';
- openModalButton.style.position = 'absolute';
- openModalButton.style.top = '114px';
- openModalButton.style.right = '125px';
- openModalButton.style.width = '25px';
- openModalButton.style.height = '25px';
- openModalButton.style.cursor = 'pointer';
- // TODO: display to classname
- openModalButton.addEventListener('click', () => controlsModal.style.display = 'inline-block');
- return openModalButton;
- }
- }
- GapiWrapper.init();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址