优化:`发送通道`参数默认值(避免反序列化时空指针)

This commit is contained in:
pppscn 2024-04-09 15:07:22 +08:00
parent 27fa30a5e1
commit 9107fa4589
33 changed files with 202 additions and 184 deletions

View File

@ -4,21 +4,21 @@ import java.io.Serializable
data class BarkSetting( data class BarkSetting(
//推送地址 //推送地址
var server: String, var server: String = "",
//分组名称 //分组名称
val group: String? = "", val group: String = "",
//消息图标 //消息图标
val icon: String? = "", val icon: String = "",
//消息声音 //消息声音
val sound: String? = "", val sound: String = "",
//消息角标 //消息角标
val badge: String? = "", val badge: String = "",
//消息链接 //消息链接
val url: String? = "", val url: String = "",
//通知级别 //通知级别
val level: String? = "active", val level: String = "active",
//标题模板 //标题模板
val title: String? = "", val title: String = "",
//加密算法 //加密算法
val transformation: String = "none", val transformation: String = "none",
//加密密钥 //加密密钥

View File

@ -5,12 +5,12 @@ import java.io.Serializable
data class DingtalkGroupRobotSetting( data class DingtalkGroupRobotSetting(
var token: String = "", var token: String = "",
var secret: String? = "", var secret: String = "",
var atAll: Boolean? = false, var atAll: Boolean = false,
var atMobiles: String? = "", var atMobiles: String = "",
var atDingtalkIds: String? = "", var atDingtalkIds: String = "",
var msgtype: String? = "text", var msgtype: String = "text",
val titleTemplate: String? = "", val titleTemplate: String = "",
) : Serializable { ) : Serializable {
fun getMsgTypeCheckId(): Int { fun getMsgTypeCheckId(): Int {

View File

@ -10,13 +10,13 @@ data class DingtalkInnerRobotSetting(
val appSecret: String = "", val appSecret: String = "",
val userIds: String = "", val userIds: String = "",
val msgKey: String = "sampleText", val msgKey: String = "sampleText",
val titleTemplate: String? = "", val titleTemplate: String = "",
val proxyType: Proxy.Type = Proxy.Type.DIRECT, val proxyType: Proxy.Type = Proxy.Type.DIRECT,
val proxyHost: String? = "", val proxyHost: String = "",
val proxyPort: String? = "", val proxyPort: String = "",
val proxyAuthenticator: Boolean? = false, val proxyAuthenticator: Boolean = false,
val proxyUsername: String? = "", val proxyUsername: String = "",
val proxyPassword: String? = "", val proxyPassword: String = "",
) : Serializable { ) : Serializable {
fun getProxyTypeCheckId(): Int { fun getProxyTypeCheckId(): Int {

View File

@ -4,19 +4,19 @@ import com.idormy.sms.forwarder.R
import java.io.Serializable import java.io.Serializable
data class EmailSetting( data class EmailSetting(
var mailType: String? = "", var mailType: String = "",
var fromEmail: String? = "", var fromEmail: String = "",
var pwd: String? = "", var pwd: String = "",
var nickname: String? = "", var nickname: String = "",
var host: String? = "", var host: String = "",
var port: String? = "", var port: String = "",
var ssl: Boolean? = false, var ssl: Boolean = false,
var startTls: Boolean? = false, var startTls: Boolean = false,
var title: String? = "", var title: String = "",
var recipients: MutableMap<String, Pair<String, String>> = mutableMapOf(), var recipients: MutableMap<String, Pair<String, String>> = mutableMapOf(),
var toEmail: String? = "", var toEmail: String = "",
var keystore: String? = "", var keystore: String = "",
var password: String? = "", var password: String = "",
var encryptionProtocol: String = "Plain", //加密协议: S/MIME、OpenPGP、Plain不传证书 var encryptionProtocol: String = "Plain", //加密协议: S/MIME、OpenPGP、Plain不传证书
) : Serializable { ) : Serializable {

View File

@ -5,14 +5,14 @@ import java.io.Serializable
data class FeishuSetting( data class FeishuSetting(
var webhook: String = "", var webhook: String = "",
val secret: String? = "", val secret: String = "",
val msgType: String? = "interactive", val msgType: String = "interactive",
val titleTemplate: String? = "", val titleTemplate: String = "",
val messageCard: String = "", //自定义消息卡片 val messageCard: String = "", //自定义消息卡片
) : Serializable { ) : Serializable {
fun getMsgTypeCheckId(): Int { fun getMsgTypeCheckId(): Int {
return if (msgType == null || msgType == "interactive") { return if (msgType == "interactive") {
R.id.rb_msg_type_interactive R.id.rb_msg_type_interactive
} else { } else {
R.id.rb_msg_type_text R.id.rb_msg_type_text

View File

@ -4,6 +4,6 @@ import java.io.Serializable
data class GotifySetting( data class GotifySetting(
var webServer: String = "", var webServer: String = "",
val title: String? = "", val title: String = "",
val priority: String? = "", val priority: String = "",
) : Serializable ) : Serializable

View File

@ -5,11 +5,11 @@ import java.io.Serializable
data class PushplusSetting( data class PushplusSetting(
var website: String = "www.pushplus.plus", var website: String = "www.pushplus.plus",
var token: String = "", var token: String = "",
val topic: String? = "", val topic: String = "",
val template: String? = "", val template: String = "",
val channel: String? = "", val channel: String = "",
val webhook: String? = "", val webhook: String = "",
val callbackUrl: String? = "", val callbackUrl: String = "",
val validTime: String? = "", val validTime: String = "",
val titleTemplate: String? = "", val titleTemplate: String = "",
) : Serializable ) : Serializable

View File

@ -4,7 +4,7 @@ import java.io.Serializable
data class ServerchanSetting( data class ServerchanSetting(
var sendKey: String = "", var sendKey: String = "",
var channel: String? = "", var channel: String = "",
var openid: String? = "", var openid: String = "",
var titleTemplate: String? = "", var titleTemplate: String = "",
) : Serializable ) : Serializable

View File

@ -6,7 +6,7 @@ import java.io.Serializable
data class SmsSetting( data class SmsSetting(
var simSlot: Int = 0, var simSlot: Int = 0,
var mobiles: String = "", var mobiles: String = "",
var onlyNoNetwork: Boolean? = false, var onlyNoNetwork: Boolean = false,
) : Serializable { ) : Serializable {
fun getSmsSimSlotCheckId(): Int { fun getSmsSimSlotCheckId(): Int {

View File

@ -4,12 +4,12 @@ import com.idormy.sms.forwarder.R
import java.io.Serializable import java.io.Serializable
data class SocketSetting( data class SocketSetting(
val method: String? = "MQTT", val method: String = "MQTT",
var address: String = "", //IP地址 var address: String = "", //IP地址
val port: Int = 0, //端口号 val port: Int = 0, //端口号
val msgTemplate: String = "", //消息模板 val msgTemplate: String = "", //消息模板
val secret: String? = "", //签名密钥 val secret: String = "", //签名密钥
val response: String? = "", //成功应答关键字 val response: String = "", //成功应答关键字
val username: String = "", //用户名 val username: String = "", //用户名
val password: String = "", //密码 val password: String = "", //密码
val inCharset: String = "", //输入编码 val inCharset: String = "", //输入编码
@ -23,7 +23,7 @@ data class SocketSetting(
fun getMethodCheckId(): Int { fun getMethodCheckId(): Int {
return when (method) { return when (method) {
null, "MQTT" -> R.id.rb_method_mqtt "MQTT" -> R.id.rb_method_mqtt
"TCP" -> R.id.rb_method_tcp "TCP" -> R.id.rb_method_tcp
"UDP" -> R.id.rb_method_udp "UDP" -> R.id.rb_method_udp
else -> R.id.rb_method_mqtt else -> R.id.rb_method_mqtt

View File

@ -5,19 +5,19 @@ import java.io.Serializable
import java.net.Proxy import java.net.Proxy
data class TelegramSetting( data class TelegramSetting(
val method: String? = "POST", val method: String = "POST",
var apiToken: String = "", var apiToken: String = "",
val chatId: String = "", val chatId: String = "",
val proxyType: Proxy.Type = Proxy.Type.DIRECT, val proxyType: Proxy.Type = Proxy.Type.DIRECT,
val proxyHost: String? = "", val proxyHost: String = "",
val proxyPort: String? = "", val proxyPort: String = "",
val proxyAuthenticator: Boolean? = false, val proxyAuthenticator: Boolean = false,
val proxyUsername: String? = "", val proxyUsername: String = "",
val proxyPassword: String? = "", val proxyPassword: String = "",
) : Serializable { ) : Serializable {
fun getMethodCheckId(): Int { fun getMethodCheckId(): Int {
return if (method == null || method == "POST") R.id.rb_method_post else R.id.rb_method_get return if (method == "GET") R.id.rb_method_get else R.id.rb_method_post
} }
fun getProxyTypeCheckId(): Int { fun getProxyTypeCheckId(): Int {

View File

@ -3,5 +3,5 @@ package com.idormy.sms.forwarder.entity.setting
import java.io.Serializable import java.io.Serializable
data class UrlSchemeSetting( data class UrlSchemeSetting(
var urlScheme: String, var urlScheme: String = "",
) : Serializable ) : Serializable

View File

@ -8,16 +8,16 @@ data class WeworkAgentSetting(
var corpID: String = "", var corpID: String = "",
val agentID: String = "", val agentID: String = "",
val secret: String = "", val secret: String = "",
val atAll: Boolean? = false, val atAll: Boolean = false,
val toUser: String? = "@all", val toUser: String = "@all",
val toParty: String? = "", val toParty: String = "",
val toTag: String? = "", val toTag: String = "",
val proxyType: Proxy.Type = Proxy.Type.DIRECT, val proxyType: Proxy.Type = Proxy.Type.DIRECT,
val proxyHost: String? = "", val proxyHost: String = "",
val proxyPort: String? = "", val proxyPort: String = "",
val proxyAuthenticator: Boolean? = false, val proxyAuthenticator: Boolean = false,
val proxyUsername: String? = "", val proxyUsername: String = "",
val proxyPassword: String? = "", val proxyPassword: String = "",
val customizeAPI: String = "https://qyapi.weixin.qq.com", val customizeAPI: String = "https://qyapi.weixin.qq.com",
) : Serializable { ) : Serializable {

View File

@ -4,11 +4,11 @@ import com.idormy.sms.forwarder.R
import java.io.Serializable import java.io.Serializable
data class WeworkRobotSetting( data class WeworkRobotSetting(
var webHook: String, var webHook: String = "",
val msgType: String = "text", val msgType: String = "text",
var atAll: Boolean? = false, var atAll: Boolean = false,
var atUserIds: String? = "", var atUserIds: String = "",
var atMobiles: String? = "", var atMobiles: String = "",
) : Serializable { ) : Serializable {
fun getMsgTypeCheckId(): Int { fun getMsgTypeCheckId(): Int {

View File

@ -196,7 +196,7 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
Log.d(TAG, settingVo.toString()) Log.d(TAG, settingVo.toString())
if (settingVo != null) { if (settingVo != null) {
if (!TextUtils.isEmpty(settingVo.mailType)) { if (!TextUtils.isEmpty(settingVo.mailType)) {
mailType = settingVo.mailType.toString() mailType = settingVo.mailType
//TODO: 替换mailType为当前语言避免切换语言后失效历史包袱怎么替换比较优雅 //TODO: 替换mailType为当前语言避免切换语言后失效历史包袱怎么替换比较优雅
if (mailType == "other" || mailType == "其他邮箱" || mailType == "其他郵箱") { if (mailType == "other" || mailType == "其他邮箱" || mailType == "其他郵箱") {
mailType = getString(R.string.other_mail_type) mailType = getString(R.string.other_mail_type)
@ -222,8 +222,8 @@ class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClick
} }
} else { } else {
//兼容旧版本 //兼容旧版本
val emails = settingVo.toEmail?.split(",") val emails = settingVo.toEmail.split(",")
if (!emails.isNullOrEmpty()) { if (emails.isNotEmpty()) {
for (email in emails.toTypedArray()) { for (email in emails.toTypedArray()) {
addRecipientItem(email) addRecipientItem(email)
} }

View File

@ -18,7 +18,15 @@ import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersWeworkAgentBinding import com.idormy.sms.forwarder.databinding.FragmentSendersWeworkAgentBinding
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.CommonUtils
import com.idormy.sms.forwarder.utils.EVENT_TOAST_ERROR
import com.idormy.sms.forwarder.utils.KEY_SENDER_CLONE
import com.idormy.sms.forwarder.utils.KEY_SENDER_ID
import com.idormy.sms.forwarder.utils.KEY_SENDER_TEST
import com.idormy.sms.forwarder.utils.KEY_SENDER_TYPE
import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.XToastUtils
import com.idormy.sms.forwarder.utils.sender.WeworkAgentUtils import com.idormy.sms.forwarder.utils.sender.WeworkAgentUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
@ -34,7 +42,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.net.Proxy import java.net.Proxy
import java.util.* import java.util.Date
@Page(name = "企业微信应用") @Page(name = "企业微信应用")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
@ -125,9 +133,9 @@ class WeworkAgentFragment : BaseFragment<FragmentSendersWeworkAgentBinding?>(),
binding!!.etToUser.setText(settingVo.toUser) binding!!.etToUser.setText(settingVo.toUser)
binding!!.etToParty.setText(settingVo.toParty) binding!!.etToParty.setText(settingVo.toParty)
binding!!.etToTag.setText(settingVo.toTag) binding!!.etToTag.setText(settingVo.toTag)
binding!!.layoutToUser.visibility = if (settingVo.atAll == true) View.GONE else View.VISIBLE binding!!.layoutToUser.visibility = if (settingVo.atAll) View.GONE else View.VISIBLE
binding!!.layoutToParty.visibility = if (settingVo.atAll == true) View.GONE else View.VISIBLE binding!!.layoutToParty.visibility = if (settingVo.atAll) View.GONE else View.VISIBLE
binding!!.layoutToTag.visibility = if (settingVo.atAll == true) View.GONE else View.VISIBLE binding!!.layoutToTag.visibility = if (settingVo.atAll) View.GONE else View.VISIBLE
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId()) binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
binding!!.etProxyHost.setText(settingVo.proxyHost) binding!!.etProxyHost.setText(settingVo.proxyHost)
binding!!.etProxyPort.setText(settingVo.proxyPort) binding!!.etProxyPort.setText(settingVo.proxyPort)

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.interceptor
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Interceptor import okhttp3.Interceptor

View File

@ -1,4 +1,4 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.interceptor
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log

View File

@ -10,6 +10,8 @@ import com.idormy.sms.forwarder.entity.setting.BarkSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.BasicAuthInterceptor
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -33,9 +35,9 @@ class BarkUtils {
) { ) {
//Log.i(TAG, "sendMsg setting:$setting msgInfo:$msgInfo rule:$rule senderIndex:$senderIndex logId:$logId msgId:$msgId") //Log.i(TAG, "sendMsg setting:$setting msgInfo:$msgInfo rule:$rule senderIndex:$senderIndex logId:$logId msgId:$msgId")
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.title, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.title.toString()) msgInfo.getTitleForSend(setting.title)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
@ -60,12 +62,12 @@ class BarkUtils {
msgMap["title"] = title msgMap["title"] = title
msgMap["body"] = content msgMap["body"] = content
msgMap["isArchive"] = 1 msgMap["isArchive"] = 1
if (!TextUtils.isEmpty(setting.group)) msgMap["group"] = setting.group.toString() if (!TextUtils.isEmpty(setting.group)) msgMap["group"] = setting.group
if (!TextUtils.isEmpty(setting.icon)) msgMap["icon"] = setting.icon.toString() if (!TextUtils.isEmpty(setting.icon)) msgMap["icon"] = setting.icon
if (!TextUtils.isEmpty(setting.level)) msgMap["level"] = setting.level.toString() if (!TextUtils.isEmpty(setting.level)) msgMap["level"] = setting.level
if (!TextUtils.isEmpty(setting.sound)) msgMap["sound"] = setting.sound.toString() if (!TextUtils.isEmpty(setting.sound)) msgMap["sound"] = setting.sound
if (!TextUtils.isEmpty(setting.badge)) msgMap["badge"] = setting.badge.toString() if (!TextUtils.isEmpty(setting.badge)) msgMap["badge"] = setting.badge
if (!TextUtils.isEmpty(setting.url)) msgMap["url"] = setting.url.toString() if (!TextUtils.isEmpty(setting.url)) msgMap["url"] = setting.url
//自动复制验证码 //自动复制验证码
val pattern = Regex("(?<!回复)(验证码|授权码|校验码|检验码|确认码|激活码|动态码|安全码|(验证)?代码|校验代码|检验代码|激活代码|确认代码|动态代码|安全代码|登入码|认证码|识别码|短信口令|动态密码|交易码|上网密码|动态口令|随机码|驗證碼|授權碼|校驗碼|檢驗碼|確認碼|激活碼|動態碼|(驗證)?代碼|校驗代碼|檢驗代碼|確認代碼|激活代碼|動態代碼|登入碼|認證碼|識別碼|一次性密码|[Cc][Oo][Dd][Ee]|[Vv]erification)") val pattern = Regex("(?<!回复)(验证码|授权码|校验码|检验码|确认码|激活码|动态码|安全码|(验证)?代码|校验代码|检验代码|激活代码|确认代码|动态代码|安全代码|登入码|认证码|识别码|短信口令|动态密码|交易码|上网密码|动态口令|随机码|驗證碼|授權碼|校驗碼|檢驗碼|確認碼|激活碼|動態碼|(驗證)?代碼|校驗代碼|檢驗代碼|確認代碼|激活代碼|動態代碼|登入碼|認證碼|識別碼|一次性密码|[Cc][Oo][Dd][Ee]|[Vv]erification)")

View File

@ -10,6 +10,7 @@ import com.idormy.sms.forwarder.entity.setting.DingtalkGroupRobotSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -44,7 +45,7 @@ class DingtalkGroupRobotUtils private constructor() {
val timestamp = System.currentTimeMillis() val timestamp = System.currentTimeMillis()
val stringToSign = "$timestamp\n" + setting.secret val stringToSign = "$timestamp\n" + setting.secret
val mac = Mac.getInstance("HmacSHA256") val mac = Mac.getInstance("HmacSHA256")
mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) mac.init(SecretKeySpec(setting.secret.toByteArray(StandardCharsets.UTF_8), "HmacSHA256"))
val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8)) val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8))
val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8") val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8")
requestUrl += "&timestamp=$timestamp&sign=$sign" requestUrl += "&timestamp=$timestamp&sign=$sign"
@ -53,16 +54,16 @@ class DingtalkGroupRobotUtils private constructor() {
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["msgtype"] = setting.msgtype ?: "text" msgMap["msgtype"] = setting.msgtype
val atMap: MutableMap<String, Any> = mutableMapOf() val atMap: MutableMap<String, Any> = mutableMapOf()
msgMap["at"] = atMap msgMap["at"] = atMap
if (setting.atAll == true) { if (setting.atAll) {
atMap["isAtAll"] = true atMap["isAtAll"] = true
} else { } else {
atMap["isAtAll"] = false atMap["isAtAll"] = false
if (!TextUtils.isEmpty(setting.atMobiles)) { if (!TextUtils.isEmpty(setting.atMobiles)) {
val atMobilesArray: Array<String> = setting.atMobiles.toString().replace("[,;]".toRegex(), ",").trim(',').split(',').toTypedArray() val atMobilesArray: Array<String> = setting.atMobiles.replace("[,;]".toRegex(), ",").trim(',').split(',').toTypedArray()
if (atMobilesArray.isNotEmpty()) { if (atMobilesArray.isNotEmpty()) {
atMap["atMobiles"] = atMobilesArray atMap["atMobiles"] = atMobilesArray
for (atMobile in atMobilesArray) { for (atMobile in atMobilesArray) {
@ -73,7 +74,7 @@ class DingtalkGroupRobotUtils private constructor() {
} }
} }
if (!TextUtils.isEmpty(setting.atDingtalkIds)) { if (!TextUtils.isEmpty(setting.atDingtalkIds)) {
val atDingtalkIdsArray: Array<String> = setting.atDingtalkIds.toString().replace("[,;]".toRegex(), ",").trim(',').split(',').toTypedArray() val atDingtalkIdsArray: Array<String> = setting.atDingtalkIds.replace("[,;]".toRegex(), ",").trim(',').split(',').toTypedArray()
if (atDingtalkIdsArray.isNotEmpty()) { if (atDingtalkIdsArray.isNotEmpty()) {
atMap["atDingtalkIds"] = atDingtalkIdsArray atMap["atDingtalkIds"] = atDingtalkIdsArray
for (atDingtalkId in atDingtalkIdsArray) { for (atDingtalkId in atDingtalkIdsArray) {
@ -86,7 +87,7 @@ class DingtalkGroupRobotUtils private constructor() {
} }
if ("markdown" == msgMap["msgtype"]) { if ("markdown" == msgMap["msgtype"]) {
val titleTemplate = setting.titleTemplate.toString() val titleTemplate = setting.titleTemplate
val title = rule?.let { msgInfo.getTitleForSend(titleTemplate, it.regexReplace) } ?: msgInfo.getTitleForSend(titleTemplate) val title = rule?.let { msgInfo.getTitleForSend(titleTemplate, it.regexReplace) } ?: msgInfo.getTitleForSend(titleTemplate)
msgMap["markdown"] = mutableMapOf<String, Any>("title" to title, "text" to content) msgMap["markdown"] = mutableMapOf<String, Any>("title" to title, "text" to content)
} else { } else {

View File

@ -11,6 +11,7 @@ import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.SharedPreference import com.idormy.sms.forwarder.utils.SharedPreference
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -63,25 +64,25 @@ class DingtalkInnerRobotUtils private constructor() {
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost)) throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort.toInt()
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) { if (setting.proxyAuthenticator && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername, setting.proxyPassword)
response.request().newBuilder().header("Proxy-Authorization", credential).build() response.request().newBuilder().header("Proxy-Authorization", credential).build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername, setting.proxyPassword.toCharArray())
} }
}) })
} }
@ -144,9 +145,9 @@ class DingtalkInnerRobotUtils private constructor() {
val msgParam: MutableMap<String, Any> = mutableMapOf() val msgParam: MutableMap<String, Any> = mutableMapOf()
if ("sampleMarkdown" == setting.msgKey) { if ("sampleMarkdown" == setting.msgKey) {
msgParam["title"] = if (rule != null) { msgParam["title"] = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate)
} }
msgParam["text"] = content msgParam["text"] = content
} else { } else {
@ -172,25 +173,25 @@ class DingtalkInnerRobotUtils private constructor() {
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost)) throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort.toInt()
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) { if (setting.proxyAuthenticator && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername, setting.proxyPassword)
response.request().newBuilder().header("Proxy-Authorization", credential).build() response.request().newBuilder().header("Proxy-Authorization", credential).build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername, setting.proxyPassword.toCharArray())
} }
}) })
} }

View File

@ -38,9 +38,9 @@ class EmailUtils {
msgId: Long = 0L msgId: Long = 0L
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.title, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.title.toString()) msgInfo.getTitleForSend(setting.title)
} }
val message: String = if (rule != null) { val message: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
@ -144,21 +144,21 @@ class EmailUtils {
val job = launch(Dispatchers.IO) { val job = launch(Dispatchers.IO) {
try { try {
// 设置邮件参数 // 设置邮件参数
val host = setting.host.toString() val host = setting.host
val port = setting.port.toString() val port = setting.port
val from = setting.fromEmail.toString() val from = setting.fromEmail
val password = setting.pwd.toString() val password = setting.pwd
val nickname = msgInfo.getTitleForSend(setting.nickname.toString()) val nickname = msgInfo.getTitleForSend(setting.nickname)
setting.recipients.ifEmpty { setting.recipients.ifEmpty {
//兼容旧的设置 //兼容旧的设置
val emails = setting.toEmail.toString().replace("[,;]".toRegex(), ",").trim(',').split(',') val emails = setting.toEmail.replace("[,;]".toRegex(), ",").trim(',').split(',')
emails.forEach { emails.forEach {
setting.recipients[it] = Pair("", "") setting.recipients[it] = Pair("", "")
} }
} }
val content = message.replace("\n", "<br>") val content = message.replace("\n", "<br>")
val openSSL = setting.ssl == true val openSSL = setting.ssl
val startTls = setting.startTls == true val startTls = setting.startTls
//发件人S/MIME私钥用于签名 //发件人S/MIME私钥用于签名
var signingPrivateKey: PrivateKey? = null var signingPrivateKey: PrivateKey? = null
@ -167,17 +167,17 @@ class EmailUtils {
var senderPGPSecretKeyRing: PGPSecretKeyRing? = null var senderPGPSecretKeyRing: PGPSecretKeyRing? = null
var senderPGPSecretKeyPassword = "" var senderPGPSecretKeyPassword = ""
if (!setting.keystore.isNullOrEmpty() && !setting.password.isNullOrEmpty()) { if (setting.keystore.isNotEmpty() && setting.password.isNotEmpty()) {
try { try {
val keystoreStream = if (setting.keystore!!.startsWith("/")) { val keystoreStream = if (setting.keystore.startsWith("/")) {
FileInputStream(setting.keystore) FileInputStream(setting.keystore)
} else { } else {
val decodedBytes = Base64.decode(setting.keystore!!) val decodedBytes = Base64.decode(setting.keystore)
ByteArrayInputStream(decodedBytes) ByteArrayInputStream(decodedBytes)
} }
when (setting.encryptionProtocol) { when (setting.encryptionProtocol) {
"S/MIME" -> { "S/MIME" -> {
val keystorePassword = setting.password.toString() val keystorePassword = setting.password
val keyStore = KeyStore.getInstance("PKCS12") val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(keystoreStream, keystorePassword.toCharArray()) keyStore.load(keystoreStream, keystorePassword.toCharArray())
val privateKeyAlias = keyStore.aliases().toList().first { keyStore.isKeyEntry(it) } val privateKeyAlias = keyStore.aliases().toList().first { keyStore.isKeyEntry(it) }
@ -187,7 +187,7 @@ class EmailUtils {
"OpenPGP" -> { "OpenPGP" -> {
senderPGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(keystoreStream) senderPGPSecretKeyRing = PGPainless.readKeyRing().secretKeyRing(keystoreStream)
senderPGPSecretKeyPassword = setting.password.toString() senderPGPSecretKeyPassword = setting.password
} }
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -11,6 +11,7 @@ import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.SharedPreference import com.idormy.sms.forwarder.utils.SharedPreference
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException

View File

@ -10,6 +10,7 @@ import com.idormy.sms.forwarder.entity.setting.FeishuSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -89,9 +90,9 @@ class FeishuUtils private constructor() {
) { ) {
val from: String = msgInfo.from val from: String = msgInfo.from
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
@ -103,7 +104,6 @@ class FeishuUtils private constructor() {
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
if (setting.secret != null) {
val timestamp = System.currentTimeMillis() / 1000 val timestamp = System.currentTimeMillis() / 1000
val stringToSign = "$timestamp\n" + setting.secret val stringToSign = "$timestamp\n" + setting.secret
Log.i(TAG, "stringToSign = $stringToSign") Log.i(TAG, "stringToSign = $stringToSign")
@ -116,11 +116,10 @@ class FeishuUtils private constructor() {
msgMap["timestamp"] = timestamp msgMap["timestamp"] = timestamp
msgMap["sign"] = sign msgMap["sign"] = sign
}
//组装报文 //组装报文
val requestMsg: String val requestMsg: String
if (setting.msgType == null || setting.msgType == "interactive") { if (setting.msgType == "interactive") {
msgMap["msg_type"] = "interactive" msgMap["msg_type"] = "interactive"
if (TextUtils.isEmpty(setting.messageCard.trim())) { if (TextUtils.isEmpty(setting.messageCard.trim())) {
msgMap["card"] = "{{CARD_BODY}}" msgMap["card"] = "{{CARD_BODY}}"

View File

@ -8,6 +8,8 @@ import com.idormy.sms.forwarder.entity.setting.GotifySetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.BasicAuthInterceptor
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -26,9 +28,9 @@ class GotifyUtils {
msgId: Long = 0L msgId: Long = 0L
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.title, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.title.toString()) msgInfo.getTitleForSend(setting.title)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)

View File

@ -10,6 +10,7 @@ import com.idormy.sms.forwarder.entity.setting.PushplusSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -29,9 +30,9 @@ class PushplusUtils private constructor() {
msgId: Long = 0L msgId: Long = 0L
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
@ -47,16 +48,16 @@ class PushplusUtils private constructor() {
msgMap["content"] = content msgMap["content"] = content
if (!TextUtils.isEmpty(title)) msgMap["title"] = title if (!TextUtils.isEmpty(title)) msgMap["title"] = title
if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template.toString() if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template
if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic.toString() if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic
if (setting.website == getString(R.string.pushplus_plus)) { if (setting.website == getString(R.string.pushplus_plus)) {
if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel.toString() if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel
if (!TextUtils.isEmpty(setting.webhook)) msgMap["webhook"] = setting.webhook.toString() if (!TextUtils.isEmpty(setting.webhook)) msgMap["webhook"] = setting.webhook
if (!TextUtils.isEmpty(setting.callbackUrl)) msgMap["callbackUrl"] = setting.callbackUrl.toString() if (!TextUtils.isEmpty(setting.callbackUrl)) msgMap["callbackUrl"] = setting.callbackUrl
if (!TextUtils.isEmpty(setting.validTime)) { if (!TextUtils.isEmpty(setting.validTime)) {
val validTime = setting.validTime?.toInt() val validTime = setting.validTime.toInt()
if (validTime != null && validTime > 0) { if (validTime > 0) {
msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L
} }
} }

View File

@ -9,6 +9,7 @@ import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -27,9 +28,9 @@ class ServerchanUtils {
msgId: Long = 0L msgId: Long = 0L
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)

View File

@ -2,13 +2,13 @@ package com.idormy.sms.forwarder.utils.sender
import android.Manifest import android.Manifest
import android.content.pm.PackageManager import android.content.pm.PackageManager
import com.idormy.sms.forwarder.utils.Log
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.SmsSetting import com.idormy.sms.forwarder.entity.setting.SmsSetting
import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.PhoneUtils import com.idormy.sms.forwarder.utils.PhoneUtils
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
@ -30,7 +30,7 @@ class SmsUtils {
msgId: Long = 0L msgId: Long = 0L
) { ) {
//仅当无网络时启用 && 判断是否真实有网络 //仅当无网络时启用 && 判断是否真实有网络
if (setting.onlyNoNetwork == true && NetworkUtils.isHaveInternet() && NetworkUtils.isAvailableByPing()) { if (setting.onlyNoNetwork && NetworkUtils.isHaveInternet() && NetworkUtils.isAvailableByPing()) {
SendUtils.updateLogs(logId, 0, getString(R.string.OnlyNoNetwork)) SendUtils.updateLogs(logId, 0, getString(R.string.OnlyNoNetwork))
SendUtils.senderLogic(0, msgInfo, rule, senderIndex, msgId) SendUtils.senderLogic(0, msgInfo, rule, senderIndex, msgId)
return return

View File

@ -57,7 +57,7 @@ class SocketUtils {
if (!TextUtils.isEmpty(setting.secret)) { if (!TextUtils.isEmpty(setting.secret)) {
val stringToSign = "$timestamp\n" + setting.secret val stringToSign = "$timestamp\n" + setting.secret
val mac = Mac.getInstance("HmacSHA256") val mac = Mac.getInstance("HmacSHA256")
mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) mac.init(SecretKeySpec(setting.secret.toByteArray(StandardCharsets.UTF_8), "HmacSHA256"))
val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8)) val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8))
sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8") sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8")
} }
@ -87,7 +87,7 @@ class SocketUtils {
// 从服务器接收响应 // 从服务器接收响应
val response = input.readLine() val response = input.readLine()
Log.d(TAG, "从服务器接收的响应: $response") Log.d(TAG, "从服务器接收的响应: $response")
val status = if (!setting.response.isNullOrEmpty() && !response.contains(setting.response)) 0 else 2 val status = if (setting.response.isNotEmpty() && !response.contains(setting.response)) 0 else 2
SendUtils.updateLogs(logId, status, response) SendUtils.updateLogs(logId, status, response)
SendUtils.senderLogic(status, msgInfo, rule, senderIndex, msgId) SendUtils.senderLogic(status, msgInfo, rule, senderIndex, msgId)
} catch (e: Exception) { } catch (e: Exception) {
@ -143,7 +143,7 @@ class SocketUtils {
override fun messageArrived(topic: String?, inMessage: MqttMessage?) { override fun messageArrived(topic: String?, inMessage: MqttMessage?) {
val payload = inMessage?.payload?.toString(Charset.forName(setting.inCharset)) val payload = inMessage?.payload?.toString(Charset.forName(setting.inCharset))
Log.d(TAG, "Received message on topic $topic: $payload") Log.d(TAG, "Received message on topic $topic: $payload")
val status = if (!setting.response.isNullOrEmpty() && !payload?.contains(setting.response)!!) 0 else 2 val status = if (setting.response.isNotEmpty() && !payload?.contains(setting.response)!!) 0 else 2
SendUtils.updateLogs(logId, status, payload.toString()) SendUtils.updateLogs(logId, status, payload.toString())
SendUtils.senderLogic(status, msgInfo, rule, senderIndex, msgId) SendUtils.senderLogic(status, msgInfo, rule, senderIndex, msgId)
} }

View File

@ -10,6 +10,7 @@ import com.idormy.sms.forwarder.entity.setting.TelegramSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -37,7 +38,7 @@ class TelegramUtils private constructor() {
logId: Long = 0L, logId: Long = 0L,
msgId: Long = 0L msgId: Long = 0L
) { ) {
if (setting.method == null || setting.method == "POST") { if (setting.method == "POST") {
msgInfo.content = htmlEncode(msgInfo.content) msgInfo.content = htmlEncode(msgInfo.content)
msgInfo.simInfo = htmlEncode(msgInfo.simInfo) msgInfo.simInfo = htmlEncode(msgInfo.simInfo)
} }
@ -55,7 +56,7 @@ class TelegramUtils private constructor() {
} }
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val request = if (setting.method != null && setting.method == "GET") { val request = if (setting.method == "GET") {
requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8") requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8")
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
XHttp.get(requestUrl) XHttp.get(requestUrl)
@ -80,21 +81,20 @@ class TelegramUtils private constructor() {
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost)) throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort.toInt()
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername, setting.proxyPassword)
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
@ -102,7 +102,7 @@ class TelegramUtils private constructor() {
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername, setting.proxyPassword.toCharArray())
} }
}) })
} }

View File

@ -11,6 +11,7 @@ import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.SharedPreference import com.idormy.sms.forwarder.utils.SharedPreference
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -60,25 +61,25 @@ class WeworkAgentUtils private constructor() {
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost)) throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort.toInt()
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) { if (setting.proxyAuthenticator && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername, setting.proxyPassword)
response.request().newBuilder().header("Proxy-Authorization", credential).build() response.request().newBuilder().header("Proxy-Authorization", credential).build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername, setting.proxyPassword.toCharArray())
} }
}) })
} }
@ -135,9 +136,9 @@ class WeworkAgentUtils private constructor() {
} }
val textMsgMap: MutableMap<String, Any> = mutableMapOf() val textMsgMap: MutableMap<String, Any> = mutableMapOf()
textMsgMap["touser"] = setting.toUser.toString() textMsgMap["touser"] = setting.toUser
textMsgMap["toparty"] = setting.toParty.toString() textMsgMap["toparty"] = setting.toParty
textMsgMap["totag"] = setting.toTag.toString() textMsgMap["totag"] = setting.toTag
textMsgMap["msgtype"] = "text" textMsgMap["msgtype"] = "text"
textMsgMap["agentid"] = setting.agentID textMsgMap["agentid"] = setting.agentID
val textText: MutableMap<String, Any> = mutableMapOf() val textText: MutableMap<String, Any> = mutableMapOf()
@ -160,25 +161,25 @@ class WeworkAgentUtils private constructor() {
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost)) throw Exception(String.format(getString(R.string.invalid_proxy_host), proxyHost))
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort.toInt()
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) { if (setting.proxyAuthenticator && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername, setting.proxyPassword)
response.request().newBuilder().header("Proxy-Authorization", credential).build() response.request().newBuilder().header("Proxy-Authorization", credential).build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername, setting.proxyPassword.toCharArray())
} }
}) })
} }

View File

@ -8,6 +8,7 @@ import com.idormy.sms.forwarder.entity.setting.WeworkRobotSetting
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.interceptor.LoggingInterceptor
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@ -43,14 +44,14 @@ class WeworkRobotUtils private constructor() {
if (setting.msgType == "markdown") { if (setting.msgType == "markdown") {
msgMap["markdown"] = contextMap msgMap["markdown"] = contextMap
} else { } else {
if (setting.atAll == true) { if (setting.atAll) {
contextMap["mentioned_list"] = arrayListOf("@all") contextMap["mentioned_list"] = arrayListOf("@all")
} else { } else {
if (!setting.atUserIds.isNullOrEmpty()) { if (setting.atUserIds.isNotEmpty()) {
contextMap["mentioned_list"] = setting.atUserIds!!.split(",") contextMap["mentioned_list"] = setting.atUserIds.split(",")
} }
if (!setting.atMobiles.isNullOrEmpty()) { if (setting.atMobiles.isNotEmpty()) {
contextMap["mentioned_mobile_list"] = setting.atMobiles!!.split(",") contextMap["mentioned_mobile_list"] = setting.atMobiles.split(",")
} }
} }
msgMap["text"] = contextMap msgMap["text"] = contextMap

View File

@ -86,7 +86,7 @@ class SendWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
if (SettingUtils.enableSilentPeriodLogs) { if (SettingUtils.enableSilentPeriodLogs) {
isSilentPeriod = true isSilentPeriod = true
} else { } else {
Log.e("SendWorker", "免打扰(禁用转发)时间段") Log.e(TAG, "免打扰(禁用转发)时间段")
return@withContext Result.failure(workDataOf("send" to "failed")) return@withContext Result.failure(workDataOf("send" to "failed"))
} }
} }
@ -98,9 +98,9 @@ class SendWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
val key = CipherUtils.md5(msgInfo.type + msgInfo.from + msgInfo.content) val key = CipherUtils.md5(msgInfo.type + msgInfo.from + msgInfo.content)
val timestamp: Long = System.currentTimeMillis() val timestamp: Long = System.currentTimeMillis()
var timestampPrev: Long by HistoryUtils(key, timestamp) var timestampPrev: Long by HistoryUtils(key, timestamp)
Log.d("SendWorker", "duplicateMessagesLimits=$duplicateMessagesLimits, timestamp=$timestamp, timestampPrev=$timestampPrev, msgInfo=$msgInfo") Log.d(TAG, "duplicateMessagesLimits=$duplicateMessagesLimits, timestamp=$timestamp, timestampPrev=$timestampPrev, msgInfo=$msgInfo")
if (timestampPrev != timestamp && timestamp - timestampPrev <= duplicateMessagesLimits) { if (timestampPrev != timestamp && timestamp - timestampPrev <= duplicateMessagesLimits) {
Log.e("SendWorker", "过滤重复消息机制") Log.e(TAG, "过滤重复消息机制")
timestampPrev = timestamp timestampPrev = timestamp
return@withContext Result.failure(workDataOf("send" to "failed")) return@withContext Result.failure(workDataOf("send" to "failed"))
} }
@ -114,7 +114,7 @@ class SendWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
val ruleListMatched: MutableList<Rule> = mutableListOf() val ruleListMatched: MutableList<Rule> = mutableListOf()
for (rule in ruleList) { for (rule in ruleList) {
Log.d("SendWorker", rule.toString()) Log.d(TAG, rule.toString())
if (rule.checkMsg(msgInfo)) ruleListMatched.add(rule) if (rule.checkMsg(msgInfo)) ruleListMatched.add(rule)
} }
if (ruleListMatched.isEmpty()) { if (ruleListMatched.isEmpty()) {
@ -137,7 +137,7 @@ class SendWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Log.e("SendWorker", "SendWorker error: ${e.message}") Log.e(TAG, "SendWorker error: ${e.message}")
return@withContext Result.failure(workDataOf("send" to e.message.toString())) return@withContext Result.failure(workDataOf("send" to e.message.toString()))
} }