优化:`飞书群机器人`和`飞书企业应用`支持自定义`消息卡片`模板 #381

优化:`飞书企业应用`支持指定`消息接收者ID类型`
pull/408/head
pppscn 6 months ago
parent d48b9d826a
commit 6792a779c3

@ -2,12 +2,13 @@ package com.idormy.sms.forwarder.entity
import android.annotation.SuppressLint
import android.text.TextUtils
import com.idormy.sms.forwarder.utils.Log
import com.google.gson.Gson
import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.utils.AppUtils
import com.idormy.sms.forwarder.utils.BatteryUtils
import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.enableSmsTemplate
import com.idormy.sms.forwarder.utils.SettingUtils.Companion.extraDeviceMark
@ -72,6 +73,10 @@ data class MsgInfo(
.replace(getString(R.string.tag_device_name), deviceMark)
.replace(getString(R.string.tag_app_version), versionName)
.replace(getString(R.string.tag_call_type), callTypeMap[callType.toString()] ?: getString(R.string.unknown_call))
.replace(getString(R.string.tag_battery_pct), TaskUtils.batteryPct.toString())
.replace(getString(R.string.tag_battery_status), BatteryUtils.getStatus(TaskUtils.batteryStatus))
.replace(getString(R.string.tag_battery_plugged), BatteryUtils.getPlugged(TaskUtils.batteryPlugged))
.replace(getString(R.string.tag_battery_info), TaskUtils.batteryInfo)
.trim()
return replaceLocationTag(replaceAppName(regexReplace(titleForSend, regexReplace), from))
}
@ -129,6 +134,42 @@ data class MsgInfo(
return replaceLocationTag(replaceAppName(regexReplace(smsVoForSend, regexReplace), from))
}
@SuppressLint("SimpleDateFormat")
fun getContentFromJson(jsonTemplate: String): String {
var template = jsonTemplate.replace("null", "")
if (TextUtils.isEmpty(template)) template = getString(R.string.tag_from)
val deviceMark = extraDeviceMark.trim()
val versionName = AppUtils.getAppVersionName()
val splitSimInfo = simInfo.split("#####")
var title = splitSimInfo.getOrElse(0) { simInfo }
title = jsonInnerStr(title)
var scheme = splitSimInfo.getOrElse(1) { "" }
scheme = jsonInnerStr(scheme)
from = jsonInnerStr(from)
content = jsonInnerStr(content)
val msgForSend: String = template.replace(getString(R.string.tag_from), from)
.replace(getString(R.string.tag_package_name), from)
.replace(getString(R.string.tag_sms), content)
.replace(getString(R.string.tag_msg), content)
.replace(getString(R.string.tag_card_slot), title)
.replace(getString(R.string.tag_card_subid), subId.toString())
.replace(getString(R.string.tag_title), title)
.replace(getString(R.string.tag_scheme), scheme)
.replace(getString(R.string.tag_uid), uid.toString())
.replace(getString(R.string.tag_receive_time), jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)))
.replace(getString(R.string.tag_current_time), jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())))
.replace(getString(R.string.tag_device_name), jsonInnerStr(deviceMark))
.replace(getString(R.string.tag_app_version), jsonInnerStr(versionName))
.replace(getString(R.string.tag_call_type), jsonInnerStr(callTypeMap[callType.toString()] ?: getString(R.string.unknown_call)))
.replace(getString(R.string.tag_battery_pct), jsonInnerStr(TaskUtils.batteryPct.toString()))
.replace(getString(R.string.tag_battery_status), jsonInnerStr(BatteryUtils.getStatus(TaskUtils.batteryStatus)))
.replace(getString(R.string.tag_battery_plugged), jsonInnerStr(BatteryUtils.getPlugged(TaskUtils.batteryPlugged)))
.replace(getString(R.string.tag_battery_info), jsonInnerStr(TaskUtils.batteryInfo))
.trim()
return replaceLocationTag(replaceAppName(msgForSend, from, true), true)
}
//正则替换内容
private fun regexReplace(content: String, regexReplace: String): String {
return if (TextUtils.isEmpty(regexReplace)) content else try {
@ -150,7 +191,7 @@ data class MsgInfo(
}
//替换{{APP名称}}标签
private fun replaceAppName(content: String, packageName: String): String {
private fun replaceAppName(content: String, packageName: String, needJson: Boolean = false): String {
if (TextUtils.isEmpty(content)) return content
if (content.indexOf(getString(R.string.tag_app_name)) == -1) return content
@ -171,18 +212,32 @@ data class MsgInfo(
}
}
}
if (needJson) {
appName = jsonInnerStr(appName)
}
return content.replace(getString(R.string.tag_app_name), appName)
}
//替换 {{定位信息}} 标签
private fun replaceLocationTag(content: String): String {
private fun replaceLocationTag(content: String, needJson: Boolean = false): String {
if (TextUtils.isEmpty(content)) return content
if (content.indexOf(getString(R.string.tag_location)) == -1) return content
val location = HttpServerUtils.apiLocationCache.toString()
var location = HttpServerUtils.apiLocationCache.toString()
if (needJson) {
location = jsonInnerStr(location)
}
return content.replace(getString(R.string.tag_location), location)
}
private fun jsonInnerStr(string: String?): String {
if (string == null) return "null"
if (string == "") return "\"\""
val jsonStr: String = Gson().toJson(string)
return if (jsonStr.length >= 2) jsonStr.substring(1, jsonStr.length - 1) else jsonStr
}
override fun toString(): String {
return "MsgInfo{" +
"mobile='" + from + '\'' +

@ -10,8 +10,21 @@ data class FeishuAppSetting(
val receiveId: String = "",
val msgType: String = "interactive",
val titleTemplate: String = "",
val receiveIdType: String = "user_id",
val messageCard: String = "", //自定义消息卡片
) : Serializable {
fun getReceiveIdTypeCheckId(): Int {
return when (receiveIdType) {
"open_id" -> R.id.rb_receive_id_type_open_id
"user_id" -> R.id.rb_receive_id_type_user_id
"union_id" -> R.id.rb_receive_id_type_union_id
"email" -> R.id.rb_receive_id_type_email
"chat_id" -> R.id.rb_receive_id_type_chat_id
else -> R.id.rb_receive_id_type_user_id
}
}
fun getMsgTypeCheckId(): Int {
return if (msgType == null || msgType == "interactive") {
R.id.rb_msg_type_interactive

@ -8,6 +8,7 @@ data class FeishuSetting(
val secret: String? = "",
val msgType: String? = "interactive",
val titleTemplate: String? = "",
val messageCard: String = "", //自定义消息卡片
) : Serializable {
fun getMsgTypeCheckId(): Int {

@ -328,6 +328,7 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(),
.setNewActivity(true)
.putInt(KEY_SENDER_TYPE, pos) //注意:目前刚好是这个顺序而已
.open(this)
dialog.dismiss()
} catch (e: Exception) {
e.printStackTrace()
Log.e(TAG, "onItemClick error: ${e.message}")

@ -94,6 +94,16 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
}
})
binding!!.rgMsgType.setOnCheckedChangeListener { _, checkedId ->
if (checkedId == R.id.rb_msg_type_interactive) {
binding!!.layoutTitleTemplate.visibility = View.VISIBLE
binding!!.layoutMessageCard.visibility = View.VISIBLE
} else {
binding!!.layoutTitleTemplate.visibility = View.GONE
binding!!.layoutMessageCard.visibility = View.GONE
}
}
//新增
if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender))
@ -128,16 +138,23 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
if (settingVo != null) {
binding!!.etAppId.setText(settingVo.appId)
binding!!.etAppSecret.setText(settingVo.appSecret)
binding!!.etUserId.setText(settingVo.receiveId)
binding!!.rgReceiveIdType.check(settingVo.getReceiveIdTypeCheckId())
binding!!.etReceiveId.setText(settingVo.receiveId)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
binding!!.etMessageCard.setText(settingVo.messageCard)
}
}
})
}
override fun initListeners() {
binding!!.btInsertSenderToTitle.setOnClickListener(this)
binding!!.btInsertExtraToTitle.setOnClickListener(this)
binding!!.btInsertTimeToTitle.setOnClickListener(this)
binding!!.btInsertDeviceNameToTitle.setOnClickListener(this)
binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertContent.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this)
@ -151,27 +168,53 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
override fun onClick(v: View) {
try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate
val etMessageCard: EditText = binding!!.etMessageCard
when (v.id) {
R.id.bt_insert_sender -> {
R.id.bt_insert_sender_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return
}
R.id.bt_insert_extra -> {
R.id.bt_insert_extra_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return
}
R.id.bt_insert_time -> {
R.id.bt_insert_time_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return
}
R.id.bt_insert_device_name -> {
R.id.bt_insert_device_name_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return
}
R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_from))
return
}
R.id.bt_insert_content -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_sms))
return
}
R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_card_slot))
return
}
R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_receive_time))
return
}
R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_device_name))
return
}
R.id.btn_test -> {
mCountDownHelper?.start()
Thread {
@ -239,15 +282,24 @@ class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View
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()
val receiveId = binding!!.etReceiveId.text.toString().trim()
if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) {
throw Exception(getString(R.string.invalid_feishu_app_parameter))
}
val receiveIdType = when (binding!!.rgReceiveIdType.checkedRadioButtonId) {
R.id.rb_receive_id_type_open_id -> "open_id"
R.id.rb_receive_id_type_user_id -> "user_id"
R.id.rb_receive_id_type_union_id -> "union_id"
R.id.rb_receive_id_type_email -> "email"
R.id.rb_receive_id_type_chat_id -> "chat_id"
else -> "user_id"
}
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim()
val messageCard = binding!!.etMessageCard.text.toString().trim()
return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
return FeishuAppSetting(appId, appSecret, receiveId, msgType, title, receiveIdType, messageCard)
}
override fun onDestroyView() {

@ -94,6 +94,16 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
}
})
binding!!.rgMsgType.setOnCheckedChangeListener { _, checkedId ->
if (checkedId == R.id.rb_msg_type_interactive) {
binding!!.layoutTitleTemplate.visibility = View.VISIBLE
binding!!.layoutMessageCard.visibility = View.VISIBLE
} else {
binding!!.layoutTitleTemplate.visibility = View.GONE
binding!!.layoutMessageCard.visibility = View.GONE
}
}
//新增
if (senderId <= 0) {
titleBar?.setSubTitle(getString(R.string.add_sender))
@ -127,13 +137,19 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
binding!!.etSecret.setText(settingVo.secret)
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
binding!!.etMessageCard.setText(settingVo.messageCard)
}
}
})
}
override fun initListeners() {
binding!!.btInsertSenderToTitle.setOnClickListener(this)
binding!!.btInsertExtraToTitle.setOnClickListener(this)
binding!!.btInsertTimeToTitle.setOnClickListener(this)
binding!!.btInsertDeviceNameToTitle.setOnClickListener(this)
binding!!.btInsertSender.setOnClickListener(this)
binding!!.btInsertContent.setOnClickListener(this)
binding!!.btInsertExtra.setOnClickListener(this)
binding!!.btInsertTime.setOnClickListener(this)
binding!!.btInsertDeviceName.setOnClickListener(this)
@ -147,27 +163,53 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
override fun onClick(v: View) {
try {
val etTitleTemplate: EditText = binding!!.etTitleTemplate
val etMessageCard: EditText = binding!!.etMessageCard
when (v.id) {
R.id.bt_insert_sender -> {
R.id.bt_insert_sender_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
return
}
R.id.bt_insert_extra -> {
R.id.bt_insert_extra_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
return
}
R.id.bt_insert_time -> {
R.id.bt_insert_time_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
return
}
R.id.bt_insert_device_name -> {
R.id.bt_insert_device_name_to_title -> {
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
return
}
R.id.bt_insert_sender -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_from))
return
}
R.id.bt_insert_content -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_sms))
return
}
R.id.bt_insert_extra -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_card_slot))
return
}
R.id.bt_insert_time -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_receive_time))
return
}
R.id.bt_insert_device_name -> {
CommonUtils.insertOrReplaceText2Cursor(etMessageCard, getString(R.string.tag_device_name))
return
}
R.id.btn_test -> {
mCountDownHelper?.start()
Thread {
@ -235,8 +277,9 @@ class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnCli
val secret = binding!!.etSecret.text.toString().trim()
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
val title = binding!!.etTitleTemplate.text.toString().trim()
val messageCard = binding!!.etMessageCard.text.toString().trim()
return FeishuSetting(webhook, secret, msgType, title)
return FeishuSetting(webhook, secret, msgType, title, messageCard)
}
override fun onDestroyView() {

@ -91,7 +91,7 @@ class FeishuAppUtils private constructor() {
logId: Long = 0L,
msgId: Long = 0L
) {
val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id"
val requestUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${setting.receiveIdType}"
Log.d(TAG, "requestUrl$requestUrl")
val content: String = if (rule != null) {
@ -106,7 +106,16 @@ class FeishuAppUtils private constructor() {
} 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))
if (TextUtils.isEmpty(setting.messageCard.trim())) {
"{\"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 {
msgInfo.getContentFromJson(
setting.messageCard.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))
}

@ -1,5 +1,6 @@
package com.idormy.sms.forwarder.utils.sender
import android.text.TextUtils
import android.util.Base64
import com.google.gson.Gson
import com.idormy.sms.forwarder.database.entity.Rule
@ -121,8 +122,20 @@ class FeishuUtils private constructor() {
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))
if (TextUtils.isEmpty(setting.messageCard.trim())) {
msgMap["card"] = "{{CARD_BODY}}"
requestMsg = Gson().toJson(msgMap).replace("\"{{CARD_BODY}}\"", buildMsg(title, content, from, msgInfo.date))
} else {
val msgTime = jsonInnerStr(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(msgInfo.date))
msgMap["card"] = msgInfo.getContentFromJson(
setting.messageCard.trimIndent()
.replace("{{MSG_TITLE}}", jsonInnerStr(title))
.replace("{{MSG_TIME}}", msgTime)
.replace("{{MSG_FROM}}", jsonInnerStr(from))
.replace("{{MSG_CONTENT}}", jsonInnerStr(content))
)
requestMsg = Gson().toJson(msgMap)
}
} else {
msgMap["msg_type"] = "text"
val contentMap: MutableMap<String, Any> = mutableMapOf()

@ -123,7 +123,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/layout_custom_template"
android:id="@+id/layout_title_template"
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -158,6 +158,78 @@
android:singleLine="true"
app:met_clearButton="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_sender_to_title"
style="@style/insertButtonStyle"
android:text="@string/insert_sender" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_extra_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_extra" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_time_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_time" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_device_name_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_device_name" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/layout_message_card"
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="RtlSymmetry">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/feishu_msg_type_interactive_message_card"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/custom_template_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.edittext.ClearEditText
android:id="@+id/et_message_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints=""
android:gravity="left|top"
android:inputType="textMultiLine"
android:minLines="5"
android:text=""
tools:ignore="RtlHardcoded,SpeakableTextPresentCheck" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -168,22 +240,28 @@
style="@style/insertButtonStyle"
android:text="@string/insert_sender" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_content"
style="@style/insertButtonStyle"
android:layout_marginStart="3dp"
android:text="@string/insert_content" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_extra"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_extra" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_time"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_time" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_device_name"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_device_name" />
</LinearLayout>

@ -95,6 +95,53 @@
</LinearLayout>
<LinearLayout
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/feishu_receive_id_type"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/rg_receive_id_type"
style="@style/rg_style"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_receive_id_type_open_id"
style="@style/rg_rb_style"
android:text="@string/open_id" />
<RadioButton
android:id="@+id/rb_receive_id_type_user_id"
style="@style/rg_rb_style"
android:checked="true"
android:text="@string/user_id" />
<RadioButton
android:id="@+id/rb_receive_id_type_union_id"
style="@style/rg_rb_style"
android:text="@string/union_id" />
<RadioButton
android:id="@+id/rb_receive_id_type_email"
style="@style/rg_rb_style"
android:text="@string/email" />
<RadioButton
android:id="@+id/rb_receive_id_type_chat_id"
style="@style/rg_rb_style"
android:text="@string/chat_id" />
</RadioGroup>
</LinearLayout>
<LinearLayout
style="@style/BarStyle"
android:layout_width="match_parent"
@ -102,14 +149,14 @@
android:orientation="horizontal">
<TextView
android:layout_width="75dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:text="@string/user_id"
android:text="@string/receive_id"
android:textStyle="bold" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/et_user_id"
android:id="@+id/et_receive_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
@ -153,7 +200,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/layout_custom_template"
android:id="@+id/layout_title_template"
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -188,6 +235,78 @@
android:singleLine="true"
app:met_clearButton="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_sender_to_title"
style="@style/insertButtonStyle"
android:text="@string/insert_sender" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_extra_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_extra" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_time_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_time" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_device_name_to_title"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:text="@string/insert_device_name" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/layout_message_card"
style="@style/BarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="RtlSymmetry">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/feishu_msg_type_interactive_message_card"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/custom_template_tips"
android:textSize="@dimen/text_size_mini"
tools:ignore="SmallSp" />
</LinearLayout>
<com.xuexiang.xui.widget.edittext.ClearEditText
android:id="@+id/et_message_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints=""
android:gravity="left|top"
android:inputType="textMultiLine"
android:minLines="5"
android:text=""
tools:ignore="RtlHardcoded,SpeakableTextPresentCheck" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -198,22 +317,28 @@
style="@style/insertButtonStyle"
android:text="@string/insert_sender" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_content"
style="@style/insertButtonStyle"
android:layout_marginStart="3dp"
android:text="@string/insert_content" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_extra"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_extra" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_time"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_time" />
<com.xuexiang.xui.widget.button.shadowbutton.RippleShadowShadowButton
android:id="@+id/bt_insert_device_name"
style="@style/insertButtonStyle"
android:layout_marginStart="5dp"
android:layout_marginStart="3dp"
android:text="@string/insert_device_name" />
</LinearLayout>

@ -323,10 +323,12 @@
<string name="email_title">Email Title</string>
<string name="feishu_webhook">Webhook</string>
<string name="feishu_secret">Secret (optional)</string>
<string name="feishu_receive_id_type">Receive Id Type"</string>
<string name="feishu_msg_type">Msg Type</string>
<string name="feishu_msg_type_text">Text</string>
<string name="feishu_msg_type_interactive">Interactive</string>
<string name="feishu_msg_type_interactive_title">Interactive Title</string>
<string name="feishu_msg_type_interactive_message_card">Message Card Json</string>
<string name="Customize_API">Customize API</string>
<string name="Corp_ID">Corp ID</string>
<string name="Agent_ID">Agent ID</string>
@ -1331,4 +1333,8 @@
<string name="logs">【Logs】</string>
<string name="close_logs">Close Logs</string>
<string name="stopped">Stopped</string>
<string name="open_id">Open ID</string>
<string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string>
<string name="receive_id">Receive ID</string>
</resources>

@ -324,10 +324,12 @@
<string name="email_title">邮件主题</string>
<string name="feishu_webhook">Webhook 地址</string>
<string name="feishu_secret">加签 Secret (没有可不填)</string>
<string name="feishu_receive_id_type">消息接收者ID类型</string>
<string name="feishu_msg_type">消息类型</string>
<string name="feishu_msg_type_text">纯文本</string>
<string name="feishu_msg_type_interactive">消息卡片</string>
<string name="feishu_msg_type_interactive_title">标题模板</string>
<string name="feishu_msg_type_interactive_message_card">自定义消息卡片</string>
<string name="Customize_API">自定义API</string>
<string name="Corp_ID">企业ID</string>
<string name="Agent_ID">AgentId</string>
@ -1332,4 +1334,8 @@
<string name="logs">【日志】</string>
<string name="close_logs">关闭日志</string>
<string name="stopped">已停止</string>
<string name="open_id">Open ID</string>
<string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string>
<string name="receive_id">消息接收者ID</string>
</resources>

@ -324,10 +324,12 @@
<string name="email_title">郵件主題</string>
<string name="feishu_webhook">Webhook 地址</string>
<string name="feishu_secret">加簽 Secret (沒有可不填)</string>
<string name="feishu_receive_id_type">訊息接收者ID類型</string>
<string name="feishu_msg_type">消息類型</string>
<string name="feishu_msg_type_text">純文本</string>
<string name="feishu_msg_type_interactive">消息卡片</string>
<string name="feishu_msg_type_interactive_title">標題模板</string>
<string name="feishu_msg_type_interactive_message_card">自定義消息卡片</string>
<string name="Customize_API">自定義API</string>
<string name="Corp_ID">企業ID</string>
<string name="Agent_ID">AgentId</string>
@ -1333,4 +1335,8 @@
<string name="logs">【日誌】</string>
<string name="close_logs">關閉日誌</string>
<string name="stopped">已停止</string>
<string name="open_id">Open ID</string>
<string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string>
<string name="receive_id">訊息接收者ID</string>
</resources>

@ -324,10 +324,12 @@
<string name="email_title">邮件主题</string>
<string name="feishu_webhook">Webhook 地址</string>
<string name="feishu_secret">加签 Secret (没有可不填)</string>
<string name="feishu_receive_id_type">消息接收者ID类型</string>
<string name="feishu_msg_type">消息类型</string>
<string name="feishu_msg_type_text">纯文本</string>
<string name="feishu_msg_type_interactive">消息卡片</string>
<string name="feishu_msg_type_interactive_title">标题模板</string>
<string name="feishu_msg_type_interactive_message_card">自定义消息卡片</string>
<string name="Customize_API">自定义API</string>
<string name="Corp_ID">企业ID</string>
<string name="Agent_ID">AgentId</string>
@ -1332,4 +1334,8 @@
<string name="logs">【日志】</string>
<string name="close_logs">关闭日志</string>
<string name="stopped">已停止</string>
<string name="open_id">Open ID</string>
<string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string>
<string name="receive_id">消息接收者ID</string>
</resources>

Loading…
Cancel
Save