Weibo auto sign and post.

Weibo auto register and post. 微博自动签到和发帖。

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Weibo auto sign and post.
// @namespace    https://liyoung1874.github.io/
// @version      0.0.6
// @author       https://liyoung1874.github.io/
// @description  Weibo auto register and post. 微博自动签到和发帖。
// @license      MIT
// @homepage     https://github.com/liyoung1874/browser-scripts#readme
// @homepageURL  https://github.com/liyoung1874/browser-scripts#readme
// @source       https://github.com/liyoung1874/browser-scripts.git
// @supportURL   https://github.com/liyoung1874/browser-scripts/issues
// @match        https://weibo.com/p*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @require      data:application/javascript,window.Vue%3DVue%3B
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/index.full.min.js
// @resource     element-plus/dist/index.css  https://cdn.jsdelivr.net/npm/[email protected]/dist/index.css
// @grant        GM_addStyle
// @grant        GM_getResourceText
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(" .configBtn[data-v-23d56050]{position:fixed;left:3rem;bottom:5rem;z-index:99999999!important}.content[data-v-23d56050]{display:flex;flex-direction:column;gap:2rem;padding:1rem 0}.flex-row[data-v-23d56050]{display:flex;flex-direction:row;gap:1rem;align-items:center} ");

(function (vue, ElementPlus) {
  'use strict';

  function setDebugNamespace(namespace) {
    if (window.localStorage) {
      localStorage.setItem("debug", `${namespace}*`);
    }
  }
  function sleep(delay = 1) {
    log("tools", `Waiting for ${delay} seconds ...`);
    return new Promise((resolve) => setTimeout(resolve, delay * 1e3));
  }
  function getDelayUntilNextTargetTime(targetHour, targetMinute = 0) {
    log(
      "tools",
      `Target time: ${targetHour > 9 ? targetHour : "0" + targetHour}:${targetMinute > 9 ? targetMinute : "0" + targetMinute}`
    );
    const now = /* @__PURE__ */ new Date();
    let targetTime = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate(),
      targetHour,
      targetMinute,
      0,
      0
    );
    if (now > targetTime) {
      targetTime.setDate(targetTime.getDate() + 1);
    }
    return targetTime - now;
  }
  function ms2str(ms) {
    let seconds = Math.floor(ms / 1e3);
    let minutes = Math.floor(seconds / 60);
    let hours = Math.floor(minutes / 60);
    seconds = seconds % 60;
    minutes = minutes % 60;
    return `${hours} hours, ${minutes} minutes, ${seconds} seconds`;
  }
  const log = (name, ...args) => {
    const message = args.join(" ");
    const time = (/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { hour12: false });
    console.log(`[${time}] ${name}: ${message}`);
  };
  const _export_sfc = (sfc, props) => {
    const target = sfc.__vccOpts || sfc;
    for (const [key, val] of props) {
      target[key] = val;
    }
    return target;
  };
  const _hoisted_1 = {
    class: "content",
    style: { "width": "500px" }
  };
  const _hoisted_2 = { class: "flex-row" };
  const _hoisted_3 = { class: "flex-row" };
  const _hoisted_4 = { style: { "margin-top": "2rem", "text-align": "center" } };
  const __default__ = {
    name: "Weibo"
  };
  const _sfc_main = /* @__PURE__ */ Object.assign(__default__, {
    setup(__props) {
      const namespace = "weibo";
      setDebugNamespace("weibo");
      const logger = (...args) => log(namespace, ...args);
      const dialogVisible = vue.ref(false);
      vue.ref("");
      const stSwitch = vue.ref(false);
      const dailyTimer = vue.ref(null);
      const dailyDelay = vue.ref(null);
      const position = "bottom-right";
      const targetTime = vue.ref("9:00");
      let reloadTry = 3;
      const openDialog = async () => {
        logger("自动配置窗口打开!");
        dialogVisible.value = true;
      };
      const closeDialog = () => {
        dialogVisible.value = false;
        logger("自动配置窗口关闭!");
        if (stSwitch.value) {
          startDailyTask();
        } else {
          logger("清除自动签到任务!");
          clearTimeout(dailyDelay.value);
          clearInterval(dailyTimer.value);
        }
        saveConfig();
      };
      const saveConfig = () => {
        logger("保存配置!");
        localStorage.setItem(
          "weibo:config",
          JSON.stringify({
            stSwitch: stSwitch.value,
            reloadTry,
            targetTime: targetTime.value
          })
        );
      };
      const loadConfig = () => {
        logger("加载配置!");
        const config = JSON.parse(localStorage.getItem("weibo:config"));
        const { stSwitch: Switch, reloadTry: Try, targetTime: time } = config;
        stSwitch.value = Switch || false;
        reloadTry = Try || 3;
        targetTime.value = time || "9:00";
        logger("加载配置成功!");
        logger("自动签到配置", stSwitch.value);
        logger("签到时间", targetTime.value);
      };
      const autoRegister = async () => {
        await sleep(3);
        if (!isSuperIndex()) {
          logger("当前不在超话页面!");
          return;
        }
        if (!stSwitch.value) {
          logger("自动签到未开启!");
          return;
        }
        const btn = document.querySelector(
          '[action-data*="api=http://i.huati.weibo.com/aj/super/checkin"]'
        );
        if (!btn && reloadTry > 0) {
          logger("未找到签到或已签到按钮!");
          reloadTry -= 1;
          saveConfig();
          window.location.reload();
        } else if (!btn && reloadTry === 0) {
          logger("未找到签到或已签到按钮!");
          ElementPlus.ElNotification({
            title: "超话签到通知",
            message: `超话签到失败!未找到签到或已签到按钮!异常时间${(/* @__PURE__ */ new Date()).toLocaleString()}`,
            type: "error",
            duration: 0,
            position
          });
          return;
        }
        const flag = btn.innerHTML.includes("已签到");
        if (flag) {
          logger("当前超话已签到!");
          return;
        }
        await sleep();
        btn.click();
        const res = await handleError();
        if (res === "error" || res === "not sure") {
          return;
        }
        if (res === "warning") {
          await sleep();
          btn.click();
          return;
        }
        logger("签到成功!");
        reloadTry = 3;
        saveConfig();
        ElementPlus.ElNotification({
          title: "超话签到通知",
          message: `超话签到成功!签到时间${(/* @__PURE__ */ new Date()).toLocaleString()}`,
          type: "success",
          duration: 0,
          position
        });
      };
      const isSuperIndex = () => {
        return window.location.href.includes("https://weibo.com/p/") && window.location.href.includes("super_index");
      };
      const handleError = async () => {
        await sleep(3);
        const errConfirm = document.querySelector("a[action-type='ok']");
        if (errConfirm) {
          if (errConfirm.innerHTML.includes("解除异常")) {
            logger("出现解除异常提示!请手动解除异常!");
            ElementPlus.ElNotification({
              title: "超话签到通知",
              message: `超话签到异常!出现解除异常提示!请手动解除异常!解除异常后刷新页面重试。异常时间${(/* @__PURE__ */ new Date()).toLocaleString()}`,
              type: "error",
              duration: 0,
              position
            });
            return "error";
          } else if (errConfirm.innerHTML.includes("确定")) {
            logger("弹出异常提示!");
            errConfirm.click();
            logger("点击异常提示,关闭异常提示!");
            return "warning";
          } else {
            logger("未知异常!");
            ElementPlus.ElNotification({
              title: "超话签到通知",
              message: `超话签到异常!未知异常!异常时间${(/* @__PURE__ */ new Date()).toLocaleString()}`,
              type: "error",
              duration: 0,
              position
            });
            return "not sure";
          }
        }
        return true;
      };
      const startDailyTask = async () => {
        logger("开启自动签到任务!");
        clearTimeout(dailyDelay.value);
        clearInterval(dailyTimer.value);
        await autoRegister();
        const [hour, minute] = targetTime.value.split(":");
        const delay = getDelayUntilNextTargetTime(+hour, +minute);
        logger("距离下一次签到还有:", ms2str(delay));
        dailyDelay.value = setTimeout(() => {
          window.location.reload();
          dailyTimer.value = setInterval(() => {
            window.location.reload();
          }, 1e3 * 60 * 60 * 24);
        }, delay);
      };
      vue.onMounted(async () => {
        await sleep(3);
        loadConfig();
        if (stSwitch.value) {
          startDailyTask();
        }
      });
      return (_ctx, _cache) => {
        const _component_el_text = vue.resolveComponent("el-text");
        const _component_el_switch = vue.resolveComponent("el-switch");
        const _component_el_time_select = vue.resolveComponent("el-time-select");
        return vue.openBlock(), vue.createElementBlock("div", null, [
          vue.createVNode(vue.unref(ElementPlus.ElDialog), {
            title: "自动配置",
            center: "",
            modelValue: dialogVisible.value,
            "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => dialogVisible.value = $event),
            "close-on-click-modal": false,
            "close-on-press-escape": false,
            "show-close": false,
            "destroy-on-close": "",
            width: "65%"
          }, {
            default: vue.withCtx(() => [
              vue.createElementVNode("div", null, [
                vue.createElementVNode("div", _hoisted_1, [
                  vue.createElementVNode("div", _hoisted_2, [
                    vue.createVNode(_component_el_text, {
                      class: "mx-1",
                      size: "large"
                    }, {
                      default: vue.withCtx(() => [
                        vue.createTextVNode("超话签到")
                      ]),
                      _: 1
                    }),
                    vue.createVNode(_component_el_switch, {
                      modelValue: stSwitch.value,
                      "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => stSwitch.value = $event),
                      "active-text": "开",
                      "inactive-text": "关"
                    }, null, 8, ["modelValue"])
                  ]),
                  vue.createElementVNode("div", _hoisted_3, [
                    vue.createVNode(_component_el_text, {
                      class: "mx-1",
                      size: "large"
                    }, {
                      default: vue.withCtx(() => [
                        vue.createTextVNode("签到时间")
                      ]),
                      _: 1
                    }),
                    vue.createVNode(_component_el_time_select, {
                      modelValue: targetTime.value,
                      "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => targetTime.value = $event),
                      style: { "width": "240px" },
                      start: "06:30",
                      step: "00:30",
                      end: "23:30",
                      placeholder: "Select time"
                    }, null, 8, ["modelValue"])
                  ])
                ])
              ]),
              vue.createElementVNode("div", _hoisted_4, [
                vue.createVNode(vue.unref(ElementPlus.ElButton), {
                  size: "large",
                  type: "primary",
                  onClick: closeDialog
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode("确定")
                  ]),
                  _: 1
                }),
                vue.createVNode(vue.unref(ElementPlus.ElButton), {
                  size: "large",
                  onClick: _cache[2] || (_cache[2] = ($event) => dialogVisible.value = false)
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode("取消")
                  ]),
                  _: 1
                })
              ])
            ]),
            _: 1
          }, 8, ["modelValue"]),
          vue.createVNode(vue.unref(ElementPlus.ElButton), {
            type: "primary",
            class: "configBtn",
            onClick: openDialog
          }, {
            default: vue.withCtx(() => [
              vue.createTextVNode("自动配置")
            ]),
            _: 1
          })
        ]);
      };
    }
  });
  const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-23d56050"]]);
  const cssLoader = (e) => {
    const t = GM_getResourceText(e);
    return GM_addStyle(t), t;
  };
  cssLoader("element-plus/dist/index.css");
  const app = vue.createApp(App);
  const appContainer = () => {
    const app2 = document.createElement("div");
    document.body.appendChild(app2);
    return app2;
  };
  app.use(ElementPlus).mount(appContainer());

})(Vue, ElementPlus);