YYPOST群发软件 发表于 2026-9-15 06:38:20

速识别验证码识别平台 AIWROK 接入示例


速识别验证码识别平台 AIWROK 接入示例










// 速识别验证码识别平台 AIWROK 接入示例
// API文档: https://www.sushibie.com/demo.html

// 全局配置
var G = {
    running: true,
    token: "b5KL6hTyLfzDk84413CZZHE00pBLES2zxbE9G8",
    apiUrl: "https://api.sushibie.com/api/YmServer/customApi",
    userInfoUrl: "https://api.sushibie.com/api/YmServer/getUserInfoApi",
    refundUrl: "https://api.sushibie.com/api/YmServer/refundApi",
    captchaType: "2001" // 验证码类型ID,根据实际需求修改
};

// 导入必要的 Java 类
importClass(java.net.HttpURLConnection);
importClass(java.net.URL);
importClass(java.io.BufferedReader);
importClass(java.io.InputStreamReader);
importClass(java.io.OutputStream);
importClass(java.lang.StringBuilder);
importClass(android.util.Base64);
importClass(java.io.FileInputStream);
importClass(java.io.File);

/**
* 将图片文件转换为 Base64 字符串
* @param {string} imagePath - 图片文件的绝对路径
* @returns {string} Base64 编码的字符串
*/
function imageToBase64(imagePath) {
    try {
      var file = new File(imagePath);
      if (!file.exists()) {
            printl(" 图片文件不存在: " + imagePath);
            return null;
      }
      
      var fis = new FileInputStream(file);
      var bytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, file.length());
      fis.read(bytes);
      fis.close();
      
      var base64 = Base64.encodeToString(bytes, Base64.NO_WRAP);
      printl(" 图片转Base64成功,大小: " + base64.length() + " 字符");
      return base64;
    } catch (e) {
      printl(" 图片转Base64失败: " + e.message);
      return null;
    }
}

/**
* 手动构建 JSON 字符串(Rhino 环境下 JSON.stringify 可能不可用)
* @param {object} obj - 要转换的对象
* @returns {string} JSON 字符串
*/
function toJson(obj) {
    var parts = [];
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
            var val = obj;
            // 统一转成 JS 字符串(兼容 Java String 对象)
            var strVal = "" + val;
            if (typeof val === "string" || val instanceof java.lang.String || typeof val === "object" && val.getClass) {
                // 转义特殊字符
                strVal = strVal.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
                parts.push('"' + key + '":"' + strVal + '"');
            } else {
                parts.push('"' + key + '":' + strVal);
            }
      }
    }
    return "{" + parts.join(",") + "}";
}

/**
* 发送 HTTP POST 请求
* @param {string} url - 请求地址
* @param {object} postData - POST 数据对象
* @returns {object} 响应结果对象
*/
function httpPost(url, postData) {
    try {
      var urlObj = new URL(url);
      var conn = urlObj.openConnection();
      conn.setRequestMethod("POST");
      conn.setDoOutput(true);
      conn.setDoInput(true);
      conn.setUseCaches(false);
      conn.setConnectTimeout(10000);
      conn.setReadTimeout(30000);
      conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
      // 不要显式调用 connect(),让 getOutputStream 自动连接

      // 手动构建 JSON 字符串
      var jsonStr = toJson(postData);
      var logStr = jsonStr;
      if (logStr.length > 200) {
            logStr = logStr.substring(0, 200) + "...";
      }
      printl(" 请求数据: " + logStr);

      // 发送请求数据
      var bodyBytes = new java.lang.String(jsonStr).getBytes("UTF-8");
      conn.setRequestProperty("Content-Length", "" + bodyBytes.length);
      var os = conn.getOutputStream();
      if (os == null) {
            printl(" 无法获取输出流");
            return null;
      }
      os.write(bodyBytes);
      os.flush();
      os.close();

      // 读取响应
      var responseCode = conn.getResponseCode();
      printl(" 响应状态码: " + responseCode);

      var is;
      if (responseCode >= 200 && responseCode < 300) {
            is = conn.getInputStream();
      } else {
            is = conn.getErrorStream();
      }

      if (is == null) {
            printl(" 无法获取输入流");
            conn.disconnect();
            return null;
      }

      var reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
      var sb = new StringBuilder();
      var line;
      while ((line = reader.readLine()) != null) {
            sb.append(line);
      }
      reader.close();
      conn.disconnect();

      var responseText = sb.toString();
      printl(" 响应内容: " + responseText);

      // 手动解析 JSON 响应
      return parseJson(responseText);
    } catch (e) {
      printl(" HTTP请求失败: " + e.message);
      return null;
    }
}

/**
* 简单 JSON 解析(Rhino 环境下可能没有原生 JSON.parse)
* 使用 org.json.JSONObject 解析
*/
function parseJson(jsonStr) {
    try {
      var jsonObj = new org.json.JSONObject(jsonStr);
      return {
            code: jsonObj.optInt("code", -1),
            msg: jsonObj.optString("msg", ""),
            data: parseJsonData(jsonObj)
      };
    } catch (e) {
      printl(" JSON解析失败: " + e.message);
      return null;
    }
}

