Skip to content

附录2:主动请求(远程控制)

chenxuyong edited this page Jun 2, 2022 · 25 revisions

适用 v3.0.0 (含)以上版本

1、接口规范约定

没有特殊声明的接口,都是按照下面的规范进行约定:

接口地址:

http://手机IP:5000/<接口URI>  #本机局域网
http://smsf.demo.com/<接口URI>  #Frp内网穿透(绑定你自己的域名)

请求方式:

POST

Content-Type:

application/json; charset=utf-8

请求示例

{
    "data": {},
    "timestamp": 1652590258638,
    "sign": ""
}

公共请求参数

参数 类型 是否必填 说明
data Any 请求参数,根据具体接口而定,参见 2、接口列表
timestamp Long 当前时间戳,单位是毫秒,与请求调用时间误差不能超过1小时
sign String 当设置secret时,生成的sign签名,规则见下方sign校验规则

响应示例

{
    "code": 200,
    "msg": "ok",
    "data": {},
    "timestamp": 1652590258638,
    "sign": ""
}

公共响应参数

参数 类型 是否必填 说明
code Int 200=成功,500=失败
msg String 成功或失败提示
data Any 响应参数,仅当成功时返回,根据具体接口而定,参见 2、接口列表
timestamp Long 时间戳,毫秒
sign String 当设置secret时,生成的sign签名,规则见下方sign校验规则

sign 校验规则(参考 阿里钉钉群机器人的sign生成):

timestamp+"\n"+密钥 当做签名字符串,使用 HmacSHA256 算法计算签名,然后进行 Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)


2、接口列表

2.1 一键换新机

2.1.1 客户端从服务端拉取配置

接口URI

/clone/pull

请求示例

{
    "data": {
        "version_code": 300038
    },
    "timestamp": 1652590258638,
    "sign": ""
}

请求参数

参数 类型 是否必填 说明
version_code Int 客户端App版本号(服务端与客户端的版本号必须一致)

响应示例

{
    "code": 200,
    "msg": "ok",
    "data": {
        "version_name": "3.0.0",
        "notify_content": "通知栏个性文案",
        "call_type1": false,
        "call_type2": false,
        "call_type3": false,
        "cancel_app_notify": false,
        "duplicate_messages_limits": 0,
        "enable_app_notify": false,
        "enable_battery_cron": true,
        "enable_battery_receiver": false,
        "enable_exclude_from_recents": false,
        "enable_help_tip": false,
        "enable_not_user_present": false,
        "enable_phone": false,
        "enable_play_silence_music": false,
        "enable_sms": false,
        "enable_sms_template": false,
        "request_delay_time": 1,
        "request_retry_times": 0,
        "request_timeout": 10,
        "battery_level_once": false,
        "battery_level_min": 0,
        "battery_level_max": 100,
        "version_code": 400038,
        "battery_cron_interval": 60,
        "battery_cron_start_time": "00:00",
        "sms_template": "",
        "sender_list": [
            {
                "time": "Apr 14, 2022 3:37:36 PM",
                "json_setting": "{\"atAll\":false,\"atMobiles\":\"\",\"secret\":\"SEC1234567890\",\"token\":\"123456789012345678901234567890\"}",
                "name": "钉钉群机器人",
                "status": 1,
                "id": 1,
                "type": 0
            }
        ],
        "rule_list": [
            {
                "check": "is",
                "filed": "package_name",
                "value": "88888888",
                "regex_replace": "",
                "type": "app",
                "sim_slot": "ALL",
                "sms_template": "",
                "time": "Apr 14, 2022 3:37:36 PM",
                "id": 1,
                "sender_id": 1,
                "status": 1
            }
        ]
    },
    "timestamp": "1652590258638",
    "sign": ""
}

响应参数

2.1.2 客户端向服务端推送配置

接口URI

/clone/push

请求示例

{
    "data": {
        "version_name": "3.0.0",
        "notify_content": "通知栏个性文案",
        "call_type1": false,
        "call_type2": false,
        "call_type3": false,
        "cancel_app_notify": false,
        "duplicate_messages_limits": 0,
        "enable_app_notify": false,
        "enable_battery_cron": true,
        "enable_battery_receiver": false,
        "enable_exclude_from_recents": false,
        "enable_help_tip": false,
        "enable_not_user_present": false,
        "enable_phone": false,
        "enable_play_silence_music": false,
        "enable_sms": false,
        "enable_sms_template": false,
        "request_delay_time": 1,
        "request_retry_times": 0,
        "request_timeout": 10,
        "battery_level_once": false,
        "battery_level_min": 0,
        "battery_level_max": 100,
        "version_code": 400038,
        "battery_cron_interval": 60,
        "battery_cron_start_time": "00:00",
        "sms_template": "",
        "sender_list": [
            {
                "time": "Apr 14, 2022 3:37:36 PM",
                "json_setting": "{\"atAll\":false,\"atMobiles\":\"\",\"secret\":\"SEC1234567890\",\"token\":\"123456789012345678901234567890\"}",
                "name": "钉钉群机器人",
                "status": 1,
                "id": 1,
                "type": 0
            }
        ],
        "rule_list": [
            {
                "check": "is",
                "filed": "package_name",
                "value": "88888888",
                "regex_replace": "",
                "type": "app",
                "sim_slot": "ALL",
                "sms_template": "",
                "time": "Apr 14, 2022 3:37:36 PM",
                "id": 1,
                "sender_id": 1,
                "status": 1
            }
        ]
    },
    "timestamp": "1652590258638",
    "sign": ""
}

