须知:
本方案需要手机有 root 权限, 并依赖 Synapse; curl 及 Tasker (MacroDroid 亦可). 向服务器发送请求由 curl 完成, 如果 Tasker 支持 POST 方法 (我还没来得及测试, Tasker 就再也不能试用了, 不过已知 MacroDroid 不支持 POST 但支持 GET) 可以不用 curl. 你可以按自己的需要魔改本方案.
大概流程 (因为 Tasker 无法使用已卸载, 我现在改用 MacroDroid):
-
手机安装 MacroDroid;
-
新建一个宏, 触发器选择 "短信来自", 发送者选择 "任何号码";
-
添加一个局部变量;
-
添加动作:
a) 动作 1: 添加 Shell 脚本, 发送一个 POST 请求 (由于我使用的是 Synapse, 此处我给出的是 Synapse 允许的请求方式):curl -H "Content-Type: application/json" -H "Authorization: Bearer <access_token>" -s -X POST -k -d '{"msgtype": "m.text", "body": "短信转发. 发送者: [sms_number]\u000a\u000a[sms_message]"}' "https://example.com:[port]/_matrix/client/r0/rooms/%21room_id:example.com/send/m.room.message" # 请求需要提供一个账号的访问 token 及目标房间 ID, 建议针对短信转发用途新建一个专用账号. # [sms_message] 及 [sms_number] 是 MacroDroid 的内置变量, 分别表示短信正文及发送者号码. # 选中 "将输出保存为字符串变量", 并选择步骤 3 新建的变量. # 选中 "完成后此案后续动作". # 这里有个大坑, 如果转发的内容需要换行, 必须使用 "\u000a" 而不是 "\n".b) 动作 2: 添加 "如果条件", 在其中添加条件: "MacroDroid 特定" -> "MacroDroid 变量", 选择步骤 3 新建的变量. 运算符选择 "不包括", 值填写
{"event_id":// 用于判断服务器是否返回了 json, 因为 json 的格式固定就没用正则表达式, 反正无脑判断前几个字符就足够了.c) 动作 2-1: 添加 toast 用于提示短信自动转发失败后自动打开 Element;
d) 动作 2-2: 添加 Shell 脚本:am start -a "android.intent.action.SEND" --es "android.intent.extra.TEXT" "短信补转发. 发送者: [sms_number]\n\n[sms_message]" -t "text/plain" im.vector.app.debug # 命令可能需要 root 权限.e) 动作 3: 继续从 "如果条件" 添加 "else 从句";
f) 动作 3-1: 单击一下 "其他", 此处可以添加一个通知 (或 toast) 用于提示短信自动转发成功;
g) 保存修改.
以上动作的排列顺序:
https://imgur.com/a/y2uqATM
效果:
当收到短信的第一时间会自动转发短信到我自建的 Synapse 服务器 (前提是手机能联网或服务器在线), 其它所有安装了 Element 的终端 (包括备用机; 电脑; 平板电脑等) 都能收到. 灰色为自动发送 (专用账号), 绿色为手动发送 (自己的账号): https://imgur.com/a/OM9hS9H https://imgur.com/a/OaM8FXY
缺点:
如果因为各种原因无法与服务器通信, 则自动打开 Element 并选择联系人手动转发收到的短信. 然而这种情况下如果遭遇短信轰炸, 流程上会出现问题. 例如瞬间收到太多短信会导致人工根本忙不过来. 我希望能在没有人工干预的前提下完成发送到 Element, 等联网恢复再由 Element 发送到服务器. 这个目前尚未实现.
