QEdge 简介及脚本开发文档

基于 Xposed 的 QQ 扩展模块 · 脚本开发指南

简介

QEdge 是一个基于 Xposed 框架的 QQ 扩展模块,允许开发者通过编写脚本扩展 QQ 的功能。JS 脚本引擎基于 Rhino(纯 Java 实现,无原生依赖),支持 ES6 语法。

脚本目录位于 QQ 数据目录下的 QEdge/plugin 文件夹中。

开发环境说明

脚本运行于 Rhino JS 引擎环境,支持 ES6 特性。编写时请遵循以下规范:

  • 属性访问:直接用点号 . 访问对象属性(如 msgData.msg),无需调用 Getter 方法。

  • 方法调用:所有 API 方法均为全局函数,直接裸调用,无需任何前缀(如 qe.)。

  • 全局作用域:所有 API 方法在脚本任意位置均可直接调用。

  • 日志输出:请使用 console.log(...) 输出日志(log 名称保留给用户变量使用);console.error(...) 用于错误日志。

  • 语法支持:支持 ES6 语法,包括箭头函数、模板字符串、let/const 等。

  • 线程模型:事件回调默认在 IO 线程执行。操作 UI 需切换至主线程。

脚本必须文件

文件名称 说明 是否必需
main.js 脚本执行入口
desc.txt 脚本描述文件
info.prop 配置文件

info.prop 配置项

配置项 说明 示例
type 脚本类型(js 表示 JS 脚本) js
id 脚本唯一标识符 example_123456
pluginName 脚本名称 示例脚本
author 作者 Developer
versionCode 版本号 1.0

全局变量

变量名 类型 描述
context android.content.Context 宿主 App 全局上下文
pluginId String 当前加载脚本 ID
pluginPath String 当前加载脚本的文件夹绝对路径
myUin String 当前登录的 QQ 号
classLoader ClassLoader QQ 宿主类加载器

核心数据结构

MsgData (消息对象)

用于 onMsg 回调中。

字段 类型 描述
type int 聊天类型 (1:好友/私聊, 2:群聊, 100:陌生人)
msgType int 消息类型
peerUin String 群号或好友QQ号
peerUid String 群号或好友UID
userUin String 发送者QQ号
userUid String 发送者UID
time long 发送时间戳 (秒)
msgId long 消息ID
msg String 文本消息内容
path String 文件/视频/语音保存路径
atList List\ 消息中艾特的QQ号列表
atMap Map\<String, String> 艾特映射表

FriendInfo (好友信息)

字段 类型 描述
uin String QQ号
uid String UID
name String 昵称
remark String 备注

GroupInfo (群信息)

字段 类型 描述
group String 群号
groupName String 群名称
groupOwner String 群主QQ号

MemberInfo (群成员信息)

字段 类型 描述
uin String 成员QQ号
uinName String 群名片/昵称
role String 角色 (OWNER/ADMIN/MEMBER)

ForbidInfo (禁言信息)

字段 类型 描述
user String 被禁言成员QQ号
userName String 被禁言成员昵称
time long 剩余禁言时长 (秒)

BlackUser (群黑名单信息)

字段 类型 描述
uin String QQ号
name String 昵称
time long 拉黑时间
op_uin String 操作者

JointGroup (共同群信息)

字段 类型 描述
qun String 群号
joinTime long 进群时间

消息相关方法

sendMsg - 发送消息

void sendMsg(String peerUin, String msg, int chatType)

发送文本消息。

参数 类型 说明
peerUin String 好友QQ号或群号
msg String 消息内容
chatType int 聊天类型 (1好友/2群聊/100陌生人)

支持格式: 艾特:[atUin=QQ号](QQ号为0时表示艾特全体) 图片:[pic=图片链接或绝对路径]

sendPic - 发送图片

void sendPic(String peerUin, String path, int chatType)

sendPtt - 发送语音

void sendPtt(String peerUin, String path, int chatType)

sendCard - 发送卡片

void sendCard(String peerUin, String data, int chatType)

sendFile - 发送文件

void sendFile(String peerUin, String path, int chatType)

sendVideo - 发送视频

void sendVideo(String peerUin, String path, int chatType)

sendBubbleVideo - 发送泡泡消息视频

void sendBubbleVideo(String peerUin, String path, int chatType)

sendPai - 拍一拍

void sendPai(String toUin, String peerUin, int chatType)
void sendPai(String toUin, String peerUin)

recallMsg - 撤回消息

void recallMsg(int chatType, String peerUin, long msgId)

sendMusic - 发送音乐卡片