/**
* 解析 data 字段
*/
function parseJsonData(jsonObj) {
    try {
      if (jsonObj.isNull("data")) return null;
      var dataObj = jsonObj.optJSONObject("data");
      if (dataObj != null) {
            return {
                code: dataObj.optInt("code", -1),
                data: dataObj.optString("data", ""),
                time: dataObj.optString("time", ""),
                score: dataObj.optString("score", ""),
                unique_code: dataObj.optString("unique_code", "")
            };
      }
      return null;
    } catch (e) {
      return null;
    }
}

/**
* 识别验证码
* @param {string} imagePath - 图片文件路径
* @param {string} type - 验证码类型ID
* @returns {object} 识别结果 {success: boolean, data: string, time: string, msg: string}
*/
function recognizeCaptcha(imagePath, type) {
    printl(" 开始识别验证码,类型: " + type);
   
    // 1. 图片转 Base64
    var imageBase64 = imageToBase64(imagePath);
    if (!imageBase64) {
      return { success: false, msg: "图片转Base64失败" };
    }
   
    // 2. 构建请求参数
    var postData = {
      token: G.token,
      type: type,
      image: imageBase64
    };
   
    // 3. 发送请求
    printl(" 正在调用寿司验证码API...");
    var response = httpPost(G.apiUrl, postData);
   
    if (!response) {
      return { success: false, msg: "API请求失败" };
    }
   
    // 4. 解析响应
    var code = response.code;
    var msg = response.msg || "未知错误";
   
    printl(" API响应码: " + code + ", 消息: " + msg);
   
    if (code === 10000) {
      // 识别成功
      var result = response.data.data;
      var time = response.data.time;
      printl(" 识别成功!结果: " + result + ", 耗时: " + time + "秒");
      return { success: true, data: result, time: time, msg: msg };
    } else if (code === 10009) {
      // 结果准备中
      printl(" 结果准备中,请稍后重试");
      return { success: false, msg: "结果准备中" };
    } else {
      // 其他错误
      printl(" 识别失败: " + msg);
      return { success: false, msg: msg };
    }
}

/**
* 获取账户余额
* @returns {object} {success: boolean, score: number, msg: string}
*/
function getBalance() {
    printl(" 查询账户余额...");
   
    var postData = {
      token: G.token,
      type: "score"
    };
   
    var response = httpPost(G.userInfoUrl, postData);
   
    if (!response) {
      return { success: false, msg: "查询失败" };
    }
   
    if (response.code === 10001) {
      var score = response.data.score;
      printl(" 账户余额: " + score + " 积分");
      return { success: true, score: parseFloat(score), msg: "查询成功" };
    } else {
      printl(" 查询失败: " + response.msg);
      return { success: false, msg: response.msg };
    }
}

/**
* 报错返分
* @param {string} uniqueCode - 打码返回的 uniqueCode
* @returns {object} {success: boolean, msg: string}
*/
function reportError(uniqueCode) {
    printl(" 提交报错,uniqueCode: " + uniqueCode);
   
    var postData = {
      token: G.token,
      uniqueCode: uniqueCode
    };
   
    var response = httpPost(G.refundUrl, postData);
   
    if (!response) {
      return { success: false, msg: "报错请求失败" };
    }
   
    if (response.code === 200) {
      printl(" 报错成功,积分已退还");
      return { success: true, msg: "报错成功" };
    } else {
      printl(" 报错失败: " + response.msg);
      return { success: false, msg: response.msg };
    }
}

// ============ 主程序 ============

function main() {
    printl("========================================");
    printl(" 寿司验证码识别 AIWROK 接入示例");
    printl("========================================");

    // 1. 查询余额
    var balanceResult = getBalance();
    if (balanceResult.success) {
      printl(" 当前可用积分: " + balanceResult.score);
    } else {
      printl(" 余额查询失败: " + balanceResult.msg);
    }

    // 2. 截图测试
    printl(" 开始截图测试...");

    try {
      // 全屏截图,获取图片对象
      var img = screen.screenShotFull();
      if (!img) {
            printl(" 截图失败,返回为空");
            return;
      }
      printl(" 截图成功");

      // 直接将图片转 base64 发送给 API
      var imageBase64 = img.toBase64();
      printl(" 图片转Base64成功,大小: " + imageBase64.length() + " 字符");

      // 3. 执行识别
      printl(" 验证码类型: " + G.captchaType);
      printl(" 正在调用寿司验证码API...");

      var postData = {
            token: G.token,
            type: G.captchaType,
            image: imageBase64
      };

      var response = httpPost(G.apiUrl, postData);
      img.recycle();

      if (!response) {
            printl(" API请求失败");
            return;
      }

      var code = response.code;
      var msg = response.msg || "未知错误";
      printl(" API响应码: " + code + ", 消息: " + msg);

      if (code === 10000 && response.data) {
            printl("========================================");
            printl(" 识别成功!");
            printl(" 识别结果: " + response.data.data);
            printl(" 识别耗时: " + response.data.time + " 秒");
            printl("========================================");
      } else {
            printl("========================================");
            printl(" 识别失败");
            printl(" 失败原因: " + msg);
            printl("========================================");
      }
    } catch (e) {
      printl(" 截图异常: " + e.message);
      printl(" 异常堆栈: " + e.stack);
      return;
    }
}

// 启动主程序
try {
    main();
} catch (e) {
    printl(" 程序执行异常: " + e.message);
    printl(" 堆栈: " + e.stack);
}

printl(" 程序执行完毕");


页: [1]
查看完整版本: 速识别验证码识别平台 AIWROK 接入示例