请求参数

略,同拉取配置接口返回的数据

响应示例

{
    "code": 200,
    "msg": "success",
    "data": "success",
    "timestamp": 1653982995002,
    "sign": "NGxleev7ZZ%2Bd2KYCPHGw9XuoDo6Y6u7y1Pe3AZmsw6k%3D"
}

2.2 远程短信

2.2.1 远程发短信

接口URI

/sms/send

请求示例

{
  "data": {
    "sim_slot": 1,
    "phone_numbers": "15888888888;19999999999",
    "msg_content": "短信内容"
  },
  "timestamp": 1652590258638,
  "sign": ""
}

请求参数

参数 类型 是否必填 说明
sim_slot Int 发送卡槽: 1=SIM1, 2=SIM2
phone_numbers String 接收手机号码,多个手机号用半角分号分隔
msg_content String 短信内容,70个字符内算一条,超过70个字符,每增加64字符累加1条,最多390字符(6条短信)

响应示例

{
    "code": 200,
    "msg": "success",
    "data": "success",
    "timestamp": 1653982995002,
    "sign": "NGxleev7ZZ%2Bd2KYCPHGw9XuoDo6Y6u7y1Pe3AZmsw6k%3D"
}

2.2.2 远程查短信

接口URI

/sms/query

请求示例

{
  "data": {
    "type": 1,
    "page_num": 1,
    "page_size": 10
  },
  "timestamp": 1652590258638,
  "sign": ""
}

请求参数

参数 类型 是否必填 说明
type Int 短信类型: 1=接收, 2=发送
page_num Int 页码,默认=1
page_size Int 分页大小,默认=10

响应示例

{
    "code": 200,
    "msg": "success",
    "data": [
        {
            "content": "123456",
            "number": "15806064566",
            "name": "Unknown Number",
            "type": 2,
            "date": 1653903967357,
            "sim_id": -1
        }
    ],
    "timestamp": 1653922777594,
    "sign": "PsizhZ16kBh7xc6W9env9U0qITqoy8lOcjpG8FKDNNs%3D"
}

响应参数

参数 类型 是否必填 说明
name String 联系人姓名
number String 联系人号码
content String 短信内容
date Long 短信时间
type Int 短信类型: 1=接收, 2=发送
sim_id Int 卡槽ID: 1=Sim1, 2=Sim2, -1=获取失败

2.3 远程查通话

接口URI

/call/query

请求示例

{
  "data": {
    "type": 1,
    "page_num": 1,
    "page_size": 10,
    "phone_number": "15888888888",
  },
  "timestamp": 1652590258638,
  "sign": ""
}

请求参数

参数 类型 是否必填 说明
type Int 通话类型:1=呼入, 2=呼出, 3=未接,0=不筛选(默认)
page_num Int 页码,默认=1
page_size Int 分页大小,默认=10
phone_number String 手机号码,模糊匹配

响应示例

{
    "code": 200,
    "msg": "success",
    "data": [
        {
            "dateLong": 1653977301182,
            "number": "911111881",
            "sim_id": -1,
            "type": 2,
            "duration": 3
        }
    ],
    "timestamp": 1653977311680,
    "sign": "MOfD66%2BptfxHvyxpTXnMdApHy6qgfQcaB0EN9sks%2F0o%3D"
}

响应参数

参数 类型 是否必填 说明
name String 姓名
number String 号码
dateLong Long 通话日期
duration Int 通话时长,秒
type Int 通话类型:1=呼入, 2=呼出, 3=未接
sim_id Int 卡槽ID: 1=Sim1, 2=Sim2, -1=获取失败

2.4 远程查话簿

接口URI

/contact/query

请求示例

{
  "data": {
    "phone_number": "15888888888",
    "name": "pppscn",
  },
  "timestamp": 1652590258638,
  "sign": ""
}

请求参数

参数 类型 是否必填 说明
phone_number String 手机号码,模糊匹配
name String 姓名,模糊匹配

响应示例

{
    "code": 200,
    "msg": "success",
    "data": [
        {
            "dateLong": 1653977301182,
            "number": "911111881",
            "sim_id": -1,
            "type": 2,
            "duration": 3
        }
    ],
    "timestamp": 1653977311680,
    "sign": "MOfD66%2BptfxHvyxpTXnMdApHy6qgfQcaB0EN9sks%2F0o%3D"
}

