前言
因为有了更好的流量套餐,所以多出一张电话卡只能放到备用安卓机上,但是换下来的卡还绑定着一些东西,偶尔要收收验证码什么的,因此就想到开发一款短信转发App。功能很简单,就用H5开发。
一开始打算这款App同时满足收发功能,直到偶然间在张大妈看见有大佬用 树莓派+企业微信 做了一个短信转发,瞬间膜拜。那么,服务器就由马老板买单了(~ ̄▽ ̄)~
正文
一、注册企业微信
注册地址:企业微信
之所以不用服务号,订阅号是因为比较麻烦,注册时都需要绑定身份证等,能简单点就简单点。
注册好后手机下载企业微信App,把自己的微信号拉入新建的企业里面去,并且扫描二维码关注 微工作台
以后就可以卸载企业微信,用正常的微信接受消息
二、创建程序
应用管理=》自建=》创建一个程序,名称随意
三、获取以下参数
1、我的企业=》企业ID
2、应用管理=》自建的程序=》AgentId 和 Secret
3、通讯录=》点击一个用户查看详情=》账号
四、用HBuilder新建5+APP Mui项目
在项目内新建一个jquery
五、新建SMS.js
var callbacks = [];
var receiver;
var filter;
var main;
var isInit = false;
var isRegistered = false;
var isOlderVersion = false;
//plusReady封装,若使用mui,可直接使用mui.plusReady()方法;
var plusReady = function(callback) {
if (window.plus) {
callback();
} else {
document.addEventListener("plusready", function() {
callback();
}, false);
}
}
/**
* 初始化
*/
var init = function(callback) {
//仅支持android版本
if (plus.os.name !== \'Android\') {
return;
}
try {
var version = plus.runtime.innerVersion.split(\'.\');
isOlderVersion = parseInt(version[version.length - 1]) < 22298;
main = plus.android.runtimeMainActivity();
var Intent = plus.android.importClass(\'android.content.Intent\');
var IntentFilter = plus.android.importClass(\'android.content.IntentFilter\');
var SmsMessage = plus.android.importClass(\'android.telephony.SmsMessage\');
var receiverClass = \'io.dcloud.feature.internal.reflect.BroadcastReceiver\';
if (isOlderVersion) {
receiverClass = \'io.dcloud.feature.internal.a.a\';
}
filter = new IntentFilter();
var onReceiveCallback = function(context, intent) {
try {
var action = intent.getAction();
if (action == "android.provider.Telephony.SMS_RECEIVED") {
var pdus = intent.getSerializableExtra("pdus");
var msgs = [];
for (var i = 0, len = pdus.length; i < len; i++) {
msgs.push(SmsMessage.createFromPdu(pdus[i]));
}
for (var i = 0, len = callbacks.length; i < len; i++) {
callbacks[i](msgs);
}
}
} catch (e) {}
}
receiver = plus.android.implements(receiverClass, {
a: onReceiveCallback,
onReceive: onReceiveCallback
});
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
callback && callback();
} catch (e) {}
}
//注册短信监听
var register = function(callback) {
callbacks.push(callback);
if (!isInit) {
isInit = isRegistered = true;
mui.plusReady(function() {
init(function() {
setTimeout(function() {
// console.log(\'registerReceiver\');
try {
if (isOlderVersion) {
main.a(receiver, filter);
} else {
main.registerReceiver(receiver, filter); //注册监听
}
} catch (e) {}
}, 300);
});
});
} else if (!isRegistered) {
// console.log(\'registerReceiver\');
try {
if (isOlderVersion) {
main.a(receiver, filter);
} else {
main.registerReceiver(receiver, filter); //注册监听
}
} catch (e) {}
}
};
//注销监听,在登录成功或从登录页跳转到其它页面后调用
var unregister = function(callback, remove) {
for (var i = 0, len = callbacks.length; i < len; i++) {
if (callbacks[i] === callback) {
callbacks.splice(i, 1);
}
}
if (remove && !callbacks.length) {
if (main && isRegistered) {
try {
if (isOlderVersion) {
main.a(receiver);
} else {
main.unregisterReceiver(receiver);
}
} catch (e) {}
isRegistered = false;
// console.log(\'unregisterReceiver\');
}
}
};
六、Index主页
把上面的四个参数填入进去,并把js引用路径进行调整
<!DOCTYPE html>
<html class="ui-page-login">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<link href="css/mui.min.css" rel="stylesheet" />
<link href="css/style.css" rel="stylesheet" />
<style>
.title {
margin-top: 0;
margin-bottom: 0;
padding-left: 0;
}
.SMS .Phone {
font-family: \'Helvetica Neue\', Helvetica, sans-serif;
font-size: 17px;
line-height: 21px;
color: #000;
}
.SMS .Context {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.SMS .Context.Active {
white-space: initial
}
</style>
</head>
<body>
<header class="mui-bar mui-bar-nav mui-bar-transparent">
<ul class="title">
<li class="mui-table-view-cell">
信使
<div id="sendSwitch" class="mui-switch mui-switch-mini mui-active">
<div class="mui-switch-handle"></div>
</div>
</li>
</ul>
</header>
<div class="mui-content">
<ul class="mui-table-view" id="SMSList">
</ul>
</div>
<script src="js/mui.min.js"></script>
<script src="js/mui.enterfocus.js"></script>
<script src="javascript/Jquery/Jquery-3.4.1.min.js"></script>
<script src="js/SMS.js"></script>
<script>
var _corpid = ""; //企业ID
var _corpsecret = ""; //Secret
var _touser="";//用户账号
var _agentid=1000000;//AgentId
var _sendSwitch = true;
var _SMSList = {}; //待发送信息集合
var _token = "";
$(function() {
//获取开关状态
mui(".title").on("tap", "#sendSwitch", function() {
var isActive = document.getElementById("sendSwitch").classList.contains("mui-active");
if (isActive) {
_sendSwitch = true;
} else {
_sendSwitch = false;
}
});
//短信点击事件
mui("#SMSList").on("tap", ".SMS", function() {
var isActive = $(".Active");
if (isActive) {
isActive.removeClass("Active")
}
$(this).children(\'.Context\').addClass("Active");
});
//获取token
getToken()
})
//****************************短信监听 开始****************************+
var handleSMS = function(msgs) {
if (_sendSwitch == false)
return;
for (var i = 0, len = msgs.length; i < len; i++) {
var phone = msgs[i].getDisplayOriginatingAddress(); //获取来源手机号
var content = msgs[i].getDisplayMessageBody(); //获取短信内容
//储存短信内容进行拼接,产生会话模式
if (_SMSList[phone] == undefined)
_SMSList[phone] = content;
else
_SMSList[phone] += content;
//延迟执行
setTimeout(function() {
SendSMS(phone)
}, 3000);
}
};
//登录页面注册短信监听事件
register(handleSMS);
//****************************短信监听 结束****************************
//获取token
function getToken() {
$.ajax({
url: "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + _corpid + "&corpsecret=" + _corpsecret,
dataType: "json",
success: function(result) {
if (result.errcode == 0) {
_token = result.access_token;
return result.access_token;
} else {
var smsHtml = \'<li class="mui-table-view-cell SMS"><p class="Phone">\' + result.errcode +
\'</p><p class="Context">\' +
result.errmsg + \'</p></li>\'
$("#SMSList").prepend(smsHtml)
mui.toast(\'获取token失败,错误码:\' + result.errcode + \'\\r错误信息:\' + result.errmsg, {
duration: \'long\',
type: \'div\'
});
}
}
});
}
//发送短信
function SendSMS(phone) {
//如果已被发送则无需再次发送
if (_SMSList[phone] == undefined)
return;
//拼接参数
var data = {
"touser": _touser,
"msgtype": "text",
"agentid": _agentid,
"text": {
"content": "发信人:" + phone + "\\n短信内容:" + _SMSList[phone]
},
"safe": 0
}
//在APP中显示短信
var smsHtml = \'<li class="mui-table-view-cell SMS"><p class="Phone">\' + phone + \'</p><p class="Context">\' +
_SMSList[phone] + \'</p></li>\'
$("#SMSList").prepend(smsHtml)
delete _SMSList[phone];
$.ajax({
type: \'POST\',
url: "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + _token,
data: JSON.stringify(data),
dataType: "json",
success: function(result) {
if (result.errcode == 42001) {
getToken()
SendSMS(phone)
} else if (result.errcode == 0) {
mui.toast(\'转发成功\', {
duration: \'long\',
type: \'div\'
});
} else {
var smsHtml = \'<li class="mui-table-view-cell SMS"><p class="Phone">\' + result.errcode +
\'</p><p class="Context">\' +
result.errmsg + \'</p></li>\'
$("#SMSList").prepend(smsHtml)
mui.toast(\'发送信息失败,错误码:\' + result.errcode + \'\\r错误信息:\' + result.errmsg, {
duration: \'long\',
type: \'div\'
});
}
}
});
}
</script>
</body>
</html>
七、权限
1、应用获取短信权限,并在手机内给与获取短信权限
2、关闭验证码保护
不关闭这个的话软件无法监听含有验证码的短信
八、成果
最后
1、因为监听短信的方法目前只支持安卓,所以ios只能参考思路
2、笔者备用安卓机系统为4.0.4,挺低了,版本往上的应该都支持
3、目前垃圾短信会被安卓机自带的管家拦截,所以不需要垃圾短信过滤( ̄▽ ̄)~*