Skip to content

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

chenxuyong edited this page Jun 1, 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.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,
            "simId": -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",
            "simId": -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",
            "simId": -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年5月31日



适用 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