响应参数

参数 类型 是否必填 说明
name String 姓名
number String 号码
dateLong Long 通话日期
duration Int 通话时长,秒
type Int 通话类型:1=呼入, 2=呼出, 3=未接
sim_id Int 卡槽ID: 0=Sim1, 1=Sim2, -1=获取失败

2.5 远程查电量

接口URI

/battery/query

请求示例

{
  "data": {},
  "timestamp": 1652590258638,
  "sign": ""
}

响应示例

{
    "code": 200,
    "msg": "success",
    "data": {
        "level": "100%",
        "scale": "100%",
        "status": "充电中",
        "health": "良好",
        "plugged": "AC"
    },
    "timestamp": 1653925480414,
    "sign": "GBmhQgeB5iplRolsMuqZd0eU%2FEBAS0PQfxFwe5TjhcU%3D"
}

响应参数

参数 类型 是否必填 说明
level String 剩余电量
scale String 充满电量
voltage String 当前电压
temperature String 当前温度
status String 电池状态
health String 健康度
plugged String 充电器

PS. SmsForwarder 3.0 API 文档到此结束,最后修改时间:2022年06月01日



适用 v2.4.4 (含)以下版本


SmsForwarder V2.4.0 以上,可以通过 被动接收 或者 主动轮询 获取指令,从而操作本机

【注意】这只是一个先行尝试的功能(来自机油的PR),下一个版本(2.5.0)重点改造此功能
对暴露的api有什么想法欢迎提issue,在合法合规的前提下,酌情考虑会不会添加!

后续版本可能发生的改变(包括但不限于):

  • 请求与应答报文重新设计(结构、状态码等统一规范)
  • 服务端与客户端双向验签(或对称加密报文)【可选】
  • 提供简单的 SmsHub Api 服务端demo【只保留HttpServer、增加内网穿透】

被动接收本地 HttpServer

  • WiFi网络下可用,启动后局域网内其他机器可直接调用本机接口

  • 一键克隆 共用本地 HttpServer,访问URL: http://本地ip:5000/send_api

  • 接收一个list并执行操纵,设置处理结果后并在尾部追加一个心跳包后返回原list

短信发送接口(v2.4.2+ 报文结构调整如下)

接口URL:

http://你的ip/send_api

请求方式:

POST

Content-Type:

application/json; charset=utf-8

请求参数:

{
    "data": [
        {
            "action": 0,
            "target": "136227276",
            "content": "Test Msg1",
            "channel": "1"
        },
        {
            "action": 0,
            "target": "13636277",
            "content": "Test Msg2",
            "channel": "2"
        }
    ]
}

返回报文:

{
    "code": 200,
    "data": [
        {
            "action": "2",
            "channel": "SIM1",
            "content": "Test Msg1",
            "target": "18888888888",
            "ts": "1644458153622",
            "type": "sms"
        },
        {
            "action": "2",
            "channel": "SIM1",
            "content": "Test Msg2",
            "target": "18888888888",
            "ts": "1644458153651",
            "type": "sms"
        }
    ],
    "heartbeat": {
        "action": "-1",
        "channel": "SIM1:18888888888;SIM2:18888888889",
        "deviceInfo": "{\"Version\":\"2.4.1\",\"heartbeat\":\"30\",\"simOperatorName\":\"中国联通\",\"imei\":xxxxxxxxxxxxxxx\"\",\"SDKVersion\":\"29\",\"mark\":\"Mi8\"}",
        "ts": "1644458153565"
    },
    "msg": ""
}

主动轮询远程 SmsHub Api

  • 请先在通用设置中,填写服务端地址,再启动服务,APP轮询执行接口返回的操作

  • 每隔30秒发送一个心跳包,包含当前设备的信息,children里为上一次心跳后收到的所有消息,服务端需返回一个 list

报文结构:

[{
    "action": "0", //发送短信操作(暂时只支持发送操作)
    "target": "88888",//收件人手机号
    "content": "xxx",//内容
    "channel": "1"//卡槽 1或2
},
{...
}]

附录:

//唯一id
private String msgId;
//心跳数据时发送的设备名
private String deviceInfo;
//卡槽信息
private String channel;
//消息内容
private String content;
//错误消息
private String errMsg;
//手机号(;分隔)或包名
private String target;
//状态或操作 0:发送短信, 1:接收到的消息, 2:操作处理成功, 3:操作处理失败, -1:心跳包 (包含deviceInfo字段,children里带有两次心跳间收到的消息)
private String action;
//消息类型 app:通知 phone:来电, sms:短信, battery:电池信息
private String type;
//时间戳
private String ts;
//两次交互之间接收到的消息
private List<SmsHubVo> children;

Clone this wiki locally