diff --git a/code/code.ino b/code/code.ino
index fd32d4b4b..8b430fa70 100644
--- a/code/code.ino
+++ b/code/code.ino
@@ -65,6 +65,7 @@ struct Config {
PushChannel pushChannels[MAX_PUSH_CHANNELS]; // 多推送通道
String webUser; // Web管理账号
String webPass; // Web管理密码
+ String numberBlackList; // 号码黑名单(换行符分隔)
};
// 默认Web管理账号密码
@@ -124,6 +125,7 @@ void saveConfig() {
preferences.putString("adminPhone", config.adminPhone);
preferences.putString("webUser", config.webUser);
preferences.putString("webPass", config.webPass);
+ preferences.putString("numBlkList", config.numberBlackList);
// 保存推送通道配置
for (int i = 0; i < MAX_PUSH_CHANNELS; i++) {
@@ -152,6 +154,7 @@ void loadConfig() {
config.adminPhone = preferences.getString("adminPhone", "");
config.webUser = preferences.getString("webUser", DEFAULT_WEB_USER);
config.webPass = preferences.getString("webPass", DEFAULT_WEB_PASS);
+ config.numberBlackList = preferences.getString("numBlkList", "");
// 加载推送通道配置
for (int i = 0; i < MAX_PUSH_CHANNELS; i++) {
@@ -327,6 +330,15 @@ const char* htmlPage = R"rawliteral(
+
+
🚫 号码黑名单
+
每行一个号码,来自黑名单号码的短信将被忽略。
+
+
+
+
+
+
@@ -742,6 +754,7 @@ void handleRoot() {
html.replace("%SMTP_PASS%", config.smtpPass);
html.replace("%SMTP_SEND_TO%", config.smtpSendTo);
html.replace("%ADMIN_PHONE%", config.adminPhone);
+ html.replace("%NUMBER_BLACK_LIST%", config.numberBlackList);
// 生成推送通道HTML
String channelsHtml = "";
@@ -1530,6 +1543,7 @@ void handleSave() {
config.smtpPass = server.arg("smtpPass");
config.smtpSendTo = server.arg("smtpSendTo");
config.adminPhone = server.arg("adminPhone");
+ config.numberBlackList = server.arg("numberBlackList");
// 保存推送通道配置
for (int i = 0; i < MAX_PUSH_CHANNELS; i++) {
@@ -1720,6 +1734,34 @@ void resetModule() {
}
+// 检查发送者是否在号码黑名单中
+bool isInNumberBlackList(const char* sender) {
+ if (config.numberBlackList.length() == 0) return false;
+
+ String originalSender = String(sender);
+ bool has86 = originalSender.startsWith("+86");
+ String strippedSender = has86 ? originalSender.substring(3) : "";
+
+ int listLen = (int)config.numberBlackList.length();
+
+ int start = 0;
+ while (start <= listLen) {
+ int end = config.numberBlackList.indexOf('\n', start);
+ if (end == -1) end = listLen;
+
+ String line = config.numberBlackList.substring(start, end);
+ line.trim();
+
+ if (line.length() > 0 && (line.equals(originalSender) || (has86 && line.equals(strippedSender)))) {
+ return true;
+ }
+
+ start = end + 1;
+ }
+
+ return false;
+}
+
// 检查发送者是否为管理员
bool isAdmin(const char* sender) {
if (config.adminPhone.length() == 0) return false;
@@ -2302,6 +2344,12 @@ void processSmsContent(const char* sender, const char* text, const char* timesta
Serial.println("内容: " + String(text));
Serial.println("====================");
+ // 检查是否在号码黑名单中
+ if (isInNumberBlackList(sender)) {
+ Serial.println("发送者在号码黑名单中,忽略该短信");
+ return;
+ }
+
// 检查是否为管理员命令
if (isAdmin(sender)) {
Serial.println("收到管理员短信,检查命令...");
@@ -2540,6 +2588,8 @@ void setup() {
Serial.println("网络已注册");
// ========== 模组初始化完成 ==========
+ // 扫描所有信道以连接信号最强的 AP,防止在 mesh 组网这类场景中连接到弱 AP
+ WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
// 连接WiFi(支持隐藏SSID)
// 参数: ssid, password, channel(0=自动), bssid(nullptr=自动), connect(true=连接隐藏网络)
WiFi.begin(WIFI_SSID, WIFI_PASS, 0, nullptr, true);