新增:Webhook发送通道支持设置Header (#129)

* 修复:手动重发消息中UTC时间未转换本地时间 (#122)

* 新增:Webhook发送通道支持设置Header (#128)
This commit is contained in:
Naccl 2022-03-03 17:36:00 +08:00 committed by GitHub
parent 32efe289b5
commit 64d930bfbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 184 additions and 13 deletions

View File

@ -31,6 +31,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
@ -86,6 +87,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("deprecation")
public class SenderActivity extends AppCompatActivity {
@ -832,6 +834,57 @@ public class SenderActivity extends AppCompatActivity {
}
//header序号
int headerItemId = 0;
/**
* 动态增删header
*
* @param headerItemMap 管理item的map用于删除指定header
* @param linearLayoutWebNotifyHeaders 需要挂载item的LinearLayout
* @param key header的key为空则不设置
* @param value header的value为空则不设置
*/
private void addHeaderItemLinearLayout(Map<Integer, LinearLayout> headerItemMap, final LinearLayout linearLayoutWebNotifyHeaders, String key, String value) {
LinearLayout linearLayoutItemAddHeader = (LinearLayout) View.inflate(this, R.layout.item_add_header, null);
ImageView imageViewRemoveHeader = linearLayoutItemAddHeader.findViewById(R.id.imageViewRemoveHeader);
if (key != null && value != null) {
EditText editTextHeaderKey = linearLayoutItemAddHeader.findViewById(R.id.editTextHeaderKey);
EditText editTextHeaderValue = linearLayoutItemAddHeader.findViewById(R.id.editTextHeaderValue);
editTextHeaderKey.setText(key);
editTextHeaderValue.setText(value);
}
imageViewRemoveHeader.setTag(headerItemId);
imageViewRemoveHeader.setOnClickListener(view2 -> {
int itemId = (int) view2.getTag();
linearLayoutWebNotifyHeaders.removeView(headerItemMap.get(itemId));
headerItemMap.remove(itemId);
});
linearLayoutWebNotifyHeaders.addView(linearLayoutItemAddHeader);
headerItemMap.put(headerItemId, linearLayoutItemAddHeader);
headerItemId++;
}
/**
* 从EditText控件中获取全部headers
*
* @param headerItemMap 管理item的map
* @return 全部headers
*/
private Map<String, String> getHeadersFromHeaderItemMap(Map<Integer, LinearLayout> headerItemMap) {
Map<String, String> headers = new HashMap<>();
for (LinearLayout headerItem : headerItemMap.values()) {
EditText editTextHeaderKey = headerItem.findViewById(R.id.editTextHeaderKey);
EditText editTextHeaderValue = headerItem.findViewById(R.id.editTextHeaderValue);
String key = editTextHeaderKey.getText().toString().trim();
String value = editTextHeaderValue.getText().toString().trim();
headers.put(key, value);
}
return headers;
}
//webhook
@SuppressLint("SimpleDateFormat")
private void setWebNotify(final SenderModel senderModel, final boolean isClone) {
@ -858,13 +911,25 @@ public class SenderActivity extends AppCompatActivity {
final EditText editTextWebNotifyWebParams = view1.findViewById(R.id.editTextWebNotifyWebParams);
final ClearEditText editTextWebNotifySecret = view1.findViewById(R.id.editTextWebNotifySecret);
final RadioGroup radioGroupWebNotifyMethod = view1.findViewById(R.id.radioGroupWebNotifyMethod);
Map<Integer, LinearLayout> headerItemMap = new HashMap<>(2);
final LinearLayout linearLayoutWebNotifyHeaders = view1.findViewById(R.id.linearLayoutWebNotifyHeaders);
final ImageView imageViewWebNotifyAddHeader = view1.findViewById(R.id.imageViewWebNotifyAddHeader);
if (webNotifySettingVo != null) {
editTextWebNotifyWebServer.setText(webNotifySettingVo.getWebServer());
editTextWebNotifyWebParams.setText(webNotifySettingVo.getWebParams());
editTextWebNotifySecret.setText(webNotifySettingVo.getSecret());
radioGroupWebNotifyMethod.check(webNotifySettingVo.getWebNotifyMethodCheckId());
//set header
for (Map.Entry<String, String> header : webNotifySettingVo.getHeaders().entrySet()) {
addHeaderItemLinearLayout(headerItemMap, linearLayoutWebNotifyHeaders, header.getKey(), header.getValue());
}
}
//add header
imageViewWebNotifyAddHeader.setOnClickListener(view -> addHeaderItemLinearLayout(headerItemMap, linearLayoutWebNotifyHeaders, null, null));
Button buttonOk = view1.findViewById(R.id.buttonOk);
Button buttonDel = view1.findViewById(R.id.buttonDel);
Button buttonTest = view1.findViewById(R.id.buttonTest);
@ -887,13 +952,14 @@ public class SenderActivity extends AppCompatActivity {
String secret = editTextWebNotifySecret.getText().trim();
String method = radioGroupWebNotifyMethod.getCheckedRadioButtonId() == R.id.radioWebNotifyMethodGet ? "GET" : "POST";
String webParams = editTextWebNotifyWebParams.getText().toString().trim();
Map<String, String> headers = getHeadersFromHeaderItemMap(headerItemMap);
if (!CommonUtil.checkUrl(webServer, false)) {
ToastUtils.delayedShow(R.string.invalid_webserver, 3000);
return;
}
WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo(webServer, secret, method, webParams);
WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo(webServer, secret, method, webParams, headers);
if (isClone || senderModel == null) {
SenderModel newSenderModel = new SenderModel();
newSenderModel.setName(senderName);
@ -927,6 +993,7 @@ public class SenderActivity extends AppCompatActivity {
String secret = editTextWebNotifySecret.getText().trim();
String method = radioGroupWebNotifyMethod.getCheckedRadioButtonId() == R.id.radioWebNotifyMethodGet ? "GET" : "POST";
String webParams = editTextWebNotifyWebParams.getText().toString().trim();
Map<String, String> headers = getHeadersFromHeaderItemMap(headerItemMap);
if (!CommonUtil.checkUrl(webServer, false)) {
ToastUtils.delayedShow(R.string.invalid_webserver, 3000);
@ -935,7 +1002,7 @@ public class SenderActivity extends AppCompatActivity {
try {
SmsVo smsVo = new SmsVo(getString(R.string.test_phone_num), getString(R.string.test_sender_sms), new Date(), getString(R.string.test_sim_info));
SenderWebNotifyMsg.sendMsg(0, handler, null, webServer, webParams, secret, method, smsVo, "", "");
SenderWebNotifyMsg.sendMsg(0, handler, null, webServer, webParams, secret, method, headers, smsVo, "", "");
} catch (Exception e) {
ToastUtils.delayedShow(getString(R.string.failed_to_fwd) + e.getMessage(), 3000);
e.printStackTrace();

View File

@ -3,6 +3,7 @@ package com.idormy.sms.forwarder.model.vo;
import com.idormy.sms.forwarder.R;
import java.io.Serializable;
import java.util.Map;
import lombok.Data;
@ -12,15 +13,17 @@ public class WebNotifySettingVo implements Serializable {
private String secret;
private String method;
private String webParams;
private Map<String, String> headers;
public WebNotifySettingVo() {
}
public WebNotifySettingVo(String webServer, String secret, String method, String webParams) {
public WebNotifySettingVo(String webServer, String secret, String method, String webParams, Map<String, String> headers) {
this.webServer = webServer;
this.secret = secret;
this.method = method;
this.webParams = webParams;
this.headers = headers;
}
public int getWebNotifyMethodCheckId() {

View File

@ -241,7 +241,7 @@ public class SendUtil {
WebNotifySettingVo webNotifySettingVo = JSON.parseObject(senderModel.getJsonSetting(), WebNotifySettingVo.class);
if (webNotifySettingVo != null) {
try {
SenderWebNotifyMsg.sendMsg(logId, handError, retryInterceptor, webNotifySettingVo.getWebServer(), webNotifySettingVo.getWebParams(), webNotifySettingVo.getSecret(), webNotifySettingVo.getMethod(), smsVo, smsTemplate, regexReplace);
SenderWebNotifyMsg.sendMsg(logId, handError, retryInterceptor, webNotifySettingVo.getWebServer(), webNotifySettingVo.getWebParams(), webNotifySettingVo.getSecret(), webNotifySettingVo.getMethod(), webNotifySettingVo.getHeaders(), smsVo, smsTemplate, regexReplace);
} catch (Exception e) {
LogUtil.updateLog(logId, 0, e.getMessage());
Log.e(TAG, "senderSendMsg: SenderWebNotifyMsg error " + e.getMessage());

View File

@ -19,6 +19,7 @@ import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@ -39,7 +40,7 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
static final String TAG = "SenderWebNotifyMsg";
public static void sendMsg(final long logId, final Handler handError, final RetryIntercepter retryInterceptor, String webServer, String webParams, String secret, String method, SmsVo smsVo, String smsTemplate, String regexReplace) throws Exception {
public static void sendMsg(final long logId, final Handler handError, final RetryIntercepter retryInterceptor, String webServer, String webParams, String secret, String method, Map<String, String> headers, SmsVo smsVo, String smsTemplate, String regexReplace) throws Exception {
String from = smsVo.getMobile();
String content = smsVo.getSmsVoForSend(smsTemplate, regexReplace);
Log.i(TAG, "sendMsg webServer:" + webServer + " webParams:" + webParams + " from:" + from + " content:" + content);
@ -65,7 +66,7 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
Log.i(TAG, "sign:" + sign);
}
Request request;
Request.Builder requestBuilder;
if (method.equals("GET") && TextUtils.isEmpty(webParams)) {
webServer += (webServer.contains("?") ? "&" : "?") + "from=" + URLEncoder.encode(from, "UTF-8");
webServer += "&content=" + URLEncoder.encode(content, "UTF-8");
@ -75,7 +76,7 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
}
Log.d(TAG, "method = GET, Url = " + webServer);
request = new Request.Builder().url(webServer).get().build();
requestBuilder = new Request.Builder().url(webServer).get();
} else if (method.equals("GET") && !TextUtils.isEmpty(webParams)) {
webParams = webParams.replace("[from]", URLEncoder.encode(from, "UTF-8"))
.replace("[content]", URLEncoder.encode(content, "UTF-8"))
@ -94,7 +95,7 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
webServer += (webServer.contains("?") ? "&" : "?") + webParams;
Log.d(TAG, "method = GET, Url = " + webServer);
request = new Request.Builder().url(webServer).get().build();
requestBuilder = new Request.Builder().url(webServer).get();
} else if (webParams != null && webParams.contains("[msg]")) {
String bodyMsg;
String contentType = "application/x-www-form-urlencoded";
@ -121,11 +122,10 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
.replace("[receive_time]", URLEncoder.encode(receiveTime, "UTF-8"));
}
RequestBody body = RequestBody.create(MediaType.parse(contentType), bodyMsg);
request = new Request.Builder()
requestBuilder = new Request.Builder()
.url(webServer)
.addHeader("Content-Type", contentType)
.method("POST", body)
.build();
.method("POST", body);
Log.d(TAG, "method = POST webParams, Body = " + bodyMsg);
} else {
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM)
@ -138,7 +138,11 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
RequestBody body = builder.build();
Log.d(TAG, "method = POST, Body = " + body);
request = new Request.Builder().url(webServer).method("POST", body).build();
requestBuilder = new Request.Builder().url(webServer).method("POST", body);
}
for (Map.Entry<String, String> entry : headers.entrySet()) {
requestBuilder.addHeader(entry.getKey(), entry.getValue());
}
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
@ -153,7 +157,7 @@ public class SenderWebNotifyMsg extends SenderBaseMsg {
.connectTimeout(Define.REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.build();
client.newCall(request).enqueue(new Callback() {
client.newCall(requestBuilder.build()).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull final IOException e) {
LogUtil.updateLog(logId, 0, e.getMessage());

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="1024"
android:viewportWidth="1024">
<path
android:fillColor="@color/colorPrimary"
android:pathData="M828.7,196.58c-84.61,-84.19 -197.06,-130.56 -316.7,-130.56s-232.13,46.37 -316.74,130.56C110.62,280.8 64,392.83 64,512c0,119.2 46.62,231.2 131.23,315.42 84.61,84.19 197.09,130.56 316.74,130.56s232.13,-46.37 316.7,-130.56c84.67,-84.26 131.3,-196.29 131.26,-315.46C959.97,392.8 913.38,280.8 828.7,196.58zM736,544l-192,0 0,192c0,17.7 -14.34,32 -32,32s-32,-14.3 -32,-32l0,-192L288,544c-17.66,0 -32,-14.34 -32,-32s14.34,-32 32,-32l192,0L480,288c0,-17.66 14.34,-32 32,-32s32,14.34 32,32l0,192 192,0c17.7,0 32,14.34 32,32S753.7,544 736,544z" />
</vector>

View File

@ -169,6 +169,37 @@
app:showEye="true" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutWebNotifyHeaders"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables,UselessParent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/headers"
android:textStyle="bold" />
<ImageView
android:id="@+id/imageViewWebNotifyAddHeader"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_add_round_fill"
android:contentDescription="@string/header_add" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
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/header_key" />
<EditText
android:id="@+id/editTextHeaderKey"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:autofillHints=""
android:inputType="text"
android:singleLine="true"
tools:ignore="LabelFor" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/header_value" />
<EditText
android:id="@+id/editTextHeaderValue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:autofillHints=""
android:inputType="text"
android:singleLine="true"
tools:ignore="LabelFor" />
<ImageView
android:id="@+id/imageViewRemoveHeader"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_delete"
app:tint="@color/design_default_color_error"
android:contentDescription="@string/header_del" />
</LinearLayout>

View File

@ -24,6 +24,11 @@
<string name="clear_logs">Clear logs</string>
<string name="add_rule">Add rule</string>
<string name="add_sender">Add sender</string>
<string name="headers">Headers</string>
<string name="header_key">Key</string>
<string name="header_value">Value</string>
<string name="header_add">Add Header</string>
<string name="header_del">Remove Header</string>h
<!--AboutActivity-->
<string name="version">Version</string>
<string name="check_for_updates">Check for updates</string>

View File

@ -24,6 +24,11 @@
<string name="clear_logs">清空日志</string>
<string name="add_rule">清空日志</string>
<string name="add_sender">添加发送通道</string>
<string name="headers">Headers</string>
<string name="header_key">Key</string>
<string name="header_value">Value</string>
<string name="header_add">添加Header</string>
<string name="header_del">删除Header</string>
<!--AboutActivity-->
<string name="version">当前版本</string>
<string name="check_for_updates">检查新版本</string>