修复:极端情况下Gson().fromJson爆空指针错误 #207

This commit is contained in:
pppscn 2022-09-21 10:33:19 +08:00
parent 74cbddc192
commit 9d75554df0
9 changed files with 1388 additions and 1388 deletions

View File

@ -1,111 +1,111 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.BarkResult import com.idormy.sms.forwarder.entity.result.BarkResult
import com.idormy.sms.forwarder.entity.setting.BarkSetting import com.idormy.sms.forwarder.entity.setting.BarkSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import java.util.regex.Pattern import java.util.regex.Pattern
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused")
class BarkUtils { class BarkUtils {
companion object { companion object {
private val TAG: String = BarkUtils::class.java.simpleName private val TAG: String = BarkUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: BarkSetting, setting: BarkSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.title.toString(), rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.title.toString()) msgInfo.getTitleForSend(setting.title.toString())
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val requestUrl: String = setting.server //推送地址 val requestUrl: String = setting.server //推送地址
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
//支持HTTP基本认证(Basic Authentication) //支持HTTP基本认证(Basic Authentication)
val regex = "^(https?://)([^:]+):([^@]+)@(.+)" val regex = "^(https?://)([^:]+):([^@]+)@(.+)"
val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList().flatMap(MatchResult::groupValues) val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList().flatMap(MatchResult::groupValues)
Log.i(TAG, "matches = $matches") Log.i(TAG, "matches = $matches")
val request = if (matches.isNotEmpty()) { val request = if (matches.isNotEmpty()) {
XHttp.post(matches[1] + matches[4]).addInterceptor(BasicAuthInterceptor(matches[2], matches[3])) XHttp.post(matches[1] + matches[4]).addInterceptor(BasicAuthInterceptor(matches[2], matches[3]))
} else { } else {
XHttp.post(requestUrl) XHttp.post(requestUrl)
} }
request.params("title", title) request.params("title", title)
.params("body", content) .params("body", content)
.params("isArchive", 1) .params("isArchive", 1)
if (!TextUtils.isEmpty(setting.group)) request.params("group", setting.group) if (!TextUtils.isEmpty(setting.group)) request.params("group", setting.group)
if (!TextUtils.isEmpty(setting.icon)) request.params("icon", setting.icon) if (!TextUtils.isEmpty(setting.icon)) request.params("icon", setting.icon)
if (!TextUtils.isEmpty(setting.level)) request.params("level", setting.level) if (!TextUtils.isEmpty(setting.level)) request.params("level", setting.level)
if (!TextUtils.isEmpty(setting.sound)) request.params("sound", setting.sound) if (!TextUtils.isEmpty(setting.sound)) request.params("sound", setting.sound)
if (!TextUtils.isEmpty(setting.badge)) request.params("badge", setting.badge) if (!TextUtils.isEmpty(setting.badge)) request.params("badge", setting.badge)
if (!TextUtils.isEmpty(setting.url)) request.params("url", setting.url) if (!TextUtils.isEmpty(setting.url)) request.params("url", setting.url)
val isCode: Int = content.indexOf("验证码") val isCode: Int = content.indexOf("验证码")
val isPassword: Int = content.indexOf("动态密码") val isPassword: Int = content.indexOf("动态密码")
val isPassword2: Int = content.indexOf("短信密码") val isPassword2: Int = content.indexOf("短信密码")
if (isCode != -1 || isPassword != -1 || isPassword2 != -1) { if (isCode != -1 || isPassword != -1 || isPassword2 != -1) {
val p = Pattern.compile("(\\d{4,6})") val p = Pattern.compile("(\\d{4,6})")
val m = p.matcher(content) val m = p.matcher(content)
if (m.find()) { if (m.find()) {
println(m.group()) println(m.group())
request.params("automaticallyCopy", "1") request.params("automaticallyCopy", "1")
request.params("copy", m.group()) request.params("copy", m.group())
} }
} }
request.ignoreHttpsCert() //忽略https证书 request.ignoreHttpsCert() //忽略https证书
.keepJson(true) .keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, BarkResult::class.java) val resp = Gson().fromJson(response, BarkResult::class.java)
if (resp.code == 200L) { if (resp?.code == 200L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: BarkSetting, msgInfo: MsgInfo) { fun sendMsg(setting: BarkSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,122 +1,122 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.DingtalkResult import com.idormy.sms.forwarder.entity.result.DingtalkResult
import com.idormy.sms.forwarder.entity.setting.DingtalkGroupRobotSetting import com.idormy.sms.forwarder.entity.setting.DingtalkGroupRobotSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import javax.crypto.Mac import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
//钉钉群自定义机器人 //钉钉群自定义机器人
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class DingtalkGroupRobotUtils private constructor() { class DingtalkGroupRobotUtils private constructor() {
companion object { companion object {
private val TAG: String = DingtalkGroupRobotUtils::class.java.simpleName private val TAG: String = DingtalkGroupRobotUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: DingtalkGroupRobotSetting, setting: DingtalkGroupRobotSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) 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 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)) { if (!TextUtils.isEmpty(setting.secret)) {
val timestamp = System.currentTimeMillis() val timestamp = System.currentTimeMillis()
val stringToSign = "$timestamp\n" + setting.secret val stringToSign = "$timestamp\n" + setting.secret
val mac = Mac.getInstance("HmacSHA256") val mac = Mac.getInstance("HmacSHA256")
mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) mac.init(SecretKeySpec(setting.secret?.toByteArray(StandardCharsets.UTF_8), "HmacSHA256"))
val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8)) val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8))
val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8") val sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8")
requestUrl += "&timestamp=$timestamp&sign=$sign" requestUrl += "&timestamp=$timestamp&sign=$sign"
} }
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["msgtype"] = "text" msgMap["msgtype"] = "text"
val textText: MutableMap<String, Any> = mutableMapOf() val textText: MutableMap<String, Any> = mutableMapOf()
textText["content"] = content textText["content"] = content
msgMap["text"] = textText msgMap["text"] = textText
val atMap: MutableMap<String, Any> = mutableMapOf() val atMap: MutableMap<String, Any> = mutableMapOf()
msgMap["at"] = atMap msgMap["at"] = atMap
if (setting.atAll == true) { if (setting.atAll == true) {
atMap["isAtAll"] = true atMap["isAtAll"] = true
} else { } else {
atMap["isAtAll"] = false atMap["isAtAll"] = false
if (!TextUtils.isEmpty(setting.atMobiles)) { if (!TextUtils.isEmpty(setting.atMobiles)) {
val atMobilesArray: Array<String>? = setting.atMobiles?.split(",".toRegex())?.toTypedArray() val atMobilesArray: Array<String>? = setting.atMobiles?.split(",".toRegex())?.toTypedArray()
if (atMobilesArray != null) { if (atMobilesArray != null) {
val atMobilesList: MutableList<String> = ArrayList() val atMobilesList: MutableList<String> = ArrayList()
for (atMobile in atMobilesArray) { for (atMobile in atMobilesArray) {
if (TextUtils.isDigitsOnly(atMobile)) { if (TextUtils.isDigitsOnly(atMobile)) {
atMobilesList.add(atMobile) atMobilesList.add(atMobile)
} }
} }
if (atMobilesList.isNotEmpty()) { if (atMobilesList.isNotEmpty()) {
atMap["atMobiles"] = atMobilesList atMap["atMobiles"] = atMobilesList
} }
} }
} }
} }
val requestMsg: String = Gson().toJson(msgMap) val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.keepJson(true) .keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, DingtalkResult::class.java) val resp = Gson().fromJson(response, DingtalkResult::class.java)
if (resp.errcode == 0L) { if (resp?.errcode == 0L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: DingtalkGroupRobotSetting, msgInfo: MsgInfo) { fun sendMsg(setting: DingtalkGroupRobotSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,242 +1,242 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.DingtalkInnerRobotResult import com.idormy.sms.forwarder.entity.result.DingtalkInnerRobotResult
import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting
import com.idormy.sms.forwarder.utils.MMKVUtils import com.idormy.sms.forwarder.utils.MMKVUtils
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xui.utils.ResUtils.getString import com.xuexiang.xui.utils.ResUtils.getString
import com.xuexiang.xutil.net.NetworkUtils import com.xuexiang.xutil.net.NetworkUtils
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Response import okhttp3.Response
import okhttp3.Route import okhttp3.Route
import java.net.Authenticator import java.net.Authenticator
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.PasswordAuthentication import java.net.PasswordAuthentication
import java.net.Proxy import java.net.Proxy
//钉钉企业内机器人 //钉钉企业内机器人
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class DingtalkInnerRobotUtils private constructor() { class DingtalkInnerRobotUtils private constructor() {
companion object { companion object {
private val TAG: String = DingtalkInnerRobotUtils::class.java.simpleName private val TAG: String = DingtalkInnerRobotUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: DingtalkInnerRobotSetting, setting: DingtalkInnerRobotSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val accessToken: String? = MMKVUtils.getString("accessToken_" + setting.agentID, "") val accessToken: String? = MMKVUtils.getString("accessToken_" + setting.agentID, "")
val expiresIn: Long = MMKVUtils.getLong("expiresIn_" + setting.agentID, 0L) val expiresIn: Long = MMKVUtils.getLong("expiresIn_" + setting.agentID, 0L)
if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) {
return sendTextMsg(setting, msgInfo, rule, logId) return sendTextMsg(setting, msgInfo, rule, logId)
} }
val requestUrl = "https://api.dingtalk.com/v1.0/oauth2/accessToken" val requestUrl = "https://api.dingtalk.com/v1.0/oauth2/accessToken"
Log.d(TAG, "requestUrl$requestUrl") Log.d(TAG, "requestUrl$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["appKey"] = setting.appKey msgMap["appKey"] = setting.appKey
msgMap["appSecret"] = setting.appSecret msgMap["appSecret"] = setting.appSecret
val requestMsg: String = Gson().toJson(msgMap) val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
val request = XHttp.post(requestUrl) val request = XHttp.post(requestUrl)
//设置代理 //设置代理
if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS)
&& !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort)
) { ) {
//代理服务器的IP和端口号 //代理服务器的IP和端口号
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost") throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost")
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator == true
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString())
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray())
} }
}) })
} }
} }
} }
request.upJson(requestMsg) request.upJson(requestMsg)
.keepJson(true) .keepJson(true)
.ignoreHttpsCert() .ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java)
if (!TextUtils.isEmpty(resp.accessToken)) { if (!TextUtils.isEmpty(resp?.accessToken)) {
MMKVUtils.put("accessToken_" + setting.agentID, resp.accessToken) MMKVUtils.put("accessToken_" + setting.agentID, resp.accessToken)
MMKVUtils.put("expiresIn_" + setting.agentID, System.currentTimeMillis() + ((resp.expireIn ?: 7200) - 120) * 1000L) //提前2分钟过期 MMKVUtils.put("expiresIn_" + setting.agentID, System.currentTimeMillis() + ((resp.expireIn ?: 7200) - 120) * 1000L) //提前2分钟过期
sendTextMsg(setting, msgInfo, rule, logId) sendTextMsg(setting, msgInfo, rule, logId)
} else { } else {
SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response))
} }
} }
}) })
} }
//发送文本消息 //发送文本消息
private fun sendTextMsg( private fun sendTextMsg(
setting: DingtalkInnerRobotSetting, setting: DingtalkInnerRobotSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val requestUrl = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" val requestUrl = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend"
Log.d(TAG, "requestUrl$requestUrl") Log.d(TAG, "requestUrl$requestUrl")
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val msgParam: MutableMap<String, Any> = mutableMapOf() val msgParam: MutableMap<String, Any> = mutableMapOf()
if ("sampleMarkdown" == setting.msgKey) { if ("sampleMarkdown" == setting.msgKey) {
msgParam["title"] = if (rule != null) { msgParam["title"] = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate.toString())
} }
msgParam["text"] = content msgParam["text"] = content
} else { } else {
msgParam["content"] = content msgParam["content"] = content
} }
val textMsgMap: MutableMap<String, Any> = mutableMapOf() val textMsgMap: MutableMap<String, Any> = mutableMapOf()
textMsgMap["robotCode"] = setting.appKey textMsgMap["robotCode"] = setting.appKey
textMsgMap["userIds"] = setting.userIds.split('|').toTypedArray() textMsgMap["userIds"] = setting.userIds.split('|').toTypedArray()
textMsgMap["msgKey"] = setting.msgKey textMsgMap["msgKey"] = setting.msgKey
textMsgMap["msgParam"] = Gson().toJson(msgParam) textMsgMap["msgParam"] = Gson().toJson(msgParam)
val requestMsg: String = Gson().toJson(textMsgMap) val requestMsg: String = Gson().toJson(textMsgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
val request = XHttp.post(requestUrl) val request = XHttp.post(requestUrl)
//设置代理 //设置代理
if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS)
&& !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort)
) { ) {
//代理服务器的IP和端口号 //代理服务器的IP和端口号
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost") throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost")
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator == true
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString())
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray())
} }
}) })
} }
} }
} }
request.upJson(requestMsg) request.upJson(requestMsg)
.headers("x-acs-dingtalk-access-token", MMKVUtils.getString("accessToken_" + setting.agentID, "")) .headers("x-acs-dingtalk-access-token", MMKVUtils.getString("accessToken_" + setting.agentID, ""))
.keepJson(true) .keepJson(true)
.ignoreHttpsCert() .ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java) val resp = Gson().fromJson(response, DingtalkInnerRobotResult::class.java)
if (!TextUtils.isEmpty(resp.processQueryKey)) { if (!TextUtils.isEmpty(resp?.processQueryKey)) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: DingtalkInnerRobotSetting, msgInfo: MsgInfo) { fun sendMsg(setting: DingtalkInnerRobotSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,163 +1,163 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.FeishuAppResult import com.idormy.sms.forwarder.entity.result.FeishuAppResult
import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting
import com.idormy.sms.forwarder.utils.MMKVUtils import com.idormy.sms.forwarder.utils.MMKVUtils
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xui.utils.ResUtils.getString import com.xuexiang.xui.utils.ResUtils.getString
//飞书企业应用 //飞书企业应用
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class FeishuAppUtils private constructor() { class FeishuAppUtils private constructor() {
companion object { companion object {
private val TAG: String = FeishuAppUtils::class.java.simpleName private val TAG: String = FeishuAppUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: FeishuAppSetting, setting: FeishuAppSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val accessToken: String? = MMKVUtils.getString("feishu_access_token_" + setting.appId, "") val accessToken: String? = MMKVUtils.getString("feishu_access_token_" + setting.appId, "")
val expiresIn: Long = MMKVUtils.getLong("feishu_expires_in_" + setting.appId, 0L) val expiresIn: Long = MMKVUtils.getLong("feishu_expires_in_" + setting.appId, 0L)
if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) {
return sendTextMsg(setting, msgInfo, rule, logId) return sendTextMsg(setting, msgInfo, rule, logId)
} }
val requestUrl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" val requestUrl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
Log.d(TAG, "requestUrl$requestUrl") Log.d(TAG, "requestUrl$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["app_id"] = setting.appId msgMap["app_id"] = setting.appId
msgMap["app_secret"] = setting.appSecret msgMap["app_secret"] = setting.appSecret
val requestMsg: String = Gson().toJson(msgMap) val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.keepJson(true) .keepJson(true)
.ignoreHttpsCert() .ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, FeishuAppResult::class.java) val resp = Gson().fromJson(response, FeishuAppResult::class.java)
if (!TextUtils.isEmpty(resp.tenant_access_token)) { if (!TextUtils.isEmpty(resp?.tenant_access_token)) {
MMKVUtils.put("feishu_access_token_" + setting.appId, 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分钟过期 MMKVUtils.put("feishu_expires_in_" + setting.appId, System.currentTimeMillis() + ((resp.expire ?: 7010) - 120) * 1000L) //提前2分钟过期
sendTextMsg(setting, msgInfo, rule, logId) sendTextMsg(setting, msgInfo, rule, logId)
} else { } else {
SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response))
} }
} }
}) })
} }
//发送文本消息 //发送文本消息
private fun sendTextMsg( private fun sendTextMsg(
setting: FeishuAppSetting, setting: FeishuAppSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id"
Log.d(TAG, "requestUrl$requestUrl") Log.d(TAG, "requestUrl$requestUrl")
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val msgContent = if ("interactive" == setting.msgType) { val msgContent = if ("interactive" == setting.msgType) {
val title = if (rule != null) { val title = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate, rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate) msgInfo.getTitleForSend(setting.titleTemplate)
} }
"{\"elements\":[{\"tag\":\"markdown\",\"content\":\"**[{{MSG_TITLE}}]({{MSG_URL}})**\\n --------------\\n{{MSG_CONTENT}}\"}]}".trimIndent().replace("{{MSG_TITLE}}", jsonInnerStr(title)) "{\"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_URL}}", jsonInnerStr("https://github.com/pppscn/SmsForwarder"))
.replace("{{MSG_CONTENT}}", jsonInnerStr(content)) .replace("{{MSG_CONTENT}}", jsonInnerStr(content))
} else { } else {
"{\"text\":\"{{MSG_CONTENT}}\"}".trimIndent().replace("{{MSG_CONTENT}}", jsonInnerStr(content)) "{\"text\":\"{{MSG_CONTENT}}\"}".trimIndent().replace("{{MSG_CONTENT}}", jsonInnerStr(content))
} }
val textMsgMap: MutableMap<String, Any> = mutableMapOf() val textMsgMap: MutableMap<String, Any> = mutableMapOf()
textMsgMap["receive_id"] = setting.receiveId textMsgMap["receive_id"] = setting.receiveId
textMsgMap["msg_type"] = setting.msgType textMsgMap["msg_type"] = setting.msgType
textMsgMap["content"] = msgContent textMsgMap["content"] = msgContent
val requestMsg: String = Gson().toJson(textMsgMap) val requestMsg: String = Gson().toJson(textMsgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.headers("Authorization", "Bearer " + MMKVUtils.getString("feishu_access_token_" + setting.appId, "")) .headers("Authorization", "Bearer " + MMKVUtils.getString("feishu_access_token_" + setting.appId, ""))
.keepJson(true) .keepJson(true)
//.ignoreHttpsCert() //.ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
//Log.d(TAG, "tlsVersion=" + response.handshake().tlsVersion()) //Log.d(TAG, "tlsVersion=" + response.handshake().tlsVersion())
//Log.d(TAG, "cipherSuite=" + response.handshake().cipherSuite().toString()) //Log.d(TAG, "cipherSuite=" + response.handshake().cipherSuite().toString())
val resp = Gson().fromJson(response, FeishuAppResult::class.java) val resp = Gson().fromJson(response, FeishuAppResult::class.java)
if (resp.code == 0L) { if (resp?.code == 0L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: FeishuAppSetting, msgInfo: MsgInfo) { fun sendMsg(setting: FeishuAppSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
private fun jsonInnerStr(string: String?): String { private fun jsonInnerStr(string: String?): String {
if (string == null) return "null" if (string == null) return "null"
val jsonStr: String = Gson().toJson(string) val jsonStr: String = Gson().toJson(string)
return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr
} }
} }
} }

View File

@ -1,187 +1,187 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.FeishuResult import com.idormy.sms.forwarder.entity.result.FeishuResult
import com.idormy.sms.forwarder.entity.setting.FeishuSetting import com.idormy.sms.forwarder.entity.setting.FeishuSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import javax.crypto.Mac import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class FeishuUtils private constructor() { class FeishuUtils private constructor() {
companion object { companion object {
private val TAG: String = FeishuUtils::class.java.simpleName private val TAG: String = FeishuUtils::class.java.simpleName
private val MSG_TEMPLATE = """ private val MSG_TEMPLATE = """
{ {
"config": { "config": {
"wide_screen_mode": true "wide_screen_mode": true
}, },
"elements": [ "elements": [
{ {
"fields": [ "fields": [
{ {
"is_short": true, "is_short": true,
"text": { "text": {
"content": "**时间**\n{{MSG_TIME}}", "content": "**时间**\n{{MSG_TIME}}",
"tag": "lark_md" "tag": "lark_md"
} }
}, },
{ {
"is_short": true, "is_short": true,
"text": { "text": {
"content": "**来源**\n{{MSG_FROM}}", "content": "**来源**\n{{MSG_FROM}}",
"tag": "lark_md" "tag": "lark_md"
} }
} }
], ],
"tag": "div" "tag": "div"
}, },
{ {
"tag": "div", "tag": "div",
"text": { "text": {
"content": "{{MSG_CONTENT}}", "content": "{{MSG_CONTENT}}",
"tag": "lark_md" "tag": "lark_md"
} }
}, },
{ {
"tag": "hr" "tag": "hr"
}, },
{ {
"elements": [ "elements": [
{ {
"content": "[SmsForwarder](https://github.com/pppscn/SmsForwarder)", "content": "[SmsForwarder](https://github.com/pppscn/SmsForwarder)",
"tag": "lark_md" "tag": "lark_md"
} }
], ],
"tag": "note" "tag": "note"
} }
], ],
"header": { "header": {
"template": "turquoise", "template": "turquoise",
"title": { "title": {
"content": "{{MSG_TITLE}}", "content": "{{MSG_TITLE}}",
"tag": "plain_text" "tag": "plain_text"
} }
} }
} }
""".trimIndent() """.trimIndent()
fun sendMsg( fun sendMsg(
setting: FeishuSetting, setting: FeishuSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val from: String = msgInfo.from val from: String = msgInfo.from
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate.toString())
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val requestUrl = setting.webhook val requestUrl = setting.webhook
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
if (setting.secret != null) { if (setting.secret != null) {
val timestamp = System.currentTimeMillis() / 1000 val timestamp = System.currentTimeMillis() / 1000
val stringToSign = "$timestamp\n" + setting.secret val stringToSign = "$timestamp\n" + setting.secret
Log.i(TAG, "stringToSign = $stringToSign") Log.i(TAG, "stringToSign = $stringToSign")
//使用HmacSHA256算法计算签名 //使用HmacSHA256算法计算签名
val mac = Mac.getInstance("HmacSHA256") val mac = Mac.getInstance("HmacSHA256")
mac.init(SecretKeySpec(stringToSign.toByteArray(StandardCharsets.UTF_8), "HmacSHA256")) mac.init(SecretKeySpec(stringToSign.toByteArray(StandardCharsets.UTF_8), "HmacSHA256"))
val signData = mac.doFinal(byteArrayOf()) val signData = mac.doFinal(byteArrayOf())
val sign = String(Base64.encode(signData, Base64.NO_WRAP)) val sign = String(Base64.encode(signData, Base64.NO_WRAP))
msgMap["timestamp"] = timestamp msgMap["timestamp"] = timestamp
msgMap["sign"] = sign msgMap["sign"] = sign
} }
//组装报文 //组装报文
val requestMsg: String val requestMsg: String
if (setting.msgType == null || setting.msgType == "interactive") { if (setting.msgType == null || setting.msgType == "interactive") {
msgMap["msg_type"] = "interactive" msgMap["msg_type"] = "interactive"
msgMap["card"] = "{{CARD_BODY}}" msgMap["card"] = "{{CARD_BODY}}"
requestMsg = Gson().toJson(msgMap).replace("\"{{CARD_BODY}}\"", buildMsg(title, content, from, msgInfo.date)) requestMsg = Gson().toJson(msgMap).replace("\"{{CARD_BODY}}\"", buildMsg(title, content, from, msgInfo.date))
} else { } else {
msgMap["msg_type"] = "text" msgMap["msg_type"] = "text"
val contentMap: MutableMap<String, Any> = mutableMapOf() val contentMap: MutableMap<String, Any> = mutableMapOf()
contentMap["text"] = content contentMap["text"] = content
msgMap["content"] = contentMap msgMap["content"] = contentMap
requestMsg = Gson().toJson(msgMap) requestMsg = Gson().toJson(msgMap)
} }
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.keepJson(true) .keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, FeishuResult::class.java) val resp = Gson().fromJson(response, FeishuResult::class.java)
if (resp.code == 0L) { if (resp?.code == 0L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
private fun buildMsg(title: String, content: String, from: String, date: Date): String { private fun buildMsg(title: String, content: String, from: String, date: Date): String {
val msgTitle = jsonInnerStr(title) val msgTitle = jsonInnerStr(title)
val msgContent = jsonInnerStr(content) val msgContent = jsonInnerStr(content)
val msgFrom = jsonInnerStr(from) val msgFrom = jsonInnerStr(from)
val msgTime = jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(date)) val msgTime = jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(date))
return MSG_TEMPLATE.replace("{{MSG_TITLE}}", msgTitle) return MSG_TEMPLATE.replace("{{MSG_TITLE}}", msgTitle)
.replace("{{MSG_TIME}}", msgTime) .replace("{{MSG_TIME}}", msgTime)
.replace("{{MSG_FROM}}", msgFrom) .replace("{{MSG_FROM}}", msgFrom)
.replace("{{MSG_CONTENT}}", msgContent) .replace("{{MSG_CONTENT}}", msgContent)
} }
private fun jsonInnerStr(string: String?): String { private fun jsonInnerStr(string: String?): String {
if (string == null) return "null" if (string == null) return "null"
val jsonStr: String = Gson().toJson(string) val jsonStr: String = Gson().toJson(string)
return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr
} }
fun sendMsg(setting: FeishuSetting, msgInfo: MsgInfo) { fun sendMsg(setting: FeishuSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,105 +1,105 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.PushplusResult import com.idormy.sms.forwarder.entity.result.PushplusResult
import com.idormy.sms.forwarder.entity.setting.PushplusSetting import com.idormy.sms.forwarder.entity.setting.PushplusSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class PushplusUtils private constructor() { class PushplusUtils private constructor() {
companion object { companion object {
private val TAG: String = PushplusUtils::class.java.simpleName private val TAG: String = PushplusUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: PushplusSetting, setting: PushplusSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val title: String = if (rule != null) { val title: String = if (rule != null) {
msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace) msgInfo.getTitleForSend(setting.titleTemplate.toString(), rule.regexReplace)
} else { } else {
msgInfo.getTitleForSend(setting.titleTemplate.toString()) msgInfo.getTitleForSend(setting.titleTemplate.toString())
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val requestUrl = "https://" + setting.website + "/send" val requestUrl = "https://" + setting.website + "/send"
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["token"] = setting.token msgMap["token"] = setting.token
msgMap["content"] = content msgMap["content"] = content
if (!TextUtils.isEmpty(title)) msgMap["title"] = title if (!TextUtils.isEmpty(title)) msgMap["title"] = title
if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template.toString() if (!TextUtils.isEmpty(setting.template)) msgMap["template"] = setting.template.toString()
if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic.toString() if (!TextUtils.isEmpty(setting.topic)) msgMap["topic"] = setting.topic.toString()
if (setting.website == ResUtils.getString(R.string.pushplus_plus)) { if (setting.website == ResUtils.getString(R.string.pushplus_plus)) {
if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel.toString() if (!TextUtils.isEmpty(setting.channel)) msgMap["channel"] = setting.channel.toString()
if (!TextUtils.isEmpty(setting.webhook)) msgMap["webhook"] = setting.webhook.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.callbackUrl)) msgMap["callbackUrl"] = setting.callbackUrl.toString()
if (!TextUtils.isEmpty(setting.validTime)) { if (!TextUtils.isEmpty(setting.validTime)) {
val validTime = setting.validTime?.toInt() val validTime = setting.validTime?.toInt()
if (validTime != null && validTime > 0) { if (validTime != null && validTime > 0) {
msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L msgMap["timestamp"] = System.currentTimeMillis() + validTime * 1000L
} }
} }
} }
val requestMsg: String = Gson().toJson(msgMap) val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.keepJson(true) .keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, PushplusResult::class.java) val resp = Gson().fromJson(response, PushplusResult::class.java)
if (resp.code == 200L) { if (resp?.code == 200L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: PushplusSetting, msgInfo: MsgInfo) { fun sendMsg(setting: PushplusSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,159 +1,159 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.TelegramResult import com.idormy.sms.forwarder.entity.result.TelegramResult
import com.idormy.sms.forwarder.entity.setting.TelegramSetting import com.idormy.sms.forwarder.entity.setting.TelegramSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xutil.net.NetworkUtils import com.xuexiang.xutil.net.NetworkUtils
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Response import okhttp3.Response
import okhttp3.Route import okhttp3.Route
import java.net.* import java.net.*
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused")
class TelegramUtils private constructor() { class TelegramUtils private constructor() {
companion object { companion object {
private val TAG: String = TelegramUtils::class.java.simpleName private val TAG: String = TelegramUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: TelegramSetting, setting: TelegramSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
if (setting.method == null || setting.method == "POST") { if (setting.method == null || setting.method == "POST") {
msgInfo.content = htmlEncode(msgInfo.content) msgInfo.content = htmlEncode(msgInfo.content)
msgInfo.simInfo = htmlEncode(msgInfo.simInfo) msgInfo.simInfo = htmlEncode(msgInfo.simInfo)
} }
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
var requestUrl = if (setting.apiToken.startsWith("http")) { var requestUrl = if (setting.apiToken.startsWith("http")) {
setting.apiToken setting.apiToken
} else { } else {
"https://api.telegram.org/bot" + setting.apiToken + "/sendMessage" "https://api.telegram.org/bot" + setting.apiToken + "/sendMessage"
} }
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val request = if (setting.method != null && setting.method == "GET") { val request = if (setting.method != null && setting.method == "GET") {
requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8") requestUrl += "?chat_id=" + setting.chatId + "&text=" + URLEncoder.encode(content, "UTF-8")
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
XHttp.get(requestUrl) XHttp.get(requestUrl)
} else { } else {
val bodyMap: MutableMap<String, Any> = mutableMapOf() val bodyMap: MutableMap<String, Any> = mutableMapOf()
bodyMap["chat_id"] = setting.chatId bodyMap["chat_id"] = setting.chatId
bodyMap["text"] = content bodyMap["text"] = content
bodyMap["parse_mode"] = "HTML" bodyMap["parse_mode"] = "HTML"
bodyMap["disable_web_page_preview"] = "true" bodyMap["disable_web_page_preview"] = "true"
val requestMsg: String = Gson().toJson(bodyMap) val requestMsg: String = Gson().toJson(bodyMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl).upJson(requestMsg) XHttp.post(requestUrl).upJson(requestMsg)
} }
//设置代理 //设置代理
if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS)
&& !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort)
) { ) {
//代理服务器的IP和端口号 //代理服务器的IP和端口号
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost") throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost")
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator == true
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString())
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray())
} }
}) })
} }
} }
} }
request.keepJson(true) request.keepJson(true)
//.ignoreHttpsCert() //.ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, TelegramResult::class.java) val resp = Gson().fromJson(response, TelegramResult::class.java)
if (resp.ok == true) { if (resp?.ok == true) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: TelegramSetting, msgInfo: MsgInfo) { fun sendMsg(setting: TelegramSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
private fun htmlEncode(source: String?): String { private fun htmlEncode(source: String?): String {
if (source == null) { if (source == null) {
return "" return ""
} }
val buffer = StringBuffer() val buffer = StringBuffer()
for (element in source) { for (element in source) {
when (element) { when (element) {
'<' -> buffer.append("&lt;") '<' -> buffer.append("&lt;")
'>' -> buffer.append("&gt;") '>' -> buffer.append("&gt;")
'&' -> buffer.append("&amp;") '&' -> buffer.append("&amp;")
'"' -> buffer.append("&quot;") '"' -> buffer.append("&quot;")
//10, 13 -> buffer.append("\n") //10, 13 -> buffer.append("\n")
else -> buffer.append(element) else -> buffer.append(element)
} }
} }
return buffer.toString() return buffer.toString()
} }
} }
} }

View File

@ -1,226 +1,226 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.DingtalkResult import com.idormy.sms.forwarder.entity.result.DingtalkResult
import com.idormy.sms.forwarder.entity.result.WeworkAgentResult import com.idormy.sms.forwarder.entity.result.WeworkAgentResult
import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting import com.idormy.sms.forwarder.entity.setting.WeworkAgentSetting
import com.idormy.sms.forwarder.utils.MMKVUtils import com.idormy.sms.forwarder.utils.MMKVUtils
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xui.utils.ResUtils.getString import com.xuexiang.xui.utils.ResUtils.getString
import com.xuexiang.xutil.net.NetworkUtils import com.xuexiang.xutil.net.NetworkUtils
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Response import okhttp3.Response
import okhttp3.Route import okhttp3.Route
import java.net.Authenticator import java.net.Authenticator
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.PasswordAuthentication import java.net.PasswordAuthentication
import java.net.Proxy import java.net.Proxy
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class WeworkAgentUtils private constructor() { class WeworkAgentUtils private constructor() {
companion object { companion object {
private val TAG: String = WeworkAgentUtils::class.java.simpleName private val TAG: String = WeworkAgentUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: WeworkAgentSetting, setting: WeworkAgentSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val accessToken: String? = MMKVUtils.getString("access_token_" + setting.agentID, "") val accessToken: String? = MMKVUtils.getString("access_token_" + setting.agentID, "")
val expiresIn: Long = MMKVUtils.getLong("expires_in_" + setting.agentID, 0L) val expiresIn: Long = MMKVUtils.getLong("expires_in_" + setting.agentID, 0L)
if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) { if (!TextUtils.isEmpty(accessToken) && expiresIn > System.currentTimeMillis()) {
return sendTextMsg(setting, msgInfo, rule, logId) return sendTextMsg(setting, msgInfo, rule, logId)
} }
var getTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" var getTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
getTokenUrl += "corpid=" + setting.corpID getTokenUrl += "corpid=" + setting.corpID
getTokenUrl += "&corpsecret=" + setting.secret getTokenUrl += "&corpsecret=" + setting.secret
Log.d(TAG, "getTokenUrl$getTokenUrl") Log.d(TAG, "getTokenUrl$getTokenUrl")
val request = XHttp.get(getTokenUrl) val request = XHttp.get(getTokenUrl)
//设置代理 //设置代理
if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS)
&& !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort)
) { ) {
//代理服务器的IP和端口号 //代理服务器的IP和端口号
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost") throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost")
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator == true
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString())
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray())
} }
}) })
} }
} }
} }
request.keepJson(true) request.keepJson(true)
.ignoreHttpsCert() .ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, WeworkAgentResult::class.java) val resp = Gson().fromJson(response, WeworkAgentResult::class.java)
if (resp.errcode == 0L) { if (resp?.errcode == 0L) {
MMKVUtils.put("access_token_" + setting.agentID, resp.access_token) MMKVUtils.put("access_token_" + setting.agentID, resp.access_token)
MMKVUtils.put("expires_in_" + setting.agentID, System.currentTimeMillis() + ((resp.expires_in ?: 7200) - 120) * 1000L) //提前2分钟过期 MMKVUtils.put("expires_in_" + setting.agentID, System.currentTimeMillis() + ((resp.expires_in ?: 7200) - 120) * 1000L) //提前2分钟过期
sendTextMsg(setting, msgInfo, rule, logId) sendTextMsg(setting, msgInfo, rule, logId)
} else { } else {
SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response)) SendUtils.updateLogs(logId, 0, String.format(getString(R.string.request_failed_tips), response))
} }
} }
}) })
} }
//发送文本消息 //发送文本消息
private fun sendTextMsg( private fun sendTextMsg(
setting: WeworkAgentSetting, setting: WeworkAgentSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val textMsgMap: MutableMap<String, Any> = mutableMapOf() val textMsgMap: MutableMap<String, Any> = mutableMapOf()
textMsgMap["touser"] = setting.toUser.toString() textMsgMap["touser"] = setting.toUser.toString()
textMsgMap["toparty"] = setting.toParty.toString() textMsgMap["toparty"] = setting.toParty.toString()
textMsgMap["totag"] = setting.toTag.toString() textMsgMap["totag"] = setting.toTag.toString()
textMsgMap["msgtype"] = "text" textMsgMap["msgtype"] = "text"
textMsgMap["agentid"] = setting.agentID textMsgMap["agentid"] = setting.agentID
val textText: MutableMap<String, Any> = mutableMapOf() val textText: MutableMap<String, Any> = mutableMapOf()
textText["content"] = content textText["content"] = content
textMsgMap["text"] = textText textMsgMap["text"] = textText
val requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + MMKVUtils.getString("access_token_" + setting.agentID, "") val requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + MMKVUtils.getString("access_token_" + setting.agentID, "")
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val requestMsg: String = Gson().toJson(textMsgMap) val requestMsg: String = Gson().toJson(textMsgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
val request = XHttp.post(requestUrl) val request = XHttp.post(requestUrl)
//设置代理 //设置代理
if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS) if ((setting.proxyType == Proxy.Type.HTTP || setting.proxyType == Proxy.Type.SOCKS)
&& !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort) && !TextUtils.isEmpty(setting.proxyHost) && !TextUtils.isEmpty(setting.proxyPort)
) { ) {
//代理服务器的IP和端口号 //代理服务器的IP和端口号
Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}") Log.d(TAG, "proxyHost = ${setting.proxyHost}, proxyPort = ${setting.proxyPort}")
val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost) val proxyHost = if (NetworkUtils.isIP(setting.proxyHost)) setting.proxyHost else NetworkUtils.getDomainAddress(setting.proxyHost)
if (!NetworkUtils.isIP(proxyHost)) { if (!NetworkUtils.isIP(proxyHost)) {
throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost") throw Exception("代理服务器主机名解析失败proxyHost=$proxyHost")
} }
val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890 val proxyPort: Int = setting.proxyPort?.toInt() ?: 7890
Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort") Log.d(TAG, "proxyHost = $proxyHost, proxyPort = $proxyPort")
request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort))) request.okproxy(Proxy(setting.proxyType, InetSocketAddress(proxyHost, proxyPort)))
//代理的鉴权账号密码 //代理的鉴权账号密码
if (setting.proxyAuthenticator == true if (setting.proxyAuthenticator == true
&& (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword)) && (!TextUtils.isEmpty(setting.proxyUsername) || !TextUtils.isEmpty(setting.proxyPassword))
) { ) {
Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}") Log.i(TAG, "proxyUsername = ${setting.proxyUsername}, proxyPassword = ${setting.proxyPassword}")
if (setting.proxyType == Proxy.Type.HTTP) { if (setting.proxyType == Proxy.Type.HTTP) {
request.okproxyAuthenticator { _: Route?, response: Response -> request.okproxyAuthenticator { _: Route?, response: Response ->
//设置代理服务器账号密码 //设置代理服务器账号密码
val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString()) val credential = Credentials.basic(setting.proxyUsername.toString(), setting.proxyPassword.toString())
response.request().newBuilder() response.request().newBuilder()
.header("Proxy-Authorization", credential) .header("Proxy-Authorization", credential)
.build() .build()
} }
} else { } else {
Authenticator.setDefault(object : Authenticator() { Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray()) return PasswordAuthentication(setting.proxyUsername.toString(), setting.proxyPassword?.toCharArray())
} }
}) })
} }
} }
} }
request.upJson(requestMsg) request.upJson(requestMsg)
.keepJson(true) .keepJson(true)
.ignoreHttpsCert() .ignoreHttpsCert()
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, DingtalkResult::class.java) val resp = Gson().fromJson(response, DingtalkResult::class.java)
if (resp.errcode == 0L) { if (resp?.errcode == 0L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: WeworkAgentSetting, msgInfo: MsgInfo) { fun sendMsg(setting: WeworkAgentSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }

View File

@ -1,82 +1,82 @@
package com.idormy.sms.forwarder.utils.sender package com.idormy.sms.forwarder.utils.sender
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.entity.MsgInfo import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.result.WeworkRobotResult import com.idormy.sms.forwarder.entity.result.WeworkRobotResult
import com.idormy.sms.forwarder.entity.setting.WeworkRobotSetting import com.idormy.sms.forwarder.entity.setting.WeworkRobotSetting
import com.idormy.sms.forwarder.utils.SendUtils import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.cache.model.CacheMode import com.xuexiang.xhttp2.cache.model.CacheMode
import com.xuexiang.xhttp2.callback.SimpleCallBack import com.xuexiang.xhttp2.callback.SimpleCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "UNUSED_PARAMETER")
class WeworkRobotUtils private constructor() { class WeworkRobotUtils private constructor() {
companion object { companion object {
private val TAG: String = WeworkRobotUtils::class.java.simpleName private val TAG: String = WeworkRobotUtils::class.java.simpleName
fun sendMsg( fun sendMsg(
setting: WeworkRobotSetting, setting: WeworkRobotSetting,
msgInfo: MsgInfo, msgInfo: MsgInfo,
rule: Rule?, rule: Rule?,
logId: Long?, logId: Long?,
) { ) {
val content: String = if (rule != null) { val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace) msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else { } else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString()) msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
} }
val requestUrl = setting.webHook val requestUrl = setting.webHook
Log.i(TAG, "requestUrl:$requestUrl") Log.i(TAG, "requestUrl:$requestUrl")
val msgMap: MutableMap<String, Any> = mutableMapOf() val msgMap: MutableMap<String, Any> = mutableMapOf()
msgMap["msgtype"] = "text" msgMap["msgtype"] = "text"
val textText: MutableMap<String, Any> = mutableMapOf() val textText: MutableMap<String, Any> = mutableMapOf()
textText["content"] = content textText["content"] = content
msgMap["text"] = textText msgMap["text"] = textText
val requestMsg: String = Gson().toJson(msgMap) val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg") Log.i(TAG, "requestMsg:$requestMsg")
XHttp.post(requestUrl) XHttp.post(requestUrl)
.upJson(requestMsg) .upJson(requestMsg)
.keepJson(true) .keepJson(true)
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s .timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE) .cacheMode(CacheMode.NO_CACHE)
.retryCount(SettingUtils.requestRetryTimes) //超时重试的次数 .retryCount(SettingUtils.requestRetryTimes) //超时重试的次数
.retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间 .retryDelay(SettingUtils.requestDelayTime) //超时重试的延迟时间
.retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时 .retryIncreaseDelay(SettingUtils.requestDelayTime) //超时重试叠加延时
.timeStamp(true) .timeStamp(true)
.execute(object : SimpleCallBack<String>() { .execute(object : SimpleCallBack<String>() {
override fun onError(e: ApiException) { override fun onError(e: ApiException) {
Log.e(TAG, e.detailMessage) Log.e(TAG, e.detailMessage)
SendUtils.updateLogs(logId, 0, e.displayMessage) SendUtils.updateLogs(logId, 0, e.displayMessage)
} }
override fun onSuccess(response: String) { override fun onSuccess(response: String) {
Log.i(TAG, response) Log.i(TAG, response)
val resp = Gson().fromJson(response, WeworkRobotResult::class.java) val resp = Gson().fromJson(response, WeworkRobotResult::class.java)
if (resp.errcode == 0L) { if (resp?.errcode == 0L) {
SendUtils.updateLogs(logId, 2, response) SendUtils.updateLogs(logId, 2, response)
} else { } else {
SendUtils.updateLogs(logId, 0, response) SendUtils.updateLogs(logId, 0, response)
} }
} }
}) })
} }
fun sendMsg(setting: WeworkRobotSetting, msgInfo: MsgInfo) { fun sendMsg(setting: WeworkRobotSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null) sendMsg(setting, msgInfo, null, null)
} }
} }
} }