Skip to content

Commit

Permalink
[bot] AutoMerging: merge all upstream's changes:
Browse files Browse the repository at this point in the history
* 'main' of https://github.com/pppscn/SmsForwarder:
  优化:让 Android 4.4 支持 TLS 1.3 pppscn#197
  新增:`飞书企业应用`发送通道
  新增测试通知标题和修复英文正则表达式 (pppscn#208)
  v3.0.8
  修复:短信内容包含“<"字符时,用tg转发失败 pppscn#205
  优化:随身WiFi断电重启后frpc启动不成功 pppscn#199
  • Loading branch information
github-actions[bot] committed Aug 19, 2022
2 parents dc684fa + b407e11 commit fa18d19
Show file tree
Hide file tree
Showing 21 changed files with 801 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

短信转发器——不仅只转发短信,备用机必备神器!

监控Android手机短信、来电、APP通知,并根据指定规则转发到其他手机:钉钉群自定义机器人、钉钉企业内机器人、企业微信群机器人、飞书机器人、企业微信应用消息、邮箱、bark、webhook、Telegram机器人、Server酱、PushPlus、手机短信等。
监控Android手机短信、来电、APP通知,并根据指定规则转发到其他手机:钉钉群自定义机器人、钉钉企业内机器人、企业微信群机器人、企业微信应用消息、飞书群机器人、飞书企业应用、邮箱、bark、webhook、Telegram机器人、Server酱、PushPlus、手机短信等。

包括主动控制服务端与客户端,让你轻松远程发短信、查短信、查通话、查话簿、查电量等。(V3.0 新增)

Expand Down
2 changes: 1 addition & 1 deletion README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

SmsForwarder - Not only forwarding text messages, but also a must-have for backup devices!

listens to SMS, incoming calls, and App notifications on Android mobile devices, and forward according to user defined rules to another App/device, including DingTalk, WeCom and WeCom Group Bot, Feishi Bot, E-mail, Bark, Webhook, Telegram Bot, ServerChan, PushPlus, SMS, etc.
listens to SMS, incoming calls, and App notifications on Android mobile devices, and forward according to user defined rules to another App/device, including DingTalk, WeCom and WeCom Group Bot, Feishu App and Feishu Group Bot, E-mail, Bark, Webhook, Telegram Bot, ServerChan, PushPlus, SMS, etc.

Including active control of the server and client, allowing you to easily and remotely send text messages, check text messages, check calls, check the phone book, check the battery, etc.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ server_addr = 88.88.88.88
server_port = 8888
#可选,建议启用
token = 888888888
#连接服务端的超时时间(增大时间避免frpc在网络未就绪的情况下启动失败)
dial_server_timeout = 60
#第一次登陆失败后是否退出
login_fail_exit = false
#[二选一即可]每台机器不可重复,通过 http://88.88.88.88:5000 访问
[SmsForwarder-TCP]
Expand Down Expand Up @@ -178,6 +182,10 @@ server_addr = 88.88.88.88
server_port = 8888
#可选,建议启用
token = 888888888
#连接服务端的超时时间(增大时间避免frpc在网络未就绪的情况下启动失败)
dial_server_timeout = 60
#第一次登陆失败后是否退出
login_fail_exit = false
#[二选一即可]每台机器不可重复,通过 http://88.88.88.88:5000 访问
[SmsForwarder-TCP]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ data class Sender(
TYPE_GOTIFY -> R.drawable.icon_gotify
TYPE_SMS -> R.drawable.icon_sms
TYPE_DINGTALK_INNER_ROBOT -> R.drawable.icon_dingtalk_inner
TYPE_FEISHU_APP -> R.drawable.icon_feishu_app
else -> R.drawable.icon_sms
}

Expand All @@ -56,6 +57,7 @@ data class Sender(
TYPE_GOTIFY -> R.drawable.icon_gotify
TYPE_SMS -> R.drawable.icon_sms
TYPE_DINGTALK_INNER_ROBOT -> R.drawable.icon_dingtalk_inner
TYPE_FEISHU_APP -> R.drawable.icon_feishu_app
else -> R.drawable.icon_sms
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.idormy.sms.forwarder.entity.result

data class FeishuAppResult(
var code: Long,
var msg: String,
//获取access_token返回
var tenant_access_token: String?,
var expire: Long?,
//发送接口返回
var content: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.idormy.sms.forwarder.entity.setting

import com.idormy.sms.forwarder.R
import java.io.Serializable

data class FeishuAppSetting(
var appId: String = "",
val appSecret: String = "",
val receiveId: String = "",
val msgType: String = "interactive",
val titleTemplate: String = "",
) : Serializable {

fun getMsgTypeCheckId(): Int {
return if (msgType == null || msgType == "interactive") {
R.id.rb_msg_type_interactive
} else {
R.id.rb_msg_type_text
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -565,12 +565,16 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
val rgSimSlot = dialogTest.findViewById<RadioGroup>(R.id.rg_sim_slot)
val tvFrom = dialogTest.findViewById<TextView>(R.id.tv_from)
val etFrom = dialogTest.findViewById<EditText>(R.id.et_from)
val tvTitle = dialogTest.findViewById<TextView>(R.id.tv_title)
val etTitle = dialogTest.findViewById<EditText>(R.id.et_title)
val tvContent = dialogTest.findViewById<TextView>(R.id.tv_content)
val etContent = dialogTest.findViewById<EditText>(R.id.et_content)

if ("app" == ruleType) {
tvSimSlot.visibility = View.GONE
rgSimSlot.visibility = View.GONE
tvTitle.visibility = View.VISIBLE
etTitle.visibility = View.VISIBLE
tvFrom.setText(R.string.test_package_name)
tvContent.setText(R.string.test_inform_content)
} else if ("call" == ruleType) {
Expand All @@ -592,7 +596,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
.positiveText(R.string.action_test)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
try {
val simSlot = when (rgSimSlot.checkedRadioButtonId) {
val simSlot = when (if (ruleType == "app") -1 else rgSimSlot.checkedRadioButtonId) {
R.id.rb_sim_slot_1 -> 0
R.id.rb_sim_slot_2 -> 1
else -> -1
Expand All @@ -608,7 +612,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
val simInfo = when (simSlot) {
0 -> "SIM1_" + SettingUtils.extraSim1
1 -> "SIM2_" + SettingUtils.extraSim2
else -> ""
else -> etTitle.text.toString()
}

val msgInfo = MsgInfo(ruleType, etFrom.text.toString(), etContent.text.toString(), Date(), simInfo, simSlot)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
TYPE_PUSHPLUS -> PushplusFragment::class.java
TYPE_GOTIFY -> GotifyFragment::class.java
TYPE_DINGTALK_INNER_ROBOT -> DingtalkInnerRobotFragment::class.java
TYPE_FEISHU_APP -> FeishuAppFragment::class.java
else -> DingtalkGroupRobotFragment::class.java
}
).setNewActivity(true)
Expand All @@ -132,6 +133,7 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
TYPE_PUSHPLUS -> PushplusFragment::class.java
TYPE_GOTIFY -> GotifyFragment::class.java
TYPE_DINGTALK_INNER_ROBOT -> DingtalkInnerRobotFragment::class.java
TYPE_FEISHU_APP -> FeishuAppFragment::class.java
else -> DingtalkGroupRobotFragment::class.java
}
).setNewActivity(true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package com.idormy.sms.forwarder.fragment.senders

import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.fragment.app.viewModels
import com.google.gson.Gson
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuAppBinding
import com.idormy.sms.forwarder.entity.MsgInfo
import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting
import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.utils.sender.FeishuAppUtils
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xrouter.annotation.AutoWired
import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.utils.CountDownButtonHelper
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.*

@Page(name = "飞书企业应用")
@Suppress("PrivatePropertyName")
class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View.OnClickListener {

private val TAG: String = FeishuAppFragment::class.java.simpleName
var titleBar: TitleBar? = null
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private var mCountDownHelper: CountDownButtonHelper? = null

@JvmField
@AutoWired(name = KEY_SENDER_ID)
var senderId: Long = 0

@JvmField
@AutoWired(name = KEY_SENDER_TYPE)
var senderType: Int = 0

@JvmField
@AutoWired(name = KEY_SENDER_CLONE)
var isClone: Boolean = false

override fun initArgs() {
XRouter.getInstance().inject(this)
}

override fun viewBindingInflate(
inflater: LayoutInflater,
container: ViewGroup,
): FragmentSendersFeishuAppBinding {
return FragmentSendersFeishuAppBinding.inflate(inflater, container, false)
}

override fun initTitle(): TitleBar? {
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu_app)
return titleBar
}

/**
* 初始化控件
*/
override fun initViews() {
//测试按钮增加倒计时,避免重复点击
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
override fun onCountDown(time: Int) {
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
}

override fun onFinished() {
binding!!.btnTest.text = getString(R.string.test)
}
})

//新增
if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender))
binding!!.btnDel.setText(R.string.discard)
return
}

//编辑
binding!!.btnDel.setText(R.string.del)
AppDatabase.getInstance(requireContext())
.senderDao()
.get(senderId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Sender> {
override fun onSubscribe(d: Disposable) {}

override fun onError(e: Throwable) {
e.printStackTrace()
}

override fun onSuccess(sender: Sender) {
if (isClone) {
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
binding!!.btnDel.setText(R.string.discard)
} else {
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
}
binding!!.etName.setText(sender.name)
binding!!.sbEnable.isChecked = sender.status == 1
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuAppSetting::class.java)
Log.d(TAG, settingVo.toString())
if (settingVo != null) {
binding!!.etAppId.setText(settingVo.appId)
binding!!.etAppSecret.setText(settingVo.appSecret)
binding!!.etUserId.setText(settingVo.receiveId)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
}
}
})
}

override fun initListeners() {
binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this)
binding!!.btnTest.setOnClickListener(this)
binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this)
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
}

@SingleClick
override fun onClick(v: View) {
try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate
when (v.id) {
R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return
}
R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return
}
R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return
}
R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return
}
R.id.btn_test -> {
mCountDownHelper?.start()
Thread {
try {
val settingVo = checkSetting()
Log.d(TAG, settingVo.toString())
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
FeishuAppUtils.sendMsg(settingVo, msgInfo)
} catch (e: Exception) {
e.printStackTrace()
if (Looper.myLooper() == null) Looper.prepare()
XToastUtils.error(e.message.toString())
Looper.loop()
}
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
}.start()
return
}
R.id.btn_del -> {
if (senderId <= 0 || isClone) {
popToBack()
return
}

MaterialDialog.Builder(requireContext())
.title(R.string.delete_sender_title)
.content(R.string.delete_sender_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
viewModel.delete(senderId)
XToastUtils.success(R.string.delete_sender_toast)
popToBack()
}
.show()
return
}
R.id.btn_save -> {
val name = binding!!.etName.text.toString().trim()
if (TextUtils.isEmpty(name)) {
throw Exception(getString(R.string.invalid_name))
}

val status = if (binding!!.sbEnable.isChecked) 1 else 0
val settingVo = checkSetting()
if (isClone) senderId = 0
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
Log.d(TAG, senderNew.toString())

viewModel.insertOrUpdate(senderNew)
XToastUtils.success(R.string.tipSaveSuccess)
popToBack()
return
}
}
} catch (e: Exception) {
XToastUtils.error(e.message.toString())
e.printStackTrace()
}
}

private fun checkSetting(): FeishuAppSetting {
val appId = binding!!.etAppId.text.toString().trim()
val appSecret = binding!!.etAppSecret.text.toString().trim()
val receiveId = binding!!.etUserId.text.toString().trim()
if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) {
throw Exception(getString(R.string.invalid_feishu_app_parameter))
}

val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim()

return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
}

override fun onDestroyView() {
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
super.onDestroyView()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.*

@Page(name = "飞书机器人")
@Page(name = "飞书群机器人")
@Suppress("PrivatePropertyName")
class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnClickListener {

Expand Down
Loading

0 comments on commit fa18d19

Please sign in to comment.