void sendMusic(String platform, String peerUin, String title, String desc, String jumpUrl, String musicUrl, String imgUrl, int chatType)
参数 类型 说明
platform String qq,wy,mg,kw(已废弃,自测),kg,mg,bd

快捷消息方法

方法 返回值 参数 说明
sendPrivateMsg void String uin, String msg 发送私聊文本消息
sendGroupMsg void String qun, String msg 发送群文本消息
sendPrivatePic void String uin, String path 发送私聊图片
sendGroupPic void String qun, String path 发送群图片
sendPrivatePtt void String uin, String path 发送私聊语音
sendGroupPtt void String qun, String path 发送群语音
sendPrivateCard void String uin, String data 发送私聊卡片
sendGroupCard void String qun, String data 发送群卡片
sendPrivateVideo void String uin, String path 发送私聊视频
sendGroupVideo void String qun, String path 发送群视频
sendPrivateFile void String uin, String path 发送私聊文件
sendGroupFile void String qun, String path 发送群文件
recallPrivateMsg void String uin, long msgId 撤回私聊消息
recallGroupMsg void String qun, long msgId 撤回群消息
addLocalGrayTipMsg void String peerUin, String jsonStr, long busiId, int chatType 添加本地灰条提示消息
sendReplyMsg void String peerUin, long replyMsgId, String msg, int chatType 发送引用回复消息
sendPrivateReplyMsg void String uin, long replyMsgId, String msg 发送私聊引用回复
sendGroupReplyMsg void String qun, long replyMsgId, String msg 发送群引用回复

平台音乐卡片

方法 返回值 参数 说明
qqsendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送QQ音乐群卡片
qqsendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送QQ音乐好友卡片
wysendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送网易云音乐群卡片
wysendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送网易云音乐好友卡片
kgsendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送酷狗音乐群卡片
kgsendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送酷狗音乐好友卡片
kwsendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送酷我音乐群卡片
kwsendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送酷我音乐好友卡片
bdsendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送百度音乐群卡片
bdsendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送百度音乐好友卡片
mgsendTroopMusic void String qun, String title, String desc, String detailUrl, String audio, String img 发送咪咕音乐群卡片
mgsendFriendMusic void String uin, String title, String desc, String detailUrl, String audio, String img 发送咪咕音乐好友卡片

好友相关方法

getAllFriend - 获取好友列表

List<FriendInfo> getAllFriend()

getJointGroupList - 获取好友共同群列表

List<JointGroup> getJointGroupList()

isFriend - 判断好友

boolean isFriend(String uin)

sendZan - 点赞

void sendZan(String uin, int num)

getCurrentUin - 获取当前QQ号

String getCurrentUin()

getCurrentUid - 获取当前UID

String getCurrentUid()

getCurrentName - 获取当前昵称

String getCurrentName()

群管理方法

getGroupList - 获取群列表

List<GroupInfo> getGroupList()

getGroupInfo - 获取群信息

Object getGroupInfo(String group)

获取指定群的详细信息对象。

getGroupMemberList - 获取群成员列表

List<MemberInfo> getGroupMemberList(String group)

getForbidInfo - 获取禁言列表

List<ForbidInfo> getForbidInfo(String group)

getGroupBlackList - 获取群拉黑名单列表

List<BlackUser> getGroupBlackList(String group)

shutUp - 禁言成员

void shutUp(String group, String uin, long time)

传 0 为解禁。

shutUpAll - 全员禁言

void shutUpAll(String group, boolean enable)

setMemberTitle - 设置群头衔

void setMemberTitle(String group, String uin, String title)

kickGroup - 踢出群成员

void kickGroup(String group, String uin, boolean block)

setGroupAdmin - 设置管理员

void setGroupAdmin(String group, String uin, boolean enable)

clockIn - 群打卡

void clockIn(String group)

changeGroupName - 更换群名

void changeGroupName(String group, String name)

getAbnormalUserList - 获取群内异常用户列表

List<String> getAbnormalUserList(String group)

setGroupLocation - 设置群地点

void setGroupLocation(String group, String location)

setGroupShortcutBar - 设置群快捷栏

void setGroupShortcutBar(String group, String desc, String link, String name, String cover)

Cookie与Token

方法 返回值 说明
getSkey() String 获取skey
getRealSkey() String 获取RealSkey(鬼知道是什么玩意)
getPskey(String url) String 获取指定域名的pskey
getPt4Token(String url) String 获取Pt4Token
getStweb() String 获取stweb
getGTK(String url) String 根据URL获取GTK
getGtk(String skey) String 根据skey计算GTK
getBkn(String key) long 计算Bkn
getGroupRKey() String 群聊图片RKey
getFriendRKey() String 私聊图片RKey

数据存储

数据保存在 plugin/脚本ID/config/ 下的 JSON 文件中。

写入数据

方法 说明
putString(configName, key, value) 写入字符串
putInt(configName, key, value) 写入整数
putLong(configName, key, value) 写入长整数
putBoolean(configName, key, value) 写入布尔值
putDouble(configName, key, value) 写入浮点数

读取数据

方法 说明
getString(configName, key, defaultValue) 读取字符串
getInt(configName, key, defaultValue) 读取整数
getLong(configName, key, defaultValue) 读取长整数
getBoolean(configName, key, defaultValue) 读取布尔值
getDouble(configName, key, defaultValue) 读取浮点数

其他操作

方法 说明
remove(configName, key) 删除键
contains(configName, key) 判断键是否存在
clear(configName) 清空配置文件
getConfigMap(configName) 获取配置文件的所有键值
getConfigPath(configName) 获取配置文件完整路径

回调方法

在脚本中实现以下方法以接收事件。

onMsg - 接收消息

void onMsg(Object msgData)

接收消息时触发,参数为 MsgData 对象。

群变动事件

方法 说明
joinGroup(joinData) 成员入群,参数为 JoinData 对象(字段: troopUin群号, memberUin成员UIN, memberUid原始UID, joinType入群类型131邀请/130主动, desc类型中文描述)
quitGroup(quitData) 成员退群,参数为 QuitData 对象(字段: troopUin群号, memberUin成员UIN, updateHeadAndName是否触发退场红字提示)
shutUpGroup(group, memberUin, time, operatorUin) 群禁言事件

交互事件

方法 说明
void chatInterface(int chatType, String peerUin, String name) 进入聊天界面
String getMsg(String text) 自己发送文本消息时拦截,用于修改发送文本
void onPaiYiPai(String peerUin, String chatType, String operatorUin) 拍一拍事件
String getSummary(String text) 自己发送图片消息时拦截,用于修改发送图片的外显

生命周期

void unLoadPlugin()

脚本停止/卸载时触发。

菜单功能

脚本菜单 (悬浮窗)

void addItem(String name, String callback)

添加脚本菜单项目。入口在聊天页面(长按右上角三条杠或者右下角加号)

回调定义:

function 回调方法名(聊天类型, peerUin, 名称) {
    // 处理逻辑
}

消息菜单 (长按消息)

void addMenuItem(String name, String callback, int[] msgTypes)

添加消息菜单项目。最后一个参数为空或不写则默认所有消息。

回调定义:

function 回调方法名(msgData) {
    // msgData为MsgData对象
}

网络请求

httpGet - GET请求

String httpGet(String url)
String httpGet(String url, int connectTimeout, int readTimeout)

httpPost - POST请求

String httpPost(String url, String body)
String httpPost(String url, String body, String contentType)

downloadFile - 下载文件

boolean downloadFile(String url, String savePath)

反射与Hook

反射方法

方法 返回值 参数 说明
callMethod Object Object obj, String methodName, Object... args 调用对象方法
callStaticMethod Object String className, String methodName, Object... args 调用静态方法
getFieldValue Object Object obj, String fieldName 获取字段值
setFieldValue void Object obj, String fieldName, Object value 设置字段值
newInstance Object String className, Object... args 创建类实例
findClass Class String className 查找类
findMethod Method Object obj, String methodName, int paramCount 根据参数数量查找方法
findMethod Method Object obj, String methodName, Class... parameterTypes 根据参数类型查找方法
findField Field Object obj, String fieldName 查找字段

Hook方法

方法 返回值 参数 说明
hookAfter XC_MethodHook.Unhook Object member, Object callback 方法执行后Hook
hookBefore XC_MethodHook.Unhook Object member, Object callback 方法执行前Hook

callback为Lambda表达式,参数为XC_MethodHook.MethodHookParam,可访问param.thisObject、param.args、param.getResult()等

UIN/UID转换

方法 返回值 参数 说明
getUidFromUin String String uin UIN转UID
getUinFromUid String String uid UID转UIN
isValidUin boolean String uin 验证UIN是否有效
isValidUid boolean String uid 验证UID是否有效
isValidQQ boolean String qq 验证QQ号是否有效

文件操作

方法 返回值 参数 说明
deleteFile boolean String path 删除文件
existsFile boolean String path 检查文件是否存在
mkdirs boolean String path 创建目录
getFileName String String path 获取文件名
getFileSize long String path 获取文件大小(字节)
getFileLastModified long String path 获取文件最后修改时间
getParentPath String String path 获取父目录路径
listFiles List\ String dirPath 列出目录下文件
readFile String String path 读取文件内容
writeFile void String path, String content 写入文件内容
appendFile void String path, String content 追加写入文件

编码解码

方法 返回值 参数 说明
urlEncode String String str URL编码
urlDecode String String str URL解码
base64Encode String String str Base64编码
base64Decode String String str Base64解码

其他方法

日志与提示

方法 返回值 参数 说明
console.log void Object msg 输出日志(写入脚本目录 log.txt 并输出到 logcat)
console.error void Object msg 输出错误日志
toast void Object msg 系统Toast
toastLong void Object msg 系统长Toast
qqToast void int icon, Object msg QQ风格顶部弹窗 (0警告/1错误/2成功)

动态加载

方法 返回值 参数 说明
loadJs void String path 加载JS文件(使用绝对路径,建议用 pluginPath 拼接)
loadJar void String path 加载Jar文件
loadJsLib void String path 加载JS库压缩包(zip/jar,一次性导入包内所有 .js)
loadDex void String path 加载Dex文件
registerActivity void Class\<?> activityClass 注册Activity

Activity操作

方法 返回值 参数 说明
startQQActivity void String activityClass 启动QQ Activity
startQQActivity void String activityClass, Map\<String, String> extras 启动QQ Activity(带参数)

工具方法

方法 返回值 参数 说明
getNowActivity Activity
获取当前顶层Activity
runOnUiThread void Runnable runnable 在主线程执行
importClass Object Object className 导入Java类(传入类名String或Packages.xxx类对象,短名绑定全局)
runOnBackgroundThread void Runnable runnable 在后台线程执行
isMainThread boolean
判断是否为主线程
sleep void long millis 休眠指定毫秒数
formatTime String long timestamp 格式化时间戳(默认格式)
formatTime String long timestamp, String format 格式化时间戳(自定义格式)
getCurrentTimeMillis long
获取当前时间戳(毫秒)
getCurrentTimeSeconds long
获取当前时间戳(秒)
getDeviceId String
获取设备ID
getVersionName String
获取模块版本名
getVersionCode int
获取模块版本号
sendPacket boolean String cmd, String jsonStr 发包: 命令字, Json包体
fetchPacket String String cmd, String jsonStr 发包: 命令字, Json包体(可返回数据)
sendPacket boolean String cmd, JSONObject json 发包: 命令字, JSONObject包体
fetchPacket String String cmd, JSONObject json 发包: 命令字, JSONObject包体(可返回数据)
readprop String String file, String name 读取properties文件中的指定键值

自身操作

方法 返回值 参数 说明
uploadAvatar boolean String filePath 上传头像(支持透明)
uploadAvatar void String filePath, boolean isStatic 第三方上传头像(支持透明),false为动态头像封面,需要apng格式
uploadCover boolean String filePath 上传主页名片图(支持透明)
uploadImage String String imagePath 上传本地图片到图床,返回图片URL(图片不存在时返回空串)
changeMyName void String nickname 修改昵称
addFriend void String uin,String msg,String remark 添加好友

JSON处理

方法 返回值 参数 说明
toJson String Object obj 对象转JSON字符串
parseJson JSONObject String jsonStr 解析JSON对象
parseJsonArray JSONArray String jsonStr 解析JSON数组

随机数

方法 返回值 参数 说明
generateRandomString String int length 生成随机字符串
generateRandomInt int int min, int max 生成随机整数

插件信息

方法 返回值 参数 说明
getPluginName String
获取插件名称
getPluginId String
获取插件ID
getPluginPath String
获取插件目录路径
isPluginEnabled boolean
判断插件是否启用
setPluginEnabled void boolean enabled 设置插件启用状态

示例脚本

console.log("脚本开始运行...");
qqToast(2, "Hello World!");

// 使用 importClass + runOnUiThread 弹出 Android 原声对话框
importClass("android.app.AlertDialog");
runOnUiThread(function() {
    new AlertDialog.Builder(getNowActivity())
        .setTitle("标题")
        .setMessage("来自 JS 插件的弹窗")
        .setPositiveButton("确定", null)
        .show();
});

addItem("测试菜单", "onTestClick");

function onTestClick(chatType, peerUin, peerName) {
    qqToast(2, "点击了菜单");
    sendMsg(peerUin, "你好!", chatType);
}

function onMsg(msgData) {
    var msg = msgData.msg;
    var peerUin = msgData.peerUin;
    var type = msgData.type;

    console.log("收到消息: " + msg);

    if (msg.indexOf("ping") >= 0) {
        sendMsg(peerUin, "pong", type);
    }
}

// loadJs 使用绝对路径加载其他脚本
// loadJs(pluginPath + "/lib/utils.js");

function unLoadPlugin() {
    qqToast(0, "脚本停止运行");
    console.log("脚本停止运行");
}