添加飞书的webhook支持

This commit is contained in:
pppscn 2021-09-27 18:11:42 +08:00
parent d65b305053
commit 9eeb815322
60 changed files with 390 additions and 15 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ local.properties
.settings/*
*/.settings/*
/app/pppscn.jks
/psd

View File

@ -1,5 +1,17 @@
package com.idormy.sms.forwarder;
import static com.idormy.sms.forwarder.model.SenderModel.STATUS_ON;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_FEISHU;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_APP;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_SERVER_CHAN;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_SMS;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_TELEGRAM;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
@ -26,6 +38,7 @@ import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.vo.BarkSettingVo;
import com.idormy.sms.forwarder.model.vo.DingDingSettingVo;
import com.idormy.sms.forwarder.model.vo.EmailSettingVo;
import com.idormy.sms.forwarder.model.vo.FeiShuSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXAppSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo;
import com.idormy.sms.forwarder.model.vo.ServerChanSettingVo;
@ -34,6 +47,7 @@ import com.idormy.sms.forwarder.model.vo.TelegramSettingVo;
import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo;
import com.idormy.sms.forwarder.sender.SenderBarkMsg;
import com.idormy.sms.forwarder.sender.SenderDingdingMsg;
import com.idormy.sms.forwarder.sender.SenderFeishuMsg;
import com.idormy.sms.forwarder.sender.SenderMailMsg;
import com.idormy.sms.forwarder.sender.SenderQyWxAppMsg;
import com.idormy.sms.forwarder.sender.SenderQyWxGroupRobotMsg;
@ -49,17 +63,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.idormy.sms.forwarder.model.SenderModel.STATUS_ON;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_APP;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_SERVER_CHAN;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_SMS;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_TELEGRAM;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY;
public class SenderActivity extends AppCompatActivity {
public static final int NOTIFY = 0x9731993;
@ -140,6 +143,9 @@ public class SenderActivity extends AppCompatActivity {
case TYPE_SMS:
setSms(senderModel);
break;
case TYPE_FEISHU:
setFeiShu(senderModel);
break;
default:
Toast.makeText(SenderActivity.this, "异常的发送方类型,自动删除!", Toast.LENGTH_LONG).show();
if (senderModel != null) {
@ -175,7 +181,6 @@ public class SenderActivity extends AppCompatActivity {
//添加AlertDialog.Builder对象的setNegativeButton()方法
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@ -227,6 +232,9 @@ public class SenderActivity extends AppCompatActivity {
case TYPE_SMS:
setSms(null);
break;
case TYPE_FEISHU:
setFeiShu(null);
break;
default:
Toast.makeText(SenderActivity.this, "暂不支持这种转发!", Toast.LENGTH_LONG).show();
break;
@ -237,6 +245,7 @@ public class SenderActivity extends AppCompatActivity {
Log.d(TAG, "setDingDing show" + senderModels.size());
}
//钉钉机器人
private void setDingDing(final SenderModel senderModel) {
DingDingSettingVo dingDingSettingVo = null;
//try phrase json setting
@ -349,6 +358,7 @@ public class SenderActivity extends AppCompatActivity {
});
}
//邮箱
private void setEmail(final SenderModel senderModel) {
EmailSettingVo emailSettingVo = null;
//try phrase json setting
@ -476,6 +486,7 @@ public class SenderActivity extends AppCompatActivity {
});
}
//Bark
private void setBark(final SenderModel senderModel) {
BarkSettingVo barkSettingVo = null;
//try phrase json setting
@ -566,6 +577,7 @@ public class SenderActivity extends AppCompatActivity {
});
}
//Server酱·Turbo版
private void setServerChan(final SenderModel senderModel) {
ServerChanSettingVo serverchanSettingVo = null;
//try phrase json setting
@ -740,7 +752,7 @@ public class SenderActivity extends AppCompatActivity {
String method = radioGroupWebNotifyMethod.getCheckedRadioButtonId() == R.id.radioWebNotifyMethodGet ? "GET" : "POST";
if (!webServer.isEmpty()) {
try {
SenderWebNotifyMsg.sendMsg(0, handler, webServer, webParams,secret, method, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
SenderWebNotifyMsg.sendMsg(0, handler, webServer, webParams, secret, method, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
@ -1073,7 +1085,7 @@ public class SenderActivity extends AppCompatActivity {
});
}
//Sms
//短信
private void setSms(final SenderModel senderModel) {
SmsSettingVo smsSettingVo = null;
//try phrase json setting
@ -1178,6 +1190,101 @@ public class SenderActivity extends AppCompatActivity {
});
}
//飞书机器人
private void setFeiShu(final SenderModel senderModel) {
FeiShuSettingVo feiShuSettingVo = null;
//try phrase json setting
if (senderModel != null) {
String jsonSettingStr = senderModel.getJsonSetting();
if (jsonSettingStr != null) {
feiShuSettingVo = JSON.parseObject(jsonSettingStr, FeiShuSettingVo.class);
}
}
final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this);
View view1 = View.inflate(SenderActivity.this, R.layout.alert_dialog_setview_feishu, null);
final EditText editTextFeishuName = view1.findViewById(R.id.editTextFeishuName);
if (senderModel != null)
editTextFeishuName.setText(senderModel.getName());
final EditText editTextFeishuWebhook = view1.findViewById(R.id.editTextFeishuWebhook);
if (feiShuSettingVo != null)
editTextFeishuWebhook.setText(feiShuSettingVo.getWebhook());
final EditText editTextFeishuSecret = view1.findViewById(R.id.editTextFeishuSecret);
if (feiShuSettingVo != null)
editTextFeishuSecret.setText(feiShuSettingVo.getSecret());
Button buttonfeishuok = view1.findViewById(R.id.buttonfeishuok);
Button buttonfeishudel = view1.findViewById(R.id.buttonfeishudel);
Button buttonfeishutest = view1.findViewById(R.id.buttonfeishutest);
alertDialog71
.setTitle(R.string.setfeishutitle)
.setIcon(R.mipmap.feishu)
.setView(view1)
.create();
final AlertDialog show = alertDialog71.show();
buttonfeishuok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(editTextFeishuName.getText().toString());
newSenderModel.setType(TYPE_FEISHU);
newSenderModel.setStatus(STATUS_ON);
FeiShuSettingVo feiShuSettingVonew = new FeiShuSettingVo(
editTextFeishuWebhook.getText().toString(),
editTextFeishuSecret.getText().toString());
newSenderModel.setJsonSetting(JSON.toJSONString(feiShuSettingVonew));
SenderUtil.addSender(newSenderModel);
initSenders();
adapter.add(senderModels);
} else {
senderModel.setName(editTextFeishuName.getText().toString());
senderModel.setType(TYPE_FEISHU);
senderModel.setStatus(STATUS_ON);
FeiShuSettingVo feiShuSettingVonew = new FeiShuSettingVo(
editTextFeishuWebhook.getText().toString(),
editTextFeishuSecret.getText().toString());
senderModel.setJsonSetting(JSON.toJSONString(feiShuSettingVonew));
SenderUtil.updateSender(senderModel);
initSenders();
adapter.update(senderModels);
}
show.dismiss();
}
});
buttonfeishudel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (senderModel != null) {
SenderUtil.delSender(senderModel.getId());
initSenders();
adapter.del(senderModels);
}
show.dismiss();
}
});
buttonfeishutest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String token = editTextFeishuWebhook.getText().toString();
String secret = editTextFeishuSecret.getText().toString();
if (token != null && !token.isEmpty()) {
try {
SenderFeishuMsg.sendMsg(0, handler, token, secret, "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (Exception e) {
Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} else {
Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");

View File

@ -17,6 +17,7 @@ public class SenderModel {
public static final int TYPE_SERVER_CHAN = 6;
public static final int TYPE_TELEGRAM = 7;
public static final int TYPE_SMS = 8;
public static final int TYPE_FEISHU = 9;
private Long id;
private String name;
private int status;
@ -52,8 +53,9 @@ public class SenderModel {
return R.mipmap.serverchan;
case (TYPE_TELEGRAM):
return R.mipmap.telegram;
case (TYPE_FEISHU):
return R.mipmap.feishu;
case (TYPE_SMS):
return R.mipmap.sms;
default:
return R.mipmap.sms;
}
@ -77,6 +79,9 @@ public class SenderModel {
return R.mipmap.serverchan;
case (TYPE_TELEGRAM):
return R.mipmap.telegram;
case (TYPE_FEISHU):
return R.mipmap.feishu;
case (TYPE_SMS):
default:
return R.mipmap.sms;

View File

@ -0,0 +1,19 @@
package com.idormy.sms.forwarder.model.vo;
import java.io.Serializable;
import lombok.Data;
@Data
public class FeiShuSettingVo implements Serializable {
private String webhook;
private String secret;
public FeiShuSettingVo() {
}
public FeiShuSettingVo(String webhook, String secret) {
this.webhook = webhook;
this.secret = secret;
}
}

View File

@ -3,6 +3,7 @@ package com.idormy.sms.forwarder.sender;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_FEISHU;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_APP;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT;
import static com.idormy.sms.forwarder.model.SenderModel.TYPE_SERVER_CHAN;
@ -21,6 +22,7 @@ import com.idormy.sms.forwarder.model.SenderModel;
import com.idormy.sms.forwarder.model.vo.BarkSettingVo;
import com.idormy.sms.forwarder.model.vo.DingDingSettingVo;
import com.idormy.sms.forwarder.model.vo.EmailSettingVo;
import com.idormy.sms.forwarder.model.vo.FeiShuSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXAppSettingVo;
import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo;
import com.idormy.sms.forwarder.model.vo.ServerChanSettingVo;
@ -254,6 +256,21 @@ public class SendUtil {
}
break;
case TYPE_FEISHU:
//try phrase json setting
if (senderModel.getJsonSetting() != null) {
FeiShuSettingVo feiShuSettingVo = JSON.parseObject(senderModel.getJsonSetting(), FeiShuSettingVo.class);
if (feiShuSettingVo != null) {
try {
SenderFeishuMsg.sendMsg(logId, handError, feiShuSettingVo.getWebhook(), feiShuSettingVo.getSecret(), smsVo.getSmsVoForSend());
} catch (Exception e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Log.e(TAG, "senderSendMsg: feishu error " + e.getMessage());
}
}
}
break;
default:
break;
}

View File

@ -0,0 +1,116 @@
package com.idormy.sms.forwarder.sender;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
import android.os.Bundle;
import android.os.Handler;
import android.util.Base64;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import com.idormy.sms.forwarder.utils.LogUtil;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SenderFeishuMsg {
static String TAG = "SenderFeishuMsg";
public static void sendMsg(final long logId, final Handler handError, String webhook, String secret, String msg) throws Exception {
Log.i(TAG, "sendMsg webhook:" + webhook + " secret:" + secret + " msg:" + msg);
if (webhook == null || webhook.isEmpty()) {
return;
}
Map textMsgMap = new HashMap();
//签名校验
if (secret != null && !secret.isEmpty()) {
Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8");
textMsgMap.put("timestamp", timestamp);
textMsgMap.put("sign", sign);
}
//组装报文
textMsgMap.put("msg_type", "text");
Map content = new HashMap();
content.put("text", msg);
textMsgMap.put("content", content);
String textMsg = JSON.toJSONString(textMsgMap);
Log.i(TAG, "textMsg:" + textMsg);
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
textMsg);
final Request request = new Request.Builder()
.url(webhook)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Log.d(TAG, "onFailure" + e.getMessage());
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送失败:" + e.getMessage());
msg.setData(bundle);
handError.sendMessage(msg);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
Log.d(TAG, "Code" + String.valueOf(response.code()) + responseStr);
//TODO:粗略解析是否发送成功
if (responseStr.contains("\"StatusCode\":0")) {
LogUtil.updateLog(logId, 1, responseStr);
} else {
LogUtil.updateLog(logId, 0, responseStr);
}
if (handError != null) {
android.os.Message msg = new android.os.Message();
msg.what = NOTIFY;
Bundle bundle = new Bundle();
bundle.putString("DATA", "发送状态:" + responseStr);
msg.setData(bundle);
handError.sendMessage(msg);
Log.d(TAG, "respone" + String.valueOf(response.code()) + responseStr);
}
}
});
}
}

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置名称" />
<EditText
android:id="@+id/editTextFeishuName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:ems="11"
android:inputType=""
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置 Webhook 地址" />
<EditText
android:id="@+id/editTextFeishuWebhook"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="14"
android:inputType="textPassword"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加签 Secret 没有可不填" />
<EditText
android:id="@+id/editTextFeishuSecret"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="14"
android:inputType="textPassword"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/buttonfeishuok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/ok" />
<Button
android:id="@+id/buttonfeishudel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:text="@string/del" />
<Button
android:id="@+id/buttonfeishutest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:text="@string/test" />
</LinearLayout>
</LinearLayout>
</ScrollView>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -10,5 +10,6 @@
<item>转发到Server酱·Turbo版</item>
<item>转发到Telegram机器人</item>
<item>转发到其他手机短信</item>
<item>转发到飞书机器人</item>
</string-array>
</resources>

View File

@ -15,6 +15,7 @@
<string name="setserverchantitle">设置Server酱·Turbo版</string>
<string name="settelegramtitle">设置Telegram机器人</string>
<string name="setsmstitle">设置SMS</string>
<string name="setfeishutitle">设置飞书机器人</string>
<string name="check_new_version">检查更新</string>
<string name="to_setting">设置</string>
<string name="to_about">关于</string>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.