diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/BarkUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/BarkUtils.kt index 54780101..fb98a91a 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/BarkUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/BarkUtils.kt @@ -1,111 +1,111 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.BarkResult -import com.idormy.sms.forwarder.entity.setting.BarkSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import java.util.regex.Pattern - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") -class BarkUtils { - companion object { - - private val TAG: String = BarkUtils::class.java.simpleName - - fun sendMsg( - setting: BarkSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val title: String = if (rule != null) { - msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) - } else { - msgInfo.getTitleForSend(setting.title.toString()) - } - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val requestUrl: String = setting.server //推送地址 - Log.i(TAG, "requestUrl:$requestUrl") - - //支持HTTP基本认证(Basic Authentication) - val regex = "^(https?://)([^:]+):([^@]+)@(.+)" - val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList().flatMap(MatchResult::groupValues) - Log.i(TAG, "matches = $matches") - val request = if (matches.isNotEmpty()) { - XHttp.post(matches[1] + matches[4]).addInterceptor(BasicAuthInterceptor(matches[2], matches[3])) - } else { - XHttp.post(requestUrl) - } - - request.params("title", title) - .params("body", content) - .params("isArchive", 1) - if (!TextUtils.isEmpty(setting.group)) request.params("group", setting.group) - if (!TextUtils.isEmpty(setting.icon)) request.params("icon", setting.icon) - if (!TextUtils.isEmpty(setting.level)) request.params("level", setting.level) - if (!TextUtils.isEmpty(setting.sound)) request.params("sound", setting.sound) - if (!TextUtils.isEmpty(setting.badge)) request.params("badge", setting.badge) - if (!TextUtils.isEmpty(setting.url)) request.params("url", setting.url) - - val isCode: Int = content.indexOf("验证码") - val isPassword: Int = content.indexOf("动态密码") - val isPassword2: Int = content.indexOf("短信密码") - if (isCode != -1 || isPassword != -1 || isPassword2 != -1) { - val p = Pattern.compile("(\\d{4,6})") - val m = p.matcher(content) - if (m.find()) { - println(m.group()) - request.params("automaticallyCopy", "1") - request.params("copy", m.group()) - } - } - - request.ignoreHttpsCert() //忽略https证书 - .keepJson(true) - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, BarkResult::class.java) - if (resp.code == 200L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - fun sendMsg(setting: BarkSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.BarkResult +import com.idormy.sms.forwarder.entity.setting.BarkSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import java.util.regex.Pattern + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") +class BarkUtils { + companion object { + + private val TAG: String = BarkUtils::class.java.simpleName + + fun sendMsg( + setting: BarkSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val title: String = if (rule != null) { + msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) + } else { + msgInfo.getTitleForSend(setting.title.toString()) + } + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val requestUrl: String = setting.server //推送地址 + Log.i(TAG, "requestUrl:$requestUrl") + + //支持HTTP基本认证(Basic Authentication) + val regex = "^(https?://)([^:]+):([^@]+)@(.+)" + val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList().flatMap(MatchResult::groupValues) + Log.i(TAG, "matches = $matches") + val request = if (matches.isNotEmpty()) { + XHttp.post(matches[1] + matches[4]).addInterceptor(BasicAuthInterceptor(matches[2], matches[3])) + } else { + XHttp.post(requestUrl) + } + + request.params("title", title) + .params("body", content) + .params("isArchive", 1) + if (!TextUtils.isEmpty(setting.group)) request.params("group", setting.group) + if (!TextUtils.isEmpty(setting.icon)) request.params("icon", setting.icon) + if (!TextUtils.isEmpty(setting.level)) request.params("level", setting.level) + if (!TextUtils.isEmpty(setting.sound)) request.params("sound", setting.sound) + if (!TextUtils.isEmpty(setting.badge)) request.params("badge", setting.badge) + if (!TextUtils.isEmpty(setting.url)) request.params("url", setting.url) + + val isCode: Int = content.indexOf("验证码") + val isPassword: Int = content.indexOf("动态密码") + val isPassword2: Int = content.indexOf("短信密码") + if (isCode != -1 || isPassword != -1 || isPassword2 != -1) { + val p = Pattern.compile("(\\d{4,6})") + val m = p.matcher(content) + if (m.find()) { + println(m.group()) + request.params("automaticallyCopy", "1") + request.params("copy", m.group()) + } + } + + request.ignoreHttpsCert() //忽略https证书 + .keepJson(true) + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, BarkResult::class.java) + if (resp?.code == 200L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + fun sendMsg(setting: BarkSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkGroupRobotUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkGroupRobotUtils.kt index d7818e98..0345507d 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkGroupRobotUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkGroupRobotUtils.kt @@ -1,122 +1,122 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Base64 -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.DingtalkResult -import com.idormy.sms.forwarder.entity.setting.DingtalkGroupRobotSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import java.net.URLEncoder -import java.nio.charset.StandardCharsets -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec - -//钉钉群自定义机器人 -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class DingtalkGroupRobotUtils private constructor() { - companion object { - - private val TAG: String = DingtalkGroupRobotUtils::class.java.simpleName - - fun sendMsg( - setting: DingtalkGroupRobotSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - var requestUrl = if (setting.token.startsWith("http")) setting.token else "https://oapi.dingtalk.com/robot/send?access_token=" + setting.token - - if (!TextUtils.isEmpty(setting.secret)) { - val timestamp = System.currentTimeMillis() - val stringToSign = "$timestamp\n" + setting.secret - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) - val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8)) - val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8") - requestUrl += "×tamp=$timestamp&sign=$sign" - } - - Log.i(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - msgMap["msgtype"] = "text" - - val textText: MutableMap = mutableMapOf() - textText["content"] = content - msgMap["text"] = textText - - val atMap: MutableMap = mutableMapOf() - msgMap["at"] = atMap - if (setting.atAll == true) { - atMap["isAtAll"] = true - } else { - atMap["isAtAll"] = false - if (!TextUtils.isEmpty(setting.atMobiles)) { - val atMobilesArray: Array? = setting.atMobiles?.split(",".toRegex())?.toTypedArray() - if (atMobilesArray != null) { - val atMobilesList: MutableList = ArrayList() - for (atMobile in atMobilesArray) { - if (TextUtils.isDigitsOnly(atMobile)) { - atMobilesList.add(atMobile) - } - } - if (atMobilesList.isNotEmpty()) { - atMap["atMobiles"] = atMobilesList - } - } - } - } - - val requestMsg: String = Gson().toJson(msgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .keepJson(true) - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, DingtalkResult::class.java) - if (resp.errcode == 0L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - fun sendMsg(setting: DingtalkGroupRobotSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Base64 +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.DingtalkResult +import com.idormy.sms.forwarder.entity.setting.DingtalkGroupRobotSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import java.net.URLEncoder +import java.nio.charset.StandardCharsets +import javax.crypto.Mac +import javax.crypto.spec.SecretKeySpec + +//钉钉群自定义机器人 +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class DingtalkGroupRobotUtils private constructor() { + companion object { + + private val TAG: String = DingtalkGroupRobotUtils::class.java.simpleName + + fun sendMsg( + setting: DingtalkGroupRobotSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + var requestUrl = if (setting.token.startsWith("http")) setting.token else "https://oapi.dingtalk.com/robot/send?access_token=" + setting.token + + if (!TextUtils.isEmpty(setting.secret)) { + val timestamp = System.currentTimeMillis() + val stringToSign = "$timestamp\n" + setting.secret + val mac = Mac.getInstance("HmacSHA256") + mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) + val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8)) + val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8") + requestUrl += "×tamp=$timestamp&sign=$sign" + } + + Log.i(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + msgMap["msgtype"] = "text" + + val textText: MutableMap = mutableMapOf() + textText["content"] = content + msgMap["text"] = textText + + val atMap: MutableMap = mutableMapOf() + msgMap["at"] = atMap + if (setting.atAll == true) { + atMap["isAtAll"] = true + } else { + atMap["isAtAll"] = false + if (!TextUtils.isEmpty(setting.atMobiles)) { + val atMobilesArray: Array? = setting.atMobiles?.split(",".toRegex())?.toTypedArray() + if (atMobilesArray != null) { + val atMobilesList: MutableList = ArrayList() + for (atMobile in atMobilesArray) { + if (TextUtils.isDigitsOnly(atMobile)) { + atMobilesList.add(atMobile) + } + } + if (atMobilesList.isNotEmpty()) { + atMap["atMobiles"] = atMobilesList + } + } + } + } + + val requestMsg: String = Gson().toJson(msgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .keepJson(true) + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, DingtalkResult::class.java) + if (resp?.errcode == 0L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + fun sendMsg(setting: DingtalkGroupRobotSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkInnerRobotUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkInnerRobotUtils.kt index 4cb61627..0cf14001 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkInnerRobotUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/DingtalkInnerRobotUtils.kt @@ -1,242 +1,242 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.R -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.DingtalkInnerRobotResult -import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting -import com.idormy.sms.forwarder.utils.MMKVUtils -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import com.xuexiang.xui.utils.ResUtils.getString -import com.xuexiang.xutil.net.NetworkUtils -import okhttp3.Credentials -import okhttp3.Response -import okhttp3.Route -import java.net.Authenticator -import java.net.InetSocketAddress -import java.net.PasswordAuthentication -import java.net.Proxy - -//钉钉企业内机器人 -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class DingtalkInnerRobotUtils private constructor() { - companion object { - - private val TAG: String = DingtalkInnerRobotUtils::class.java.simpleName - - fun sendMsg( - setting: DingtalkInnerRobotSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - - val accessToken: String? = MMKVUtils.getString("accessToken_" + setting.agentID, "") - val expiresIn: Long = MMKVUtils.getLong("expiresIn_" + setting.agentID, 0L) - if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { - return sendTextMsg(setting, msgInfo, rule, logId) - } - - val requestUrl = "https://api.dingtalk.com/v1.0/oauth2/accessToken" - Log.d(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - msgMap["appKey"] = setting.appKey - msgMap["appSecret"] = setting.appSecret - val requestMsg: String = Gson().toJson(msgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - val request = XHttp.post(requestUrl) - - //设置代理 - if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) - && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) - ) { - //代理服务器的IP和端口号 - Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") - val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) - if (!NetworkUtils.isIP(proxyHost)) { - throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") - } - val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 - - Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") - request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) - - //代理的鉴权账号密码 - if (setting.proxyAuthenticator == true - && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) - ) { - Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") - - if (setting.proxyType == Proxy.Type.HTTP) { - request.okproxyAuthenticator { _: Route?, response: Response -> - //设置代理服务器账号密码 - val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } else { - Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) - } - }) - } - } - } - - request.upJson(requestMsg) - .keepJson(true) - .ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) - if (!TextUtils.isEmpty(resp.accessToken)) { - MMKVUtils.put("accessToken_" + setting.agentID, resp.accessToken) - MMKVUtils.put("expiresIn_" + setting.agentID, System.currentTimeMillis() + ((resp.expireIn ?: 7200) - 120) * 1000L) //提前2分钟过期 - sendTextMsg(setting, msgInfo, rule, logId) - } else { - SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) - } - } - - }) - - } - - //发送文本消息 - private fun sendTextMsg( - setting: DingtalkInnerRobotSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val requestUrl = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" - Log.d(TAG, "requestUrl:$requestUrl") - - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val msgParam: MutableMap = mutableMapOf() - if ("sampleMarkdown" == setting.msgKey) { - msgParam["title"] = if (rule != null) { - msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) - } else { - msgInfo.getTitleForSend(setting.titleTemplate.toString()) - } - msgParam["text"] = content - } else { - msgParam["content"] = content - } - - val textMsgMap: MutableMap = mutableMapOf() - textMsgMap["robotCode"] = setting.appKey - textMsgMap["userIds"] = setting.userIds.split('|').toTypedArray() - textMsgMap["msgKey"] = setting.msgKey - textMsgMap["msgParam"] = Gson().toJson(msgParam) - - val requestMsg: String = Gson().toJson(textMsgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - val request = XHttp.post(requestUrl) - - //设置代理 - if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) - && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) - ) { - //代理服务器的IP和端口号 - Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") - val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) - if (!NetworkUtils.isIP(proxyHost)) { - throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") - } - val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 - - Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") - request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) - - //代理的鉴权账号密码 - if (setting.proxyAuthenticator == true - && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) - ) { - Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") - - if (setting.proxyType == Proxy.Type.HTTP) { - request.okproxyAuthenticator { _: Route?, response: Response -> - //设置代理服务器账号密码 - val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } else { - Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) - } - }) - } - } - } - - request.upJson(requestMsg) - .headers("x-acs-dingtalk-access-token", MMKVUtils.getString("accessToken_" + setting.agentID, "")) - .keepJson(true) - .ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) - if (!TextUtils.isEmpty(resp.processQueryKey)) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - } - - fun sendMsg(setting: DingtalkInnerRobotSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.DingtalkInnerRobotResult +import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting +import com.idormy.sms.forwarder.utils.MMKVUtils +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import com.xuexiang.xui.utils.ResUtils.getString +import com.xuexiang.xutil.net.NetworkUtils +import okhttp3.Credentials +import okhttp3.Response +import okhttp3.Route +import java.net.Authenticator +import java.net.InetSocketAddress +import java.net.PasswordAuthentication +import java.net.Proxy + +//钉钉企业内机器人 +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class DingtalkInnerRobotUtils private constructor() { + companion object { + + private val TAG: String = DingtalkInnerRobotUtils::class.java.simpleName + + fun sendMsg( + setting: DingtalkInnerRobotSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + + val accessToken: String? = MMKVUtils.getString("accessToken_" + setting.agentID, "") + val expiresIn: Long = MMKVUtils.getLong("expiresIn_" + setting.agentID, 0L) + if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { + return sendTextMsg(setting, msgInfo, rule, logId) + } + + val requestUrl = "https://api.dingtalk.com/v1.0/oauth2/accessToken" + Log.d(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + msgMap["appKey"] = setting.appKey + msgMap["appSecret"] = setting.appSecret + val requestMsg: String = Gson().toJson(msgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + val request = XHttp.post(requestUrl) + + //设置代理 + if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) + && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) + ) { + //代理服务器的IP和端口号 + Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") + val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) + if (!NetworkUtils.isIP(proxyHost)) { + throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") + } + val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 + + Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") + request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) + + //代理的鉴权账号密码 + if (setting.proxyAuthenticator == true + && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) + ) { + Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") + + if (setting.proxyType == Proxy.Type.HTTP) { + request.okproxyAuthenticator { _: Route?, response: Response -> + //设置代理服务器账号密码 + val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } else { + Authenticator.setDefault(object : Authenticator() { + override fun getPasswordAuthentication(): PasswordAuthentication { + return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) + } + }) + } + } + } + + request.upJson(requestMsg) + .keepJson(true) + .ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) + if (!TextUtils.isEmpty(resp?.accessToken)) { + MMKVUtils.put("accessToken_" + setting.agentID, resp.accessToken) + MMKVUtils.put("expiresIn_" + setting.agentID, System.currentTimeMillis() + ((resp.expireIn ?: 7200) - 120) * 1000L) //提前2分钟过期 + sendTextMsg(setting, msgInfo, rule, logId) + } else { + SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) + } + } + + }) + + } + + //发送文本消息 + private fun sendTextMsg( + setting: DingtalkInnerRobotSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val requestUrl = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" + Log.d(TAG, "requestUrl:$requestUrl") + + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val msgParam: MutableMap = mutableMapOf() + if ("sampleMarkdown" == setting.msgKey) { + msgParam["title"] = if (rule != null) { + msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) + } else { + msgInfo.getTitleForSend(setting.titleTemplate.toString()) + } + msgParam["text"] = content + } else { + msgParam["content"] = content + } + + val textMsgMap: MutableMap = mutableMapOf() + textMsgMap["robotCode"] = setting.appKey + textMsgMap["userIds"] = setting.userIds.split('|').toTypedArray() + textMsgMap["msgKey"] = setting.msgKey + textMsgMap["msgParam"] = Gson().toJson(msgParam) + + val requestMsg: String = Gson().toJson(textMsgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + val request = XHttp.post(requestUrl) + + //设置代理 + if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) + && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) + ) { + //代理服务器的IP和端口号 + Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") + val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) + if (!NetworkUtils.isIP(proxyHost)) { + throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") + } + val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 + + Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") + request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) + + //代理的鉴权账号密码 + if (setting.proxyAuthenticator == true + && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) + ) { + Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") + + if (setting.proxyType == Proxy.Type.HTTP) { + request.okproxyAuthenticator { _: Route?, response: Response -> + //设置代理服务器账号密码 + val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } else { + Authenticator.setDefault(object : Authenticator() { + override fun getPasswordAuthentication(): PasswordAuthentication { + return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) + } + }) + } + } + } + + request.upJson(requestMsg) + .headers("x-acs-dingtalk-access-token", MMKVUtils.getString("accessToken_" + setting.agentID, "")) + .keepJson(true) + .ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) + if (!TextUtils.isEmpty(resp?.processQueryKey)) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + } + + fun sendMsg(setting: DingtalkInnerRobotSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuAppUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuAppUtils.kt index 10eb5d07..6697f501 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuAppUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuAppUtils.kt @@ -1,163 +1,163 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.R -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.FeishuAppResult -import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting -import com.idormy.sms.forwarder.utils.MMKVUtils -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import com.xuexiang.xui.utils.ResUtils.getString - -//飞书企业应用 -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class FeishuAppUtils private constructor() { - companion object { - - private val TAG: String = FeishuAppUtils::class.java.simpleName - - fun sendMsg( - setting: FeishuAppSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - - val accessToken: String? = MMKVUtils.getString("feishu_access_token_" + setting.appId, "") - val expiresIn: Long = MMKVUtils.getLong("feishu_expires_in_" + setting.appId, 0L) - if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { - return sendTextMsg(setting, msgInfo, rule, logId) - } - - val requestUrl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" - Log.d(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - msgMap["app_id"] = setting.appId - msgMap["app_secret"] = setting.appSecret - val requestMsg: String = Gson().toJson(msgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .keepJson(true) - .ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, FeishuAppResult::class.java) - if (!TextUtils.isEmpty(resp.tenant_access_token)) { - MMKVUtils.put("feishu_access_token_" + setting.appId, resp.tenant_access_token) - MMKVUtils.put("feishu_expires_in_" + setting.appId, System.currentTimeMillis() + ((resp.expire ?: 7010) - 120) * 1000L) //提前2分钟过期 - sendTextMsg(setting, msgInfo, rule, logId) - } else { - SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) - } - } - - }) - - } - - //发送文本消息 - private fun sendTextMsg( - setting: FeishuAppSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" - Log.d(TAG, "requestUrl:$requestUrl") - - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val msgContent = if ("interactive" == setting.msgType) { - val title = if (rule != null) { - msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace) - } else { - msgInfo.getTitleForSend(setting.titleTemplate) - } - "{\"elements\":[{\"tag\":\"markdown\",\"content\":\"**[{{MSG_TITLE}}]({{MSG_URL}})**\\n --------------\\n{{MSG_CONTENT}}\"}]}".trimIndent().replace("{{MSG_TITLE}}", jsonInnerStr(title)) - .replace("{{MSG_URL}}", jsonInnerStr("https://github.com/pppscn/SmsForwarder")) - .replace("{{MSG_CONTENT}}", jsonInnerStr(content)) - } else { - "{\"text\":\"{{MSG_CONTENT}}\"}".trimIndent().replace("{{MSG_CONTENT}}", jsonInnerStr(content)) - } - - val textMsgMap: MutableMap = mutableMapOf() - textMsgMap["receive_id"] = setting.receiveId - textMsgMap["msg_type"] = setting.msgType - textMsgMap["content"] = msgContent - - val requestMsg: String = Gson().toJson(textMsgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .headers("Authorization", "Bearer " + MMKVUtils.getString("feishu_access_token_" + setting.appId, "")) - .keepJson(true) - //.ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - //Log.d(TAG, "tlsVersion=" + response.handshake().tlsVersion()) - //Log.d(TAG, "cipherSuite=" + response.handshake().cipherSuite().toString()) - - val resp = Gson().fromJson(response, FeishuAppResult::class.java) - if (resp.code == 0L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - } - - fun sendMsg(setting: FeishuAppSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - - private fun jsonInnerStr(string: String?): String { - if (string == null) return "null" - - val jsonStr: String = Gson().toJson(string) - return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr - } - - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.FeishuAppResult +import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting +import com.idormy.sms.forwarder.utils.MMKVUtils +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import com.xuexiang.xui.utils.ResUtils.getString + +//飞书企业应用 +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class FeishuAppUtils private constructor() { + companion object { + + private val TAG: String = FeishuAppUtils::class.java.simpleName + + fun sendMsg( + setting: FeishuAppSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + + val accessToken: String? = MMKVUtils.getString("feishu_access_token_" + setting.appId, "") + val expiresIn: Long = MMKVUtils.getLong("feishu_expires_in_" + setting.appId, 0L) + if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { + return sendTextMsg(setting, msgInfo, rule, logId) + } + + val requestUrl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" + Log.d(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + msgMap["app_id"] = setting.appId + msgMap["app_secret"] = setting.appSecret + val requestMsg: String = Gson().toJson(msgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .keepJson(true) + .ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, FeishuAppResult::class.java) + if (!TextUtils.isEmpty(resp?.tenant_access_token)) { + MMKVUtils.put("feishu_access_token_" + setting.appId, resp.tenant_access_token) + MMKVUtils.put("feishu_expires_in_" + setting.appId, System.currentTimeMillis() + ((resp.expire ?: 7010) - 120) * 1000L) //提前2分钟过期 + sendTextMsg(setting, msgInfo, rule, logId) + } else { + SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) + } + } + + }) + + } + + //发送文本消息 + private fun sendTextMsg( + setting: FeishuAppSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" + Log.d(TAG, "requestUrl:$requestUrl") + + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val msgContent = if ("interactive" == setting.msgType) { + val title = if (rule != null) { + msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace) + } else { + msgInfo.getTitleForSend(setting.titleTemplate) + } + "{\"elements\":[{\"tag\":\"markdown\",\"content\":\"**[{{MSG_TITLE}}]({{MSG_URL}})**\\n --------------\\n{{MSG_CONTENT}}\"}]}".trimIndent().replace("{{MSG_TITLE}}", jsonInnerStr(title)) + .replace("{{MSG_URL}}", jsonInnerStr("https://github.com/pppscn/SmsForwarder")) + .replace("{{MSG_CONTENT}}", jsonInnerStr(content)) + } else { + "{\"text\":\"{{MSG_CONTENT}}\"}".trimIndent().replace("{{MSG_CONTENT}}", jsonInnerStr(content)) + } + + val textMsgMap: MutableMap = mutableMapOf() + textMsgMap["receive_id"] = setting.receiveId + textMsgMap["msg_type"] = setting.msgType + textMsgMap["content"] = msgContent + + val requestMsg: String = Gson().toJson(textMsgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .headers("Authorization", "Bearer " + MMKVUtils.getString("feishu_access_token_" + setting.appId, "")) + .keepJson(true) + //.ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + //Log.d(TAG, "tlsVersion=" + response.handshake().tlsVersion()) + //Log.d(TAG, "cipherSuite=" + response.handshake().cipherSuite().toString()) + + val resp = Gson().fromJson(response, FeishuAppResult::class.java) + if (resp?.code == 0L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + } + + fun sendMsg(setting: FeishuAppSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + + private fun jsonInnerStr(string: String?): String { + if (string == null) return "null" + + val jsonStr: String = Gson().toJson(string) + return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuUtils.kt index 52fa0d0d..f8e14944 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/FeishuUtils.kt @@ -1,187 +1,187 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.util.Base64 -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.FeishuResult -import com.idormy.sms.forwarder.entity.setting.FeishuSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import java.nio.charset.StandardCharsets -import java.text.SimpleDateFormat -import java.util.* -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class FeishuUtils private constructor() { - companion object { - - private val TAG: String = FeishuUtils::class.java.simpleName - private val MSG_TEMPLATE = """ -{ - "config": { - "wide_screen_mode": true - }, - "elements": [ - { - "fields": [ - { - "is_short": true, - "text": { - "content": "**时间**\n{{MSG_TIME}}", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "**来源**\n{{MSG_FROM}}", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "div", - "text": { - "content": "{{MSG_CONTENT}}", - "tag": "lark_md" - } - }, - { - "tag": "hr" - }, - { - "elements": [ - { - "content": "[SmsForwarder](https://github.com/pppscn/SmsForwarder)", - "tag": "lark_md" - } - ], - "tag": "note" - } - ], - "header": { - "template": "turquoise", - "title": { - "content": "{{MSG_TITLE}}", - "tag": "plain_text" - } - } -} - """.trimIndent() - - fun sendMsg( - setting: FeishuSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val from: String = msgInfo.from - val title: String = if (rule != null) { - msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) - } else { - msgInfo.getTitleForSend(setting.titleTemplate.toString()) - } - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val requestUrl = setting.webhook - Log.i(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - if (setting.secret != null) { - val timestamp = System.currentTimeMillis() / 1000 - val stringToSign = "$timestamp\n" + setting.secret - Log.i(TAG, "stringToSign = $stringToSign") - - //使用HmacSHA256算法计算签名 - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(stringToSign.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) - val signData = mac.doFinal(byteArrayOf()) - val sign = String(Base64.encode(signData, Base64.NO_WRAP)) - - msgMap["timestamp"] = timestamp - msgMap["sign"] = sign - } - - //组装报文 - val requestMsg: String - if (setting.msgType == null || setting.msgType == "interactive") { - msgMap["msg_type"] = "interactive" - msgMap["card"] = "{{CARD_BODY}}" - requestMsg = Gson().toJson(msgMap).replace("\"{{CARD_BODY}}\"", buildMsg(title, content, from, msgInfo.date)) - } else { - msgMap["msg_type"] = "text" - val contentMap: MutableMap = mutableMapOf() - contentMap["text"] = content - msgMap["content"] = contentMap - requestMsg = Gson().toJson(msgMap) - } - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .keepJson(true) - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, FeishuResult::class.java) - if (resp.code == 0L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - private fun buildMsg(title: String, content: String, from: String, date: Date): String { - val msgTitle = jsonInnerStr(title) - val msgContent = jsonInnerStr(content) - val msgFrom = jsonInnerStr(from) - val msgTime = jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(date)) - return MSG_TEMPLATE.replace("{{MSG_TITLE}}", msgTitle) - .replace("{{MSG_TIME}}", msgTime) - .replace("{{MSG_FROM}}", msgFrom) - .replace("{{MSG_CONTENT}}", msgContent) - } - - private fun jsonInnerStr(string: String?): String { - if (string == null) return "null" - - val jsonStr: String = Gson().toJson(string) - return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr - } - - fun sendMsg(setting: FeishuSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.util.Base64 +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.FeishuResult +import com.idormy.sms.forwarder.entity.setting.FeishuSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import java.nio.charset.StandardCharsets +import java.text.SimpleDateFormat +import java.util.* +import javax.crypto.Mac +import javax.crypto.spec.SecretKeySpec + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class FeishuUtils private constructor() { + companion object { + + private val TAG: String = FeishuUtils::class.java.simpleName + private val MSG_TEMPLATE = """ +{ + "config": { + "wide_screen_mode": true + }, + "elements": [ + { + "fields": [ + { + "is_short": true, + "text": { + "content": "**时间**\n{{MSG_TIME}}", + "tag": "lark_md" + } + }, + { + "is_short": true, + "text": { + "content": "**来源**\n{{MSG_FROM}}", + "tag": "lark_md" + } + } + ], + "tag": "div" + }, + { + "tag": "div", + "text": { + "content": "{{MSG_CONTENT}}", + "tag": "lark_md" + } + }, + { + "tag": "hr" + }, + { + "elements": [ + { + "content": "[SmsForwarder](https://github.com/pppscn/SmsForwarder)", + "tag": "lark_md" + } + ], + "tag": "note" + } + ], + "header": { + "template": "turquoise", + "title": { + "content": "{{MSG_TITLE}}", + "tag": "plain_text" + } + } +} + """.trimIndent() + + fun sendMsg( + setting: FeishuSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val from: String = msgInfo.from + val title: String = if (rule != null) { + msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) + } else { + msgInfo.getTitleForSend(setting.titleTemplate.toString()) + } + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val requestUrl = setting.webhook + Log.i(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + if (setting.secret != null) { + val timestamp = System.currentTimeMillis() / 1000 + val stringToSign = "$timestamp\n" + setting.secret + Log.i(TAG, "stringToSign = $stringToSign") + + //使用HmacSHA256算法计算签名 + val mac = Mac.getInstance("HmacSHA256") + mac.init(SecretKeySpec(stringToSign.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) + val signData = mac.doFinal(byteArrayOf()) + val sign = String(Base64.encode(signData, Base64.NO_WRAP)) + + msgMap["timestamp"] = timestamp + msgMap["sign"] = sign + } + + //组装报文 + val requestMsg: String + if (setting.msgType == null || setting.msgType == "interactive") { + msgMap["msg_type"] = "interactive" + msgMap["card"] = "{{CARD_BODY}}" + requestMsg = Gson().toJson(msgMap).replace("\"{{CARD_BODY}}\"", buildMsg(title, content, from, msgInfo.date)) + } else { + msgMap["msg_type"] = "text" + val contentMap: MutableMap = mutableMapOf() + contentMap["text"] = content + msgMap["content"] = contentMap + requestMsg = Gson().toJson(msgMap) + } + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .keepJson(true) + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, FeishuResult::class.java) + if (resp?.code == 0L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + private fun buildMsg(title: String, content: String, from: String, date: Date): String { + val msgTitle = jsonInnerStr(title) + val msgContent = jsonInnerStr(content) + val msgFrom = jsonInnerStr(from) + val msgTime = jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(date)) + return MSG_TEMPLATE.replace("{{MSG_TITLE}}", msgTitle) + .replace("{{MSG_TIME}}", msgTime) + .replace("{{MSG_FROM}}", msgFrom) + .replace("{{MSG_CONTENT}}", msgContent) + } + + private fun jsonInnerStr(string: String?): String { + if (string == null) return "null" + + val jsonStr: String = Gson().toJson(string) + return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr + } + + fun sendMsg(setting: FeishuSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/PushplusUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/PushplusUtils.kt index bd0b8243..b2322efe 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/PushplusUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/PushplusUtils.kt @@ -1,105 +1,105 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.R -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.PushplusResult -import com.idormy.sms.forwarder.entity.setting.PushplusSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import com.xuexiang.xui.utils.ResUtils - - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class PushplusUtils private constructor() { - companion object { - - private val TAG: String = PushplusUtils::class.java.simpleName - - fun sendMsg( - setting: PushplusSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val title: String = if (rule != null) { - msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) - } else { - msgInfo.getTitleForSend(setting.titleTemplate.toString()) - } - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val requestUrl = "https://" + setting.website + "/send" - Log.i(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - msgMap["token"] = setting.token - msgMap["content"] = content - - if (!TextUtils.isEmpty(title)) msgMap["title"] = title - if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template.toString() - if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic.toString() - - if (setting.website == ResUtils.getString(R.string.pushplus_plus)) { - if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel.toString() - if (!TextUtils.isEmpty(setting.webhook)) msgMap["webhook"] = setting.webhook.toString() - if (!TextUtils.isEmpty(setting.callbackUrl)) msgMap["callbackUrl"] = setting.callbackUrl.toString() - if (!TextUtils.isEmpty(setting.validTime)) { - val validTime = setting.validTime?.toInt() - if (validTime != null && validTime > 0) { - msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L - } - } - } - - - val requestMsg: String = Gson().toJson(msgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .keepJson(true) - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, PushplusResult::class.java) - if (resp.code == 200L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - fun sendMsg(setting: PushplusSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.PushplusResult +import com.idormy.sms.forwarder.entity.setting.PushplusSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import com.xuexiang.xui.utils.ResUtils + + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class PushplusUtils private constructor() { + companion object { + + private val TAG: String = PushplusUtils::class.java.simpleName + + fun sendMsg( + setting: PushplusSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val title: String = if (rule != null) { + msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) + } else { + msgInfo.getTitleForSend(setting.titleTemplate.toString()) + } + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val requestUrl = "https://" + setting.website + "/send" + Log.i(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + msgMap["token"] = setting.token + msgMap["content"] = content + + if (!TextUtils.isEmpty(title)) msgMap["title"] = title + if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template.toString() + if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic.toString() + + if (setting.website == ResUtils.getString(R.string.pushplus_plus)) { + if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel.toString() + if (!TextUtils.isEmpty(setting.webhook)) msgMap["webhook"] = setting.webhook.toString() + if (!TextUtils.isEmpty(setting.callbackUrl)) msgMap["callbackUrl"] = setting.callbackUrl.toString() + if (!TextUtils.isEmpty(setting.validTime)) { + val validTime = setting.validTime?.toInt() + if (validTime != null && validTime > 0) { + msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L + } + } + } + + + val requestMsg: String = Gson().toJson(msgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .keepJson(true) + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, PushplusResult::class.java) + if (resp?.code == 200L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + fun sendMsg(setting: PushplusSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/TelegramUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/TelegramUtils.kt index c3951076..a44b0f91 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/TelegramUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/TelegramUtils.kt @@ -1,159 +1,159 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.TelegramResult -import com.idormy.sms.forwarder.entity.setting.TelegramSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import com.xuexiang.xutil.net.NetworkUtils -import okhttp3.Credentials -import okhttp3.Response -import okhttp3.Route -import java.net.* - - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") -class TelegramUtils private constructor() { - companion object { - - private val TAG: String = TelegramUtils::class.java.simpleName - - fun sendMsg( - setting: TelegramSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - if (setting.method == null || setting.method == "POST") { - msgInfo.content = htmlEncode(msgInfo.content) - msgInfo.simInfo = htmlEncode(msgInfo.simInfo) - } - - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - var requestUrl = if (setting.apiToken.startsWith("http")) { - setting.apiToken - } else { - "https://api.telegram.org/bot" + setting.apiToken + "/sendMessage" - } - Log.i(TAG, "requestUrl:$requestUrl") - - val request = if (setting.method != null && setting.method == "GET") { - requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8") - Log.i(TAG, "requestUrl:$requestUrl") - XHttp.get(requestUrl) - } else { - val bodyMap: MutableMap = mutableMapOf() - bodyMap["chat_id"] = setting.chatId - bodyMap["text"] = content - bodyMap["parse_mode"] = "HTML" - bodyMap["disable_web_page_preview"] = "true" - val requestMsg: String = Gson().toJson(bodyMap) - Log.i(TAG, "requestMsg:$requestMsg") - XHttp.post(requestUrl).upJson(requestMsg) - } - - //设置代理 - if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) - && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) - ) { - //代理服务器的IP和端口号 - Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") - val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) - if (!NetworkUtils.isIP(proxyHost)) { - throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") - } - val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 - - Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") - request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) - - //代理的鉴权账号密码 - if (setting.proxyAuthenticator == true - && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) - ) { - Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") - - if (setting.proxyType == Proxy.Type.HTTP) { - request.okproxyAuthenticator { _: Route?, response: Response -> - //设置代理服务器账号密码 - val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } else { - Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) - } - }) - } - } - } - - request.keepJson(true) - //.ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, TelegramResult::class.java) - if (resp.ok == true) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - fun sendMsg(setting: TelegramSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - - private fun htmlEncode(source: String?): String { - if (source == null) { - return "" - } - val buffer = StringBuffer() - for (element in source) { - when (element) { - '<' -> buffer.append("<") - '>' -> buffer.append(">") - '&' -> buffer.append("&") - '"' -> buffer.append(""") - //10, 13 -> buffer.append("\n") - else -> buffer.append(element) - } - } - return buffer.toString() - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.TelegramResult +import com.idormy.sms.forwarder.entity.setting.TelegramSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import com.xuexiang.xutil.net.NetworkUtils +import okhttp3.Credentials +import okhttp3.Response +import okhttp3.Route +import java.net.* + + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") +class TelegramUtils private constructor() { + companion object { + + private val TAG: String = TelegramUtils::class.java.simpleName + + fun sendMsg( + setting: TelegramSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + if (setting.method == null || setting.method == "POST") { + msgInfo.content = htmlEncode(msgInfo.content) + msgInfo.simInfo = htmlEncode(msgInfo.simInfo) + } + + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + var requestUrl = if (setting.apiToken.startsWith("http")) { + setting.apiToken + } else { + "https://api.telegram.org/bot" + setting.apiToken + "/sendMessage" + } + Log.i(TAG, "requestUrl:$requestUrl") + + val request = if (setting.method != null && setting.method == "GET") { + requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8") + Log.i(TAG, "requestUrl:$requestUrl") + XHttp.get(requestUrl) + } else { + val bodyMap: MutableMap = mutableMapOf() + bodyMap["chat_id"] = setting.chatId + bodyMap["text"] = content + bodyMap["parse_mode"] = "HTML" + bodyMap["disable_web_page_preview"] = "true" + val requestMsg: String = Gson().toJson(bodyMap) + Log.i(TAG, "requestMsg:$requestMsg") + XHttp.post(requestUrl).upJson(requestMsg) + } + + //设置代理 + if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) + && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) + ) { + //代理服务器的IP和端口号 + Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") + val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) + if (!NetworkUtils.isIP(proxyHost)) { + throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") + } + val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 + + Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") + request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) + + //代理的鉴权账号密码 + if (setting.proxyAuthenticator == true + && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) + ) { + Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") + + if (setting.proxyType == Proxy.Type.HTTP) { + request.okproxyAuthenticator { _: Route?, response: Response -> + //设置代理服务器账号密码 + val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } else { + Authenticator.setDefault(object : Authenticator() { + override fun getPasswordAuthentication(): PasswordAuthentication { + return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) + } + }) + } + } + } + + request.keepJson(true) + //.ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, TelegramResult::class.java) + if (resp?.ok == true) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + fun sendMsg(setting: TelegramSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + + private fun htmlEncode(source: String?): String { + if (source == null) { + return "" + } + val buffer = StringBuffer() + for (element in source) { + when (element) { + '<' -> buffer.append("<") + '>' -> buffer.append(">") + '&' -> buffer.append("&") + '"' -> buffer.append(""") + //10, 13 -> buffer.append("\n") + else -> buffer.append(element) + } + } + return buffer.toString() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkAgentUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkAgentUtils.kt index 026bf682..db5085e8 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkAgentUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkAgentUtils.kt @@ -1,226 +1,226 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.text.TextUtils -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.R -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.DingtalkResult -import com.idormy.sms.forwarder.entity.result.WeworkAgentResult -import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting -import com.idormy.sms.forwarder.utils.MMKVUtils -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException -import com.xuexiang.xui.utils.ResUtils.getString -import com.xuexiang.xutil.net.NetworkUtils -import okhttp3.Credentials -import okhttp3.Response -import okhttp3.Route -import java.net.Authenticator -import java.net.InetSocketAddress -import java.net.PasswordAuthentication -import java.net.Proxy - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class WeworkAgentUtils private constructor() { - companion object { - - private val TAG: String = WeworkAgentUtils::class.java.simpleName - - fun sendMsg( - setting: WeworkAgentSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - - val accessToken: String? = MMKVUtils.getString("access_token_" + setting.agentID, "") - val expiresIn: Long = MMKVUtils.getLong("expires_in_" + setting.agentID, 0L) - if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { - return sendTextMsg(setting, msgInfo, rule, logId) - } - - var getTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" - getTokenUrl += "corpid=" + setting.corpID - getTokenUrl += "&corpsecret=" + setting.secret - Log.d(TAG, "getTokenUrl:$getTokenUrl") - - val request = XHttp.get(getTokenUrl) - - //设置代理 - if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) - && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) - ) { - //代理服务器的IP和端口号 - Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") - val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) - if (!NetworkUtils.isIP(proxyHost)) { - throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") - } - val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 - - Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") - request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) - - //代理的鉴权账号密码 - if (setting.proxyAuthenticator == true - && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) - ) { - Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") - - if (setting.proxyType == Proxy.Type.HTTP) { - request.okproxyAuthenticator { _: Route?, response: Response -> - //设置代理服务器账号密码 - val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } else { - Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) - } - }) - } - } - } - - request.keepJson(true) - .ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, WeworkAgentResult::class.java) - if (resp.errcode == 0L) { - MMKVUtils.put("access_token_" + setting.agentID, resp.access_token) - MMKVUtils.put("expires_in_" + setting.agentID, System.currentTimeMillis() + ((resp.expires_in ?: 7200) - 120) * 1000L) //提前2分钟过期 - sendTextMsg(setting, msgInfo, rule, logId) - } else { - SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) - } - } - - }) - - } - - //发送文本消息 - private fun sendTextMsg( - setting: WeworkAgentSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val textMsgMap: MutableMap = mutableMapOf() - textMsgMap["touser"] = setting.toUser.toString() - textMsgMap["toparty"] = setting.toParty.toString() - textMsgMap["totag"] = setting.toTag.toString() - textMsgMap["msgtype"] = "text" - textMsgMap["agentid"] = setting.agentID - val textText: MutableMap = mutableMapOf() - textText["content"] = content - textMsgMap["text"] = textText - val requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + MMKVUtils.getString("access_token_" + setting.agentID, "") - Log.i(TAG, "requestUrl:$requestUrl") - val requestMsg: String = Gson().toJson(textMsgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - val request = XHttp.post(requestUrl) - - //设置代理 - if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) - && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) - ) { - //代理服务器的IP和端口号 - Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") - val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) - if (!NetworkUtils.isIP(proxyHost)) { - throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") - } - val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 - - Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") - request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) - - //代理的鉴权账号密码 - if (setting.proxyAuthenticator == true - && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) - ) { - Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") - - if (setting.proxyType == Proxy.Type.HTTP) { - request.okproxyAuthenticator { _: Route?, response: Response -> - //设置代理服务器账号密码 - val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } - } else { - Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) - } - }) - } - } - } - - request.upJson(requestMsg) - .keepJson(true) - .ignoreHttpsCert() - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, DingtalkResult::class.java) - if (resp.errcode == 0L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - } - - fun sendMsg(setting: WeworkAgentSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - - } +package com.idormy.sms.forwarder.utils.sender + +import android.text.TextUtils +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.R +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.DingtalkResult +import com.idormy.sms.forwarder.entity.result.WeworkAgentResult +import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting +import com.idormy.sms.forwarder.utils.MMKVUtils +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException +import com.xuexiang.xui.utils.ResUtils.getString +import com.xuexiang.xutil.net.NetworkUtils +import okhttp3.Credentials +import okhttp3.Response +import okhttp3.Route +import java.net.Authenticator +import java.net.InetSocketAddress +import java.net.PasswordAuthentication +import java.net.Proxy + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class WeworkAgentUtils private constructor() { + companion object { + + private val TAG: String = WeworkAgentUtils::class.java.simpleName + + fun sendMsg( + setting: WeworkAgentSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + + val accessToken: String? = MMKVUtils.getString("access_token_" + setting.agentID, "") + val expiresIn: Long = MMKVUtils.getLong("expires_in_" + setting.agentID, 0L) + if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { + return sendTextMsg(setting, msgInfo, rule, logId) + } + + var getTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" + getTokenUrl += "corpid=" + setting.corpID + getTokenUrl += "&corpsecret=" + setting.secret + Log.d(TAG, "getTokenUrl:$getTokenUrl") + + val request = XHttp.get(getTokenUrl) + + //设置代理 + if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) + && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) + ) { + //代理服务器的IP和端口号 + Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") + val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) + if (!NetworkUtils.isIP(proxyHost)) { + throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") + } + val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 + + Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") + request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) + + //代理的鉴权账号密码 + if (setting.proxyAuthenticator == true + && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) + ) { + Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") + + if (setting.proxyType == Proxy.Type.HTTP) { + request.okproxyAuthenticator { _: Route?, response: Response -> + //设置代理服务器账号密码 + val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } else { + Authenticator.setDefault(object : Authenticator() { + override fun getPasswordAuthentication(): PasswordAuthentication { + return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) + } + }) + } + } + } + + request.keepJson(true) + .ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, WeworkAgentResult::class.java) + if (resp?.errcode == 0L) { + MMKVUtils.put("access_token_" + setting.agentID, resp.access_token) + MMKVUtils.put("expires_in_" + setting.agentID, System.currentTimeMillis() + ((resp.expires_in ?: 7200) - 120) * 1000L) //提前2分钟过期 + sendTextMsg(setting, msgInfo, rule, logId) + } else { + SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) + } + } + + }) + + } + + //发送文本消息 + private fun sendTextMsg( + setting: WeworkAgentSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val textMsgMap: MutableMap = mutableMapOf() + textMsgMap["touser"] = setting.toUser.toString() + textMsgMap["toparty"] = setting.toParty.toString() + textMsgMap["totag"] = setting.toTag.toString() + textMsgMap["msgtype"] = "text" + textMsgMap["agentid"] = setting.agentID + val textText: MutableMap = mutableMapOf() + textText["content"] = content + textMsgMap["text"] = textText + val requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + MMKVUtils.getString("access_token_" + setting.agentID, "") + Log.i(TAG, "requestUrl:$requestUrl") + val requestMsg: String = Gson().toJson(textMsgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + val request = XHttp.post(requestUrl) + + //设置代理 + if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) + && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) + ) { + //代理服务器的IP和端口号 + Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") + val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) + if (!NetworkUtils.isIP(proxyHost)) { + throw Exception("代理服务器主机名解析失败:proxyHost=$proxyHost") + } + val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 + + Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") + request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) + + //代理的鉴权账号密码 + if (setting.proxyAuthenticator == true + && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) + ) { + Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") + + if (setting.proxyType == Proxy.Type.HTTP) { + request.okproxyAuthenticator { _: Route?, response: Response -> + //设置代理服务器账号密码 + val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } else { + Authenticator.setDefault(object : Authenticator() { + override fun getPasswordAuthentication(): PasswordAuthentication { + return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) + } + }) + } + } + } + + request.upJson(requestMsg) + .keepJson(true) + .ignoreHttpsCert() + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, DingtalkResult::class.java) + if (resp?.errcode == 0L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + } + + fun sendMsg(setting: WeworkAgentSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkRobotUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkRobotUtils.kt index c9916c35..57a61a90 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkRobotUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/sender/WeworkRobotUtils.kt @@ -1,82 +1,82 @@ -package com.idormy.sms.forwarder.utils.sender - -import android.util.Log -import com.google.gson.Gson -import com.idormy.sms.forwarder.database.entity.Rule -import com.idormy.sms.forwarder.entity.MsgInfo -import com.idormy.sms.forwarder.entity.result.WeworkRobotResult -import com.idormy.sms.forwarder.entity.setting.WeworkRobotSetting -import com.idormy.sms.forwarder.utils.SendUtils -import com.idormy.sms.forwarder.utils.SettingUtils -import com.xuexiang.xhttp2.XHttp -import com.xuexiang.xhttp2.cache.model.CacheMode -import com.xuexiang.xhttp2.callback.SimpleCallBack -import com.xuexiang.xhttp2.exception.ApiException - -@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") -class WeworkRobotUtils private constructor() { - companion object { - - private val TAG: String = WeworkRobotUtils::class.java.simpleName - - fun sendMsg( - setting: WeworkRobotSetting, - msgInfo: MsgInfo, - rule: Rule?, - logId: Long?, - ) { - val content: String = if (rule != null) { - msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) - } else { - msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) - } - - val requestUrl = setting.webHook - Log.i(TAG, "requestUrl:$requestUrl") - - val msgMap: MutableMap = mutableMapOf() - msgMap["msgtype"] = "text" - - val textText: MutableMap = mutableMapOf() - textText["content"] = content - msgMap["text"] = textText - - val requestMsg: String = Gson().toJson(msgMap) - Log.i(TAG, "requestMsg:$requestMsg") - - XHttp.post(requestUrl) - .upJson(requestMsg) - .keepJson(true) - .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s - .cacheMode(CacheMode.NO_CACHE) - .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 - .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 - .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 - .timeStamp(true) - .execute(object : SimpleCallBack() { - - override fun onError(e: ApiException) { - Log.e(TAG, e.detailMessage) - SendUtils.updateLogs(logId, 0, e.displayMessage) - } - - override fun onSuccess(response: String) { - Log.i(TAG, response) - - val resp = Gson().fromJson(response, WeworkRobotResult::class.java) - if (resp.errcode == 0L) { - SendUtils.updateLogs(logId, 2, response) - } else { - SendUtils.updateLogs(logId, 0, response) - } - } - - }) - - } - - fun sendMsg(setting: WeworkRobotSetting, msgInfo: MsgInfo) { - sendMsg(setting, msgInfo, null, null) - } - } +package com.idormy.sms.forwarder.utils.sender + +import android.util.Log +import com.google.gson.Gson +import com.idormy.sms.forwarder.database.entity.Rule +import com.idormy.sms.forwarder.entity.MsgInfo +import com.idormy.sms.forwarder.entity.result.WeworkRobotResult +import com.idormy.sms.forwarder.entity.setting.WeworkRobotSetting +import com.idormy.sms.forwarder.utils.SendUtils +import com.idormy.sms.forwarder.utils.SettingUtils +import com.xuexiang.xhttp2.XHttp +import com.xuexiang.xhttp2.cache.model.CacheMode +import com.xuexiang.xhttp2.callback.SimpleCallBack +import com.xuexiang.xhttp2.exception.ApiException + +@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") +class WeworkRobotUtils private constructor() { + companion object { + + private val TAG: String = WeworkRobotUtils::class.java.simpleName + + fun sendMsg( + setting: WeworkRobotSetting, + msgInfo: MsgInfo, + rule: Rule?, + logId: Long?, + ) { + val content: String = if (rule != null) { + msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) + } else { + msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) + } + + val requestUrl = setting.webHook + Log.i(TAG, "requestUrl:$requestUrl") + + val msgMap: MutableMap = mutableMapOf() + msgMap["msgtype"] = "text" + + val textText: MutableMap = mutableMapOf() + textText["content"] = content + msgMap["text"] = textText + + val requestMsg: String = Gson().toJson(msgMap) + Log.i(TAG, "requestMsg:$requestMsg") + + XHttp.post(requestUrl) + .upJson(requestMsg) + .keepJson(true) + .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s + .cacheMode(CacheMode.NO_CACHE) + .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 + .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 + .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 + .timeStamp(true) + .execute(object : SimpleCallBack() { + + override fun onError(e: ApiException) { + Log.e(TAG, e.detailMessage) + SendUtils.updateLogs(logId, 0, e.displayMessage) + } + + override fun onSuccess(response: String) { + Log.i(TAG, response) + + val resp = Gson().fromJson(response, WeworkRobotResult::class.java) + if (resp?.errcode == 0L) { + SendUtils.updateLogs(logId, 2, response) + } else { + SendUtils.updateLogs(logId, 0, response) + } + } + + }) + + } + + fun sendMsg(setting: WeworkRobotSetting, msgInfo: MsgInfo) { + sendMsg(setting, msgInfo, null, null) + } + } } \ No newline at end of file