mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-02 17:07:41 +08:00
修复:极端情况下Gson().fromJson爆空指针错误 #207
This commit is contained in:
parent
74cbddc192
commit
9d75554df0
@ -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<String>() {
|
||||
|
||||
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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String, Any> = mutableMapOf()
|
||||
msgMap["msgtype"] = "text"
|
||||
|
||||
val textText: MutableMap<String, Any> = mutableMapOf()
|
||||
textText["content"] = content
|
||||
msgMap["text"] = textText
|
||||
|
||||
val atMap: MutableMap<String, Any> = mutableMapOf()
|
||||
msgMap["at"] = atMap
|
||||
if (setting.atAll == true) {
|
||||
atMap["isAtAll"] = true
|
||||
} else {
|
||||
atMap["isAtAll"] = false
|
||||
if (!TextUtils.isEmpty(setting.atMobiles)) {
|
||||
val atMobilesArray: Array<String>? = setting.atMobiles?.split(",".toRegex())?.toTypedArray()
|
||||
if (atMobilesArray != null) {
|
||||
val atMobilesList: MutableList<String> = 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<String>() {
|
||||
|
||||
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<String, Any> = mutableMapOf()
|
||||
msgMap["msgtype"] = "text"
|
||||
|
||||
val textText: MutableMap<String, Any> = mutableMapOf()
|
||||
textText["content"] = content
|
||||
msgMap["text"] = textText
|
||||
|
||||
val atMap: MutableMap<String, Any> = mutableMapOf()
|
||||
msgMap["at"] = atMap
|
||||
if (setting.atAll == true) {
|
||||
atMap["isAtAll"] = true
|
||||
} else {
|
||||
atMap["isAtAll"] = false
|
||||
if (!TextUtils.isEmpty(setting.atMobiles)) {
|
||||
val atMobilesArray: Array<String>? = setting.atMobiles?.split(",".toRegex())?.toTypedArray()
|
||||
if (atMobilesArray != null) {
|
||||
val atMobilesList: MutableList<String> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = 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<String>() {
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String>() {
|
||||
|
||||
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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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<String>() {
|
||||
|
||||
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<String, Any> = 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<String, Any> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<String, Any> = mutableMapOf()
|
||||
msgMap["msgtype"] = "text"
|
||||
|
||||
val textText: MutableMap<String, Any> = 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<String>() {
|
||||
|
||||
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<String, Any> = mutableMapOf()
|
||||
msgMap["msgtype"] = "text"
|
||||
|
||||
val textText: MutableMap<String, Any> = 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<String>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user