整理:code review

This commit is contained in:
pppscn 2023-02-01 10:51:17 +08:00
parent 992fc2eb8c
commit e1660fe9bb
16 changed files with 713 additions and 714 deletions

View File

@ -1,174 +1,174 @@
package com.idormy.sms.forwarder.service
import android.app.*
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.lifecycle.Observer
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.utils.*
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xutil.file.FileUtils
import frpclib.Frpclib
import io.reactivex.Single
import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@Suppress("PrivatePropertyName", "DeferredResultUnused", "OPT_IN_USAGE")
class ForegroundService : Service() {
private val TAG: String = "ForegroundService"
private val compositeDisposable = CompositeDisposable()
private val frpcObserver = Observer { uid: String ->
if (Frpclib.isRunning(uid)) {
return@Observer
}
AppDatabase.getInstance(App.context)
.frpcDao()
.get(uid)
.flatMap { (uid1, _, config) ->
val error = Frpclib.runContent(uid1, config)
Single.just(error)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<String> {
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onError(e: Throwable) {
e.printStackTrace()
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
}
override fun onSuccess(msg: String) {
if (!TextUtils.isEmpty(msg)) {
Log.e(TAG, msg)
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
} else {
LiveEventBus.get(EVENT_FRPC_RUNNING_SUCCESS, String::class.java).post(uid)
}
}
})
}
private var notificationManager: NotificationManager? = null
companion object {
var isRunning = false
}
override fun onCreate() {
super.onCreate()
try {
//纯客户端模式
if (SettingUtils.enablePureClientMode) return
notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
startForeground(FRONT_NOTIFY_ID, createForegroundNotification())
//开关通知监听服务
if (SettingUtils.enableAppNotify && CommonUtils.isNotificationListenerServiceEnabled(this)) {
CommonUtils.toggleNotificationListenerService(this)
}
if (FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
//监听Frpc启动指令
LiveEventBus.get(INTENT_FRPC_APPLY_FILE, String::class.java).observeStickyForever(frpcObserver)
//自启动的Frpc
GlobalScope.async(Dispatchers.IO) {
val frpcList = AppDatabase.getInstance(App.context).frpcDao().getAutorun()
if (frpcList.isEmpty()) {
Log.d(TAG, "没有自启动的Frpc")
return@async
}
for (frpc in frpcList) {
val error = Frpclib.runContent(frpc.uid, frpc.config)
if (!TextUtils.isEmpty(error)) {
Log.e(TAG, error)
}
}
}
}
isRunning = true
} catch (e: Exception) {
e.printStackTrace()
isRunning = false
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
isRunning = true
return START_STICKY
}
override fun onDestroy() {
//纯客户端模式
if (SettingUtils.enablePureClientMode) {
super.onDestroy()
return
}
try {
stopForeground(true)
compositeDisposable.dispose()
isRunning = false
} catch (e: Exception) {
e.printStackTrace()
}
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
private fun createForegroundNotification(): Notification {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val notificationChannel = NotificationChannel(FRONT_CHANNEL_ID, FRONT_CHANNEL_NAME, importance)
notificationChannel.description = "Frpc Foreground Service"
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.vibrationPattern = longArrayOf(0, 1000, 500, 1000)
notificationChannel.enableVibration(true)
if (notificationManager != null) {
notificationManager!!.createNotificationChannel(notificationChannel)
}
}
val builder = NotificationCompat.Builder(this, FRONT_CHANNEL_ID)
builder.setSmallIcon(R.drawable.ic_forwarder)
builder.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_menu_frpc))
// TODO: 部分机型标题会重复待排除
// if (DeviceUtils.getDeviceBrand().contains("Xiaomi")) {
builder.setContentTitle(getString(R.string.app_name))
//}
builder.setContentText(SettingUtils.notifyContent.toString())
builder.setWhen(System.currentTimeMillis())
val activityIntent = Intent(this, MainActivity::class.java)
val flags = if (Build.VERSION.SDK_INT >= 30) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_UPDATE_CURRENT
val pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, flags)
builder.setContentIntent(pendingIntent)
return builder.build()
}
package com.idormy.sms.forwarder.service
import android.app.*
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.lifecycle.Observer
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.utils.*
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xutil.file.FileUtils
import frpclib.Frpclib
import io.reactivex.Single
import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@Suppress("PrivatePropertyName", "DeferredResultUnused", "OPT_IN_USAGE")
class ForegroundService : Service() {
private val TAG: String = "ForegroundService"
private val compositeDisposable = CompositeDisposable()
private val frpcObserver = Observer { uid: String ->
if (Frpclib.isRunning(uid)) {
return@Observer
}
AppDatabase.getInstance(App.context)
.frpcDao()
.get(uid)
.flatMap { (uid1, _, config) ->
val error = Frpclib.runContent(uid1, config)
Single.just(error)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<String> {
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onError(e: Throwable) {
e.printStackTrace()
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
}
override fun onSuccess(msg: String) {
if (!TextUtils.isEmpty(msg)) {
Log.e(TAG, msg)
LiveEventBus.get(EVENT_FRPC_RUNNING_ERROR, String::class.java).post(uid)
} else {
LiveEventBus.get(EVENT_FRPC_RUNNING_SUCCESS, String::class.java).post(uid)
}
}
})
}
private var notificationManager: NotificationManager? = null
companion object {
var isRunning = false
}
override fun onCreate() {
super.onCreate()
try {
//纯客户端模式
if (SettingUtils.enablePureClientMode) return
notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
startForeground(FRONT_NOTIFY_ID, createForegroundNotification())
//开关通知监听服务
if (SettingUtils.enableAppNotify && CommonUtils.isNotificationListenerServiceEnabled(this)) {
CommonUtils.toggleNotificationListenerService(this)
}
if (FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
//监听Frpc启动指令
LiveEventBus.get(INTENT_FRPC_APPLY_FILE, String::class.java).observeStickyForever(frpcObserver)
//自启动的Frpc
GlobalScope.async(Dispatchers.IO) {
val frpcList = AppDatabase.getInstance(App.context).frpcDao().getAutorun()
if (frpcList.isEmpty()) {
Log.d(TAG, "没有自启动的Frpc")
return@async
}
for (frpc in frpcList) {
val error = Frpclib.runContent(frpc.uid, frpc.config)
if (!TextUtils.isEmpty(error)) {
Log.e(TAG, error)
}
}
}
}
isRunning = true
} catch (e: Exception) {
e.printStackTrace()
isRunning = false
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
isRunning = true
return START_STICKY
}
override fun onDestroy() {
//纯客户端模式
if (SettingUtils.enablePureClientMode) {
super.onDestroy()
return
}
try {
stopForeground(true)
compositeDisposable.dispose()
isRunning = false
} catch (e: Exception) {
e.printStackTrace()
}
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
private fun createForegroundNotification(): Notification {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val notificationChannel = NotificationChannel(FRONT_CHANNEL_ID, FRONT_CHANNEL_NAME, importance)
notificationChannel.description = "Frpc Foreground Service"
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.vibrationPattern = longArrayOf(0, 1000, 500, 1000)
notificationChannel.enableVibration(true)
if (notificationManager != null) {
notificationManager!!.createNotificationChannel(notificationChannel)
}
}
val builder = NotificationCompat.Builder(this, FRONT_CHANNEL_ID)
builder.setSmallIcon(R.drawable.ic_forwarder)
builder.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_menu_frpc))
// TODO: 部分机型标题会重复待排除
// if (DeviceUtils.getDeviceBrand().contains("Xiaomi")) {
builder.setContentTitle(getString(R.string.app_name))
//}
builder.setContentText(SettingUtils.notifyContent)
builder.setWhen(System.currentTimeMillis())
val activityIntent = Intent(this, MainActivity::class.java)
val flags = if (Build.VERSION.SDK_INT >= 30) PendingIntent.FLAG_IMMUTABLE else PendingIntent.FLAG_UPDATE_CURRENT
val pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, flags)
builder.setContentIntent(pendingIntent)
return builder.build()
}
}

View File

@ -35,7 +35,7 @@ class BarkUtils {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val requestUrl: String = setting.server //推送地址

View File

@ -35,7 +35,7 @@ class DingtalkGroupRobotUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
var requestUrl = if (setting.token.startsWith("http")) setting.token else "https://oapi.dingtalk.com/robot/send?access_token=" + setting.token

View File

@ -126,7 +126,7 @@ class DingtalkInnerRobotUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val msgParam: MutableMap<String, Any> = mutableMapOf()

View File

@ -1,151 +1,151 @@
package com.idormy.sms.forwarder.utils.sender
import android.util.Log
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.setting.EmailSetting
import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.mail.Mail
import com.idormy.sms.forwarder.utils.mail.MailSender
import com.xuexiang.xui.utils.ResUtils
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused")
class EmailUtils {
companion object {
private val TAG: String = EmailUtils::class.java.simpleName
fun sendMsg(
setting: EmailSetting,
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 message: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
}
//常用邮箱类型的转换
when (setting.mailType) {
"@qq.com", "@foxmail.com" -> {
setting.host = "smtp.qq.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@exmail.qq.com" -> {
setting.host = "smtp.exmail.qq.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@msn.com" -> {
setting.host = "smtp-mail.outlook.com"
setting.port = "587"
setting.ssl = false
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@outlook.com", "@office365.com", "@live.com", "@hotmail.com" -> {
setting.host = "smtp.office365.com"
setting.port = "587"
setting.ssl = false
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@gmail.com" -> {
setting.host = "smtp.gmail.com"
setting.port = "587"
setting.ssl = true
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@yeah.net" -> {
setting.host = "smtp.yeah.net"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@163.com" -> {
setting.host = "smtp.163.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@126.com" -> {
setting.host = "smtp.126.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@sina.com" -> {
setting.host = "smtp.sina.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@sina.cn" -> {
setting.host = "smtp.sina.cn"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@139.com" -> {
setting.host = "smtp.139.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@189.cn" -> {
setting.host = "smtp.189.cn"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
else -> {}
}
//收件地址
val toAddressList = setting.toEmail.toString().replace("[,;]".toRegex(), ",").trim(',').split(',')
//创建邮箱
val mail = Mail().apply {
mailServerHost = setting.host.toString()
mailServerPort = setting.port.toString()
fromAddress = setting.fromEmail.toString()
fromNickname = msgInfo.getTitleForSend(setting.nickname.toString())
password = setting.pwd.toString()
toAddress = toAddressList
subject = title
content = message.replace("\n", "<br>")
openSSL = setting.ssl == true
startTls = setting.startTls == true
}
MailSender.getInstance().sendMail(mail, object : MailSender.OnMailSendListener {
override fun onError(e: Throwable) {
Log.e("MailSender", e.message.toString())
SendUtils.updateLogs(logId, 0, e.message.toString())
}
override fun onSuccess() {
SendUtils.updateLogs(logId, 2, ResUtils.getString(R.string.request_succeeded))
}
})
}
fun sendMsg(setting: EmailSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
package com.idormy.sms.forwarder.utils.sender
import android.util.Log
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.setting.EmailSetting
import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.mail.Mail
import com.idormy.sms.forwarder.utils.mail.MailSender
import com.xuexiang.xui.utils.ResUtils
@Suppress("PrivatePropertyName", "UNUSED_PARAMETER", "unused")
class EmailUtils {
companion object {
private val TAG: String = EmailUtils::class.java.simpleName
fun sendMsg(
setting: EmailSetting,
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 message: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
//常用邮箱类型的转换
when (setting.mailType) {
"@qq.com", "@foxmail.com" -> {
setting.host = "smtp.qq.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@exmail.qq.com" -> {
setting.host = "smtp.exmail.qq.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@msn.com" -> {
setting.host = "smtp-mail.outlook.com"
setting.port = "587"
setting.ssl = false
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@outlook.com", "@office365.com", "@live.com", "@hotmail.com" -> {
setting.host = "smtp.office365.com"
setting.port = "587"
setting.ssl = false
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@gmail.com" -> {
setting.host = "smtp.gmail.com"
setting.port = "587"
setting.ssl = true
setting.startTls = true
setting.fromEmail += setting.mailType
}
"@yeah.net" -> {
setting.host = "smtp.yeah.net"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@163.com" -> {
setting.host = "smtp.163.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@126.com" -> {
setting.host = "smtp.126.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@sina.com" -> {
setting.host = "smtp.sina.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@sina.cn" -> {
setting.host = "smtp.sina.cn"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@139.com" -> {
setting.host = "smtp.139.com"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
"@189.cn" -> {
setting.host = "smtp.189.cn"
setting.port = "465"
setting.ssl = true
setting.fromEmail += setting.mailType
}
else -> {}
}
//收件地址
val toAddressList = setting.toEmail.toString().replace("[,;]".toRegex(), ",").trim(',').split(',')
//创建邮箱
val mail = Mail().apply {
mailServerHost = setting.host.toString()
mailServerPort = setting.port.toString()
fromAddress = setting.fromEmail.toString()
fromNickname = msgInfo.getTitleForSend(setting.nickname.toString())
password = setting.pwd.toString()
toAddress = toAddressList
subject = title
content = message.replace("\n", "<br>")
openSSL = setting.ssl == true
startTls = setting.startTls == true
}
MailSender.getInstance().sendMail(mail, object : MailSender.OnMailSendListener {
override fun onError(e: Throwable) {
Log.e("MailSender", e.message.toString())
SendUtils.updateLogs(logId, 0, e.message.toString())
}
override fun onSuccess() {
SendUtils.updateLogs(logId, 2, ResUtils.getString(R.string.request_succeeded))
}
})
}
fun sendMsg(setting: EmailSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
}

View File

@ -84,7 +84,7 @@ class FeishuAppUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val msgContent = if ("interactive" == setting.msgType) {

View File

@ -94,7 +94,7 @@ class FeishuUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val requestUrl = setting.webhook

View File

@ -1,89 +1,89 @@
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.GotifyResult
import com.idormy.sms.forwarder.entity.setting.GotifySetting
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", "unused")
class GotifyUtils {
companion object {
private val TAG: String = GotifyUtils::class.java.simpleName
fun sendMsg(
setting: GotifySetting,
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.webServer //推送地址
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("message", content)
.params("priority", setting.priority)
.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, GotifyResult::class.java)
if (resp?.id != null) {
SendUtils.updateLogs(logId, 2, response)
} else {
SendUtils.updateLogs(logId, 0, response)
}
}
})
}
fun sendMsg(setting: GotifySetting, 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.GotifyResult
import com.idormy.sms.forwarder.entity.setting.GotifySetting
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", "unused")
class GotifyUtils {
companion object {
private val TAG: String = GotifyUtils::class.java.simpleName
fun sendMsg(
setting: GotifySetting,
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)
}
val requestUrl: String = setting.webServer //推送地址
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("message", content)
.params("priority", setting.priority)
.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, GotifyResult::class.java)
if (resp?.id != null) {
SendUtils.updateLogs(logId, 2, response)
} else {
SendUtils.updateLogs(logId, 0, response)
}
}
})
}
fun sendMsg(setting: GotifySetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
}

View File

@ -37,7 +37,7 @@ class PushplusUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val requestUrl = "https://" + setting.website + "/send"
@ -63,7 +63,6 @@ class PushplusUtils private constructor() {
}
}
val requestMsg: String = Gson().toJson(msgMap)
Log.i(TAG, "requestMsg:$requestMsg")

View File

@ -1,83 +1,83 @@
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.ServerchanResult
import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
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", "unused")
class ServerchanUtils {
companion object {
private val TAG: String = ServerchanUtils::class.java.simpleName
fun sendMsg(
setting: ServerchanSetting,
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: String = String.format("https://sctapi.ftqq.com/%s.send", setting.sendKey) //推送地址
Log.i(TAG, "requestUrl:$requestUrl")
val request = XHttp.post(requestUrl)
.params("title", title)
.params("desp", content)
if (!TextUtils.isEmpty(setting.channel)) request.params("channel", setting.channel)
if (!TextUtils.isEmpty(setting.openid)) request.params("group", setting.openid)
request.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, ServerchanResult::class.java)
if (resp?.code == 0L) {
SendUtils.updateLogs(logId, 2, response)
} else {
SendUtils.updateLogs(logId, 0, response)
}
}
})
}
fun sendMsg(setting: ServerchanSetting, 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.ServerchanResult
import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
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", "unused")
class ServerchanUtils {
companion object {
private val TAG: String = ServerchanUtils::class.java.simpleName
fun sendMsg(
setting: ServerchanSetting,
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)
}
val requestUrl: String = String.format("https://sctapi.ftqq.com/%s.send", setting.sendKey) //推送地址
Log.i(TAG, "requestUrl:$requestUrl")
val request = XHttp.post(requestUrl)
.params("title", title)
.params("desp", content)
if (!TextUtils.isEmpty(setting.channel)) request.params("channel", setting.channel)
if (!TextUtils.isEmpty(setting.openid)) request.params("group", setting.openid)
request.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, ServerchanResult::class.java)
if (resp?.code == 0L) {
SendUtils.updateLogs(logId, 2, response)
} else {
SendUtils.updateLogs(logId, 0, response)
}
}
})
}
fun sendMsg(setting: ServerchanSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
}

View File

@ -40,7 +40,7 @@ class TelegramUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
var requestUrl = if (setting.apiToken.startsWith("http")) {

View File

@ -1,209 +1,209 @@
package com.idormy.sms.forwarder.utils.sender
import android.annotation.SuppressLint
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.setting.WebhookSetting
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.app.AppUtils
import java.net.URLEncoder
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", "unused")
class WebhookUtils {
companion object {
private val TAG: String = WebhookUtils::class.java.simpleName
fun sendMsg(
setting: WebhookSetting,
msgInfo: MsgInfo,
rule: Rule?,
logId: Long?,
) {
val from: String = msgInfo.from
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
}
var requestUrl: String = setting.webServer //推送地址
Log.i(TAG, "requestUrl:$requestUrl")
val timestamp = System.currentTimeMillis()
val orgContent: String = msgInfo.content
val deviceMark: String = SettingUtils.extraDeviceMark ?: ""
val appVersion: String = AppUtils.getAppVersionName()
val simInfo: String = msgInfo.simInfo
@SuppressLint("SimpleDateFormat") val receiveTime =
SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()) //smsVo.getDate()
var sign = ""
if (!TextUtils.isEmpty(setting.secret)) {
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))
sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8")
}
var webParams = setting.webParams?.trim()
//支持HTTP基本认证(Basic Authentication)
val regex = "^(https?://)([^:]+):([^@]+)@(.+)"
val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList()
.flatMap(MatchResult::groupValues)
Log.i(TAG, "matches = $matches")
if (matches.isNotEmpty()) {
requestUrl = matches[1] + matches[4]
Log.i(TAG, "requestUrl:$requestUrl")
}
val request = if (setting.method == "GET" && TextUtils.isEmpty(webParams)) {
setting.webServer += (if (setting.webServer.contains("?")) "&" else "?") + "from=" + URLEncoder.encode(
from,
"UTF-8"
)
requestUrl += "&content=" + URLEncoder.encode(content, "UTF-8")
if (!TextUtils.isEmpty(sign)) {
requestUrl += "&timestamp=$timestamp"
requestUrl += "&sign=$sign"
}
Log.d(TAG, "method = GET, Url = $requestUrl")
XHttp.get(requestUrl).keepJson(true)
} else if (setting.method == "GET" && !TextUtils.isEmpty(webParams)) {
webParams = webParams.toString().replace("[from]", URLEncoder.encode(from, "UTF-8"))
.replace("[content]", URLEncoder.encode(content, "UTF-8"))
.replace("[msg]", URLEncoder.encode(content, "UTF-8"))
.replace("[org_content]", URLEncoder.encode(orgContent, "UTF-8"))
.replace("[device_mark]", URLEncoder.encode(deviceMark, "UTF-8"))
.replace("[app_version]", URLEncoder.encode(appVersion, "UTF-8"))
.replace("[title]", URLEncoder.encode(simInfo, "UTF-8"))
.replace("[card_slot]", URLEncoder.encode(simInfo, "UTF-8"))
.replace("[receive_time]", URLEncoder.encode(receiveTime, "UTF-8"))
.replace("\n", "%0A")
if (!TextUtils.isEmpty(setting.secret)) {
webParams = webParams.replace("[timestamp]", timestamp.toString())
.replace("[sign]", URLEncoder.encode(sign, "UTF-8"))
}
requestUrl += if (webParams.startsWith("/")) {
webParams
} else {
(if (requestUrl.contains("?")) "&" else "?") + webParams
}
Log.d(TAG, "method = GET, Url = $requestUrl")
XHttp.get(requestUrl).keepJson(true)
} else if (webParams != null && webParams.isNotEmpty() && webParams.startsWith("{")) {
val bodyMsg = webParams.replace("[from]", from)
.replace("[content]", escapeJson(content))
.replace("[msg]", escapeJson(content))
.replace("[org_content]", escapeJson(orgContent))
.replace("[device_mark]", escapeJson(deviceMark))
.replace("[app_version]", appVersion)
.replace("[title]", escapeJson(simInfo))
.replace("[card_slot]", escapeJson(simInfo))
.replace("[receive_time]", receiveTime)
.replace("[timestamp]", timestamp.toString())
.replace("[sign]", sign)
Log.d(TAG, "method = ${setting.method}, Url = $requestUrl, bodyMsg = $bodyMsg")
when (setting.method) {
"PUT" -> XHttp.put(requestUrl).keepJson(true).upJson(bodyMsg)
"PATCH" -> XHttp.patch(requestUrl).keepJson(true).upJson(bodyMsg)
else -> XHttp.post(requestUrl).keepJson(true).upJson(bodyMsg)
}
} else {
if (webParams == null || webParams.isEmpty()) {
webParams = "from=[from]&content=[content]&timestamp=[timestamp]"
if (!TextUtils.isEmpty(sign)) webParams += "&sign=[sign]"
}
Log.d(TAG, "method = ${setting.method}, Url = $requestUrl")
val postRequest = when (setting.method) {
"PUT" -> XHttp.put(requestUrl).keepJson(true)
"PATCH" -> XHttp.patch(requestUrl).keepJson(true)
else -> XHttp.post(requestUrl).keepJson(true)
}
webParams.trim('&').split("&").forEach {
val param = it.split("=")
if (param.size == 2) {
postRequest.params(
param[0], param[1].replace("[from]", from)
.replace("[content]", content)
.replace("[msg]", content)
.replace("[org_content]", orgContent)
.replace("[device_mark]", deviceMark)
.replace("[app_version]", appVersion)
.replace("[title]", simInfo)
.replace("[card_slot]", simInfo)
.replace("[receive_time]", receiveTime)
.replace("[timestamp]", timestamp.toString())
.replace("[sign]", sign)
)
}
}
postRequest
}
//添加headers
for ((key, value) in setting.headers?.entries!!) {
request.headers(key, value)
}
//支持HTTP基本认证(Basic Authentication)
if (matches.isNotEmpty()) {
request.addInterceptor(BasicAuthInterceptor(matches[2], matches[3]))
}
request.ignoreHttpsCert() //忽略https证书
.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)
SendUtils.updateLogs(logId, 2, response)
}
})
}
//JSON需要转义的字符
private fun escapeJson(str: String?): String {
if (str == null) return "null"
val jsonStr: String = Gson().toJson(str)
return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr
}
fun sendMsg(setting: WebhookSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
package com.idormy.sms.forwarder.utils.sender
import android.annotation.SuppressLint
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.setting.WebhookSetting
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.app.AppUtils
import java.net.URLEncoder
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", "unused")
class WebhookUtils {
companion object {
private val TAG: String = WebhookUtils::class.java.simpleName
fun sendMsg(
setting: WebhookSetting,
msgInfo: MsgInfo,
rule: Rule?,
logId: Long?,
) {
val from: String = msgInfo.from
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
var requestUrl: String = setting.webServer //推送地址
Log.i(TAG, "requestUrl:$requestUrl")
val timestamp = System.currentTimeMillis()
val orgContent: String = msgInfo.content
val deviceMark: String = SettingUtils.extraDeviceMark
val appVersion: String = AppUtils.getAppVersionName()
val simInfo: String = msgInfo.simInfo
@SuppressLint("SimpleDateFormat") val receiveTime =
SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()) //smsVo.getDate()
var sign = ""
if (!TextUtils.isEmpty(setting.secret)) {
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))
sign = URLEncoder.encode(String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8")
}
var webParams = setting.webParams?.trim()
//支持HTTP基本认证(Basic Authentication)
val regex = "^(https?://)([^:]+):([^@]+)@(.+)"
val matches = Regex(regex, RegexOption.IGNORE_CASE).findAll(requestUrl).toList()
.flatMap(MatchResult::groupValues)
Log.i(TAG, "matches = $matches")
if (matches.isNotEmpty()) {
requestUrl = matches[1] + matches[4]
Log.i(TAG, "requestUrl:$requestUrl")
}
val request = if (setting.method == "GET" && TextUtils.isEmpty(webParams)) {
setting.webServer += (if (setting.webServer.contains("?")) "&" else "?") + "from=" + URLEncoder.encode(
from,
"UTF-8"
)
requestUrl += "&content=" + URLEncoder.encode(content, "UTF-8")
if (!TextUtils.isEmpty(sign)) {
requestUrl += "&timestamp=$timestamp"
requestUrl += "&sign=$sign"
}
Log.d(TAG, "method = GET, Url = $requestUrl")
XHttp.get(requestUrl).keepJson(true)
} else if (setting.method == "GET" && !TextUtils.isEmpty(webParams)) {
webParams = webParams.toString().replace("[from]", URLEncoder.encode(from, "UTF-8"))
.replace("[content]", URLEncoder.encode(content, "UTF-8"))
.replace("[msg]", URLEncoder.encode(content, "UTF-8"))
.replace("[org_content]", URLEncoder.encode(orgContent, "UTF-8"))
.replace("[device_mark]", URLEncoder.encode(deviceMark, "UTF-8"))
.replace("[app_version]", URLEncoder.encode(appVersion, "UTF-8"))
.replace("[title]", URLEncoder.encode(simInfo, "UTF-8"))
.replace("[card_slot]", URLEncoder.encode(simInfo, "UTF-8"))
.replace("[receive_time]", URLEncoder.encode(receiveTime, "UTF-8"))
.replace("\n", "%0A")
if (!TextUtils.isEmpty(setting.secret)) {
webParams = webParams.replace("[timestamp]", timestamp.toString())
.replace("[sign]", URLEncoder.encode(sign, "UTF-8"))
}
requestUrl += if (webParams.startsWith("/")) {
webParams
} else {
(if (requestUrl.contains("?")) "&" else "?") + webParams
}
Log.d(TAG, "method = GET, Url = $requestUrl")
XHttp.get(requestUrl).keepJson(true)
} else if (webParams != null && webParams.isNotEmpty() && webParams.startsWith("{")) {
val bodyMsg = webParams.replace("[from]", from)
.replace("[content]", escapeJson(content))
.replace("[msg]", escapeJson(content))
.replace("[org_content]", escapeJson(orgContent))
.replace("[device_mark]", escapeJson(deviceMark))
.replace("[app_version]", appVersion)
.replace("[title]", escapeJson(simInfo))
.replace("[card_slot]", escapeJson(simInfo))
.replace("[receive_time]", receiveTime)
.replace("[timestamp]", timestamp.toString())
.replace("[sign]", sign)
Log.d(TAG, "method = ${setting.method}, Url = $requestUrl, bodyMsg = $bodyMsg")
when (setting.method) {
"PUT" -> XHttp.put(requestUrl).keepJson(true).upJson(bodyMsg)
"PATCH" -> XHttp.patch(requestUrl).keepJson(true).upJson(bodyMsg)
else -> XHttp.post(requestUrl).keepJson(true).upJson(bodyMsg)
}
} else {
if (webParams == null || webParams.isEmpty()) {
webParams = "from=[from]&content=[content]&timestamp=[timestamp]"
if (!TextUtils.isEmpty(sign)) webParams += "&sign=[sign]"
}
Log.d(TAG, "method = ${setting.method}, Url = $requestUrl")
val postRequest = when (setting.method) {
"PUT" -> XHttp.put(requestUrl).keepJson(true)
"PATCH" -> XHttp.patch(requestUrl).keepJson(true)
else -> XHttp.post(requestUrl).keepJson(true)
}
webParams.trim('&').split("&").forEach {
val param = it.split("=")
if (param.size == 2) {
postRequest.params(
param[0], param[1].replace("[from]", from)
.replace("[content]", content)
.replace("[msg]", content)
.replace("[org_content]", orgContent)
.replace("[device_mark]", deviceMark)
.replace("[app_version]", appVersion)
.replace("[title]", simInfo)
.replace("[card_slot]", simInfo)
.replace("[receive_time]", receiveTime)
.replace("[timestamp]", timestamp.toString())
.replace("[sign]", sign)
)
}
}
postRequest
}
//添加headers
for ((key, value) in setting.headers?.entries!!) {
request.headers(key, value)
}
//支持HTTP基本认证(Basic Authentication)
if (matches.isNotEmpty()) {
request.addInterceptor(BasicAuthInterceptor(matches[2], matches[3]))
}
request.ignoreHttpsCert() //忽略https证书
.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)
SendUtils.updateLogs(logId, 2, response)
}
})
}
//JSON需要转义的字符
private fun escapeJson(str: String?): String {
if (str == null) return "null"
val jsonStr: String = Gson().toJson(str)
return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr
}
fun sendMsg(setting: WebhookSetting, msgInfo: MsgInfo) {
sendMsg(setting, msgInfo, null, null)
}
}
}

View File

@ -120,7 +120,7 @@ class WeworkAgentUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val textMsgMap: MutableMap<String, Any> = mutableMapOf()
@ -132,7 +132,7 @@ class WeworkAgentUtils private constructor() {
val textText: MutableMap<String, Any> = mutableMapOf()
textText["content"] = content
textMsgMap["text"] = textText
var accessToken: String by SharedPreference("access_token_" + setting.agentID, "")
val accessToken: String by SharedPreference("access_token_" + setting.agentID, "")
val requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$accessToken"
Log.i(TAG, "requestUrl:$requestUrl")
val requestMsg: String = Gson().toJson(textMsgMap)

View File

@ -28,7 +28,7 @@ class WeworkRobotUtils private constructor() {
val content: String = if (rule != null) {
msgInfo.getContentForSend(rule.smsTemplate, rule.regexReplace)
} else {
msgInfo.getContentForSend(SettingUtils.smsTemplate.toString())
msgInfo.getContentForSend(SettingUtils.smsTemplate)
}
val requestUrl = setting.webHook

View File

@ -340,7 +340,7 @@
<string name="sim2_remark" tools:ignore="Typos">SIM2 SubId/Label</string>
<string name="carrier_mobile" tools:ignore="Typos">Label of SIM,\neg. AT&amp;T_88888888</string>
<string name="tip_number_only_error_message">Number must be greater than 0!</string>
<string name="regexp_number_only" tools:ignore="Typos">^[1-9]?\\d+$</string>
<string name="regexp_number_only" tools:ignore="TypographyDashes,Typos">^[1-9]?\\d+$</string>
<string name="low_power_alarm_threshold">Low Power Alarm</string>
<string name="low_power_alarm_threshold_tips">Value range: 099.\nLeft blank or 0 is disabled</string>
<string name="retry_interval">Retry Interval</string>

View File

@ -341,7 +341,7 @@
<string name="sim2_remark" tools:ignore="Typos">SIM2主键/备注</string>
<string name="carrier_mobile">序号/运营商_手机号</string>
<string name="tip_number_only_error_message">数字必须大于0!</string>
<string name="regexp_number_only" tools:ignore="Typos">^[1-9]?\\d+$</string>
<string name="regexp_number_only" tools:ignore="TypographyDashes,Typos">^[1-9]?\\d+$</string>
<string name="low_power_alarm_threshold">安全电量范围(%)</string>
<string name="low_power_alarm_threshold_tips">超出安全范围将发出预警</string>
<string name="retry_interval">请求重试机制</string>