Skip to content

Commit

Permalink
feat: Add Batch Push
Browse files Browse the repository at this point in the history
  • Loading branch information
cwxia0s committed Dec 24, 2024
1 parent 157609b commit 26bac99
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 29 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ English | **[中文文档](README.zh.md)**
> [!NOTE]
> Device token may change, the previous way to use multi-key or key alias may be unavailable, refer to [Tips](doc/tips.md) for more details.
> [!NOTE]
> Batch Push has the highest priority, if `device_keys` is specified and not empty, `device_key` will be ignored, in both V1 and V2 APIs.
<!-- > [!CAUTION]
> For D1 Alpha Users: On August 1, 2024, D1 alpha databases will stop accepting live SQL queries. See [Migration Guide](https://developers.cloudflare.com/d1/platform/alpha-migration/) -->

Expand Down
3 changes: 3 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
> [!NOTE]
> Device token可能发生变化, 之前使用多Key或Key别名的方法可能会失效, 如有多Key使用需要参考[Tips](doc/tips.zh.md).
> [!NOTE]
> 批量推送有最高优先级, 如果指定了`device_keys`且不为空, `device_key`将被忽略.
<!-- > [!CAUTION]
> 对于D1 Alpha用户: 在2024-08-01之后, D1 Alpha数据库将停止接受SQL查询,需要使用新的D1数据库,参考[迁移指南](https://developers.cloudflare.com/d1/platform/alpha-migration/) -->

Expand Down
61 changes: 47 additions & 14 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const rootPath = '/'
const basicAuth = ''

async function handleRequest(request, env, ctx) {
const { searchParams, pathname } = new URL(request.url)
const {searchParams, pathname} = new URL(request.url)
const handler = new Handler(env)
const realPathname = pathname.replace((new RegExp('^'+rootPath.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"))), '/')
const realPathname = pathname.replace((new RegExp('^' + rootPath.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"))), '/')

switch (realPathname) {
case "/register": {
Expand Down Expand Up @@ -76,10 +76,13 @@ async function handleRequest(request, env, ctx) {
requestBody.body = pathParts[4]
}
}
} catch (err) {
if (requestBody.device_keys && typeof requestBody.device_keys === 'string') {
requestBody.device_keys = requestBody.device_keys.split(',').map(item => item.trim())
}
} catch (error) {
return new Response(JSON.stringify({
'code': 400,
'message': `request bind failed: ${err}`,
'message': `request bind failed: ${error}`,
'timestamp': util.getTimestamp(),
}), {
status: 400,
Expand All @@ -89,6 +92,36 @@ async function handleRequest(request, env, ctx) {
})
}

if (requestBody.device_keys && requestBody.device_keys.length > 0) {
return new Response(JSON.stringify({
'code': 200,
'message': 'success',
'data': await Promise.all(requestBody.device_keys.map(async (device_key) => {
if (!device_key) {
return {
message: 'device key is empty',
code: 400,
device_key: device_key,
}
}

const response = await handler.push({...requestBody, device_key})
const responseBody = await response.json()
return {
message: responseBody.message,
code: response.status,
device_key: device_key,
}
})),
'timestamp': util.getTimestamp(),
}), {
status: 200,
headers: {
'content-type': 'application/json',
}
})
}

if (realPathname != '/push') {
requestBody.device_key = pathParts[1]
}
Expand Down Expand Up @@ -128,10 +161,10 @@ async function handleRequest(request, env, ctx) {
*/
class Handler {
constructor(env) {
this.version = "v2.1.4"
this.build = "2024-12-16 18:27:31"
this.version = "v2.1.5"
this.build = "2024-12-24 20:46:57"
this.arch = "js"
this.commit = "10d6f31e53bddb011290fffa7b7ede7dd7dec666"
this.commit = "157609b4732361a55f3bb1bb6eb7d5ac31d2a583"

const db = new Database(env)

Expand All @@ -141,8 +174,8 @@ class Handler {

if (!deviceToken) {
return new Response(JSON.stringify({
'message': 'device token is empty',
'code': 400,
'message': 'device token is empty',
'timestamp': util.getTimestamp(),
}), {
status: 400,
Expand All @@ -157,8 +190,8 @@ class Handler {
key = util.newShortUUID()
} else {
return new Response(JSON.stringify({
'message': "device registration failed: register disabled",
'code': 500,
'message': "device registration failed: register disabled",
}), {
status: 500,
headers: {
Expand All @@ -171,8 +204,8 @@ class Handler {
await db.saveDeviceTokenByKey(key, deviceToken)

return new Response(JSON.stringify({
'message': 'success',
'code': 200,
'message': 'success',
'timestamp': util.getTimestamp(),
'data': {
'key': key,
Expand All @@ -189,8 +222,8 @@ class Handler {

this.ping = async (parameters) => {
return new Response(JSON.stringify({
'message': 'pong',
'code': 200,
'message': 'pong',
'timestamp': util.getTimestamp(),
}), {
status: 200,
Expand Down Expand Up @@ -333,8 +366,8 @@ class Handler {

if (response.status === 200) {
return new Response(JSON.stringify({
'message': 'success',
'code': 200,
'message': 'success',
'timestamp': util.getTimestamp(),
}), {
status: 200,
Expand All @@ -353,8 +386,8 @@ class Handler {
}

return new Response(JSON.stringify({
'message': `push failed: ${message}`,
'code': response.status,
'message': `push failed: ${message}`,
'timestamp': util.getTimestamp(),
}), {
status: response.status,
Expand Down Expand Up @@ -531,4 +564,4 @@ class Util {
}
}

const util = new Util()
const util = new Util()
60 changes: 47 additions & 13 deletions main_kv.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const rootPath = '/'
const basicAuth = ''

async function handleRequest(request, env, ctx) {
const { searchParams, pathname } = new URL(request.url)
const {searchParams, pathname} = new URL(request.url)
const handler = new Handler(env)
const realPathname = pathname.replace((new RegExp('^'+rootPath.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"))), '/')
const realPathname = pathname.replace((new RegExp('^' + rootPath.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"))), '/')

switch (realPathname) {
case "/register": {
Expand Down Expand Up @@ -76,10 +76,13 @@ async function handleRequest(request, env, ctx) {
requestBody.body = pathParts[4]
}
}
} catch (err) {
if (requestBody.device_keys && typeof requestBody.device_keys === 'string') {
requestBody.device_keys = requestBody.device_keys.split(',').map(item => item.trim())
}
} catch (error) {
return new Response(JSON.stringify({
'code': 400,
'message': `request bind failed: ${err}`,
'message': `request bind failed: ${error}`,
'timestamp': util.getTimestamp(),
}), {
status: 400,
Expand All @@ -89,6 +92,36 @@ async function handleRequest(request, env, ctx) {
})
}

if (requestBody.device_keys && requestBody.device_keys.length > 0) {
return new Response(JSON.stringify({
'code': 200,
'message': 'success',
'data': await Promise.all(requestBody.device_keys.map(async (device_key) => {
if (!device_key) {
return {
message: 'device key is empty',
code: 400,
device_key: device_key,
}
}

const response = await handler.push({...requestBody, device_key})
const responseBody = await response.json()
return {
message: responseBody.message,
code: response.status,
device_key: device_key,
}
})),
'timestamp': util.getTimestamp(),
}), {
status: 200,
headers: {
'content-type': 'application/json',
}
})
}

if (realPathname != '/push') {
requestBody.device_key = pathParts[1]
}
Expand Down Expand Up @@ -128,10 +161,10 @@ async function handleRequest(request, env, ctx) {
*/
class Handler {
constructor(env) {
this.version = "v2.1.4"
this.build = "2024-12-16 18:27:31"
this.version = "v2.1.5"
this.build = "2024-12-24 20:46:57"
this.arch = "js"
this.commit = "10d6f31e53bddb011290fffa7b7ede7dd7dec666"
this.commit = "157609b4732361a55f3bb1bb6eb7d5ac31d2a583"

const db = new Database(env)

Expand All @@ -141,8 +174,8 @@ class Handler {

if (!deviceToken) {
return new Response(JSON.stringify({
'message': 'device token is empty',
'code': 400,
'message': 'device token is empty',
'timestamp': util.getTimestamp(),
}), {
status: 400,
Expand All @@ -157,8 +190,8 @@ class Handler {
key = util.newShortUUID()
} else {
return new Response(JSON.stringify({
'message': "device registration failed: register disabled",
'code': 500,
'message': "device registration failed: register disabled",
}), {
status: 500,
headers: {
Expand All @@ -171,8 +204,8 @@ class Handler {
await db.saveDeviceTokenByKey(key, deviceToken)

return new Response(JSON.stringify({
'message': 'success',
'code': 200,
'message': 'success',
'timestamp': util.getTimestamp(),
'data': {
'key': key,
Expand All @@ -189,8 +222,8 @@ class Handler {

this.ping = async (parameters) => {
return new Response(JSON.stringify({
'message': 'pong',
'code': 200,
'message': 'pong',
'timestamp': util.getTimestamp(),
}), {
status: 200,
Expand Down Expand Up @@ -333,8 +366,8 @@ class Handler {

if (response.status === 200) {
return new Response(JSON.stringify({
'message': 'success',
'code': 200,
'message': 'success',
'timestamp': util.getTimestamp(),
}), {
status: 200,
Expand All @@ -353,8 +386,8 @@ class Handler {
}

return new Response(JSON.stringify({
'message': `push failed: ${message}`,
'code': response.status,
'message': `push failed: ${message}`,
'timestamp': util.getTimestamp(),
}), {
status: response.status,
Expand Down Expand Up @@ -470,6 +503,7 @@ class Database {
}
}


/**
* Class Util
*/
Expand Down
60 changes: 58 additions & 2 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ DEVICE_KEY=""
BAD_DEVICE_KEY=""
INVALID_DEVICE_KEY=""

BATCH_PUSH_KEY_1=""
BATCH_PUSH_KEY_2=$DEVICE_KEY
BATCH_PUSH_KEY_3=$BAD_DEVICE_KEY

DEVICE_TOKEN="0000test0device0token0000"

echo -e "\e[1;32m"
Expand All @@ -30,8 +34,6 @@ curl -X "POST" "$SERVER_ADDRESS/$DEVICE_KEY" \
"isArchive": "0"
}'

# Seems that icon is not compatible with subtitle

echo ""

curl -X "POST" "$SERVER_ADDRESS/push" \
Expand Down Expand Up @@ -100,6 +102,36 @@ echo $ciphertext
# URL encoding the ciphertext, there may be special characters.
curl --data-urlencode "ciphertext=$ciphertext" $SERVER_ADDRESS/$DEVICE_KEY?isArchive=0

echo -e "\e[1;32m"
echo ""
echo "---------------------------------------------------------------------"
echo "Test Batch Push"
echo "---------------------------------------------------------------------"
echo ""
echo -e "\e[0m"

curl -X "POST" "$SERVER_ADDRESS/push" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"body": "Test Batch Message In Body",
"group": "testBatchPush",
"url": "https://mritd.com",
"isArchive": "0",
"device_keys": ["'$BATCH_PUSH_KEY_1'", "'$BATCH_PUSH_KEY_2'", "'$BATCH_PUSH_KEY_3'"]
}'

echo ""

curl -X "POST" "$SERVER_ADDRESS/push" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"body": "Test Batch Message In Body",
"group": "testBatchPush",
"url": "https://mritd.com",
"isArchive": "0",
"device_keys": "'$BATCH_PUSH_KEY_1','$BATCH_PUSH_KEY_2','$BATCH_PUSH_KEY_3'"
}'

echo -e "\e[1;32m"
echo ""
echo "---------------------------------------------------------------------"
Expand Down Expand Up @@ -163,4 +195,28 @@ echo -e "\e[0m"

curl "$SERVER_ADDRESS/push"

echo ""

curl -X "POST" "$SERVER_ADDRESS/push" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"body": "Test Batch Message In Body",
"group": "testBatchPush",
"url": "https://mritd.com",
"isArchive": "0",
"device_keys": ",,"
}'

echo ""

curl -X "POST" "$SERVER_ADDRESS/push" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"body": "Test Batch Message In Body",
"group": "testBatchPush",
"url": "https://mritd.com",
"isArchive": "0",
"device_keys": []
}'

echo ""

0 comments on commit 26bac99

Please sign in to comment.