Skip to content

Commit

Permalink
发送文件时支持别名 (#184)
Browse files Browse the repository at this point in the history
❤️ contributor: @Cassius0924 

## todo @danni-cool 
- <del>接口参数校验检查</del>
- <del> 推消息v1 接口参数检查</del>
- <del> 推消息 v2 接口参数检查</del>
- [x] downloadurl 解析 ? query参数 $alias
- [x] 核心逻辑修改
- [x] 用例测试
  • Loading branch information
danni-cool authored Mar 18, 2024
2 parents 5d191f1 + f0181ee commit 1f580a4
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,22 @@ curl --location 'http://localhost:3001/webhook/msg/v2?token=[YOUR_PERSONAL_TOKEN
}'
```

##### 发文件 url 同时支持修改成目标文件名

> 有些情况下,直接发送 url 文件名可能不是我们想要的,给 url 拼接 query 参数 `$alias` 可用于指定发送给目标的文件名(注意:别名不做文件转换)
```bash
curl --location 'http://localhost:3001/webhook/msg/v2?token=[YOUR_PERSONAL_TOKEN]' \
--header 'Content-Type: application/json' \
--data '{
"to": "testUser",
"data": {
"type": "fileUrl" ,
"content": "https://download.samplelib.com/jpeg/sample-clouds-400x300.jpg?$alias=cloud.jpg"
}
}'
```

##### 发给群消息

```bash
Expand Down
40 changes: 23 additions & 17 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
const { FileBox } = require('file-box')
const MIME = require('mime')
const { logger } = require('./log')
const { URL } = require('url')
/**
* 下载媒体文件转化为Buffer
* @param {string} fileUrl
* @returns {Promise<{buffer?: Buffer, fileName?: string}>}
* @returns {Promise<{buffer?: Buffer, fileName?: string, fileNameAlias?: string}>}
*/
const downloadFile = async (fileUrl) => {
try {
const response = await fetch(fileUrl)

if (response.ok) {
const buffer = Buffer.from(await response.arrayBuffer())
let fileName = getFileNameFromUrl(fileUrl)
// 使用自定义文件名,解决URL无文件后缀名时,文件被微信解析成不正确的后缀问题
let { fileName, query } = getFileInfoFromUrl(fileUrl)

// deal with unValid Url format like https://pangji-home.com/Fi5DimeGHBLQ3KcELn3DolvENjVU
if (fileName === '') {
Expand All @@ -24,7 +26,8 @@ const downloadFile = async (fileUrl) => {

return {
buffer,
fileName
fileName,
fileNameAlias: query?.$alias
}
}

Expand All @@ -36,25 +39,29 @@ const downloadFile = async (fileUrl) => {
}

/**
* @typedef {{fileName: string, query: null | Record<string, string>} } fileInfoObj
* 从url中提取文件名
* @param {string} url
* @returns {string}
* @returns {fileInfoObj}
* @example 参数 url 示例
* valid: "http://www.baidu.com/image.png?a=1 => image.png"
* notValid: "https://pangji-home.com/Fi5DimeGHBLQ3KcELn3DolvENjVU => ''"
*/
const getFileNameFromUrl = (url) => {
const matchRes = url.match(/.*\/([^/?]*)/)?.[1]

if (matchRes === undefined) return ''
const getFileInfoFromUrl = (url) => {
/** @type {fileInfoObj} */
let matchRes = {
fileName: url.match(/.*\/([^/?]*)/)?.[1] || '', // fileName has string.string is Valid filename
query: null
}

const checkMathDotPosition = matchRes.indexOf('.')
// fileName has string.string is Valid filename
if (checkMathDotPosition > -1) {
return matchRes
} else {
return ''
try {
const urlObj = new URL(url)
matchRes.query = Object.fromEntries(urlObj.searchParams)
} catch (e) {
// make ts happy
}

return matchRes
}

/**
Expand All @@ -63,9 +70,9 @@ const getFileNameFromUrl = (url) => {
* @returns {Promise<import('file-box').FileBoxInterface>}
*/
const getMediaFromUrl = async (url) => {
const { buffer, fileName } = await downloadFile(url)
const { buffer, fileName, fileNameAlias } = await downloadFile(url)
//@ts-expect-errors buffer 解析是吧的情况
return FileBox.fromBuffer(buffer, fileName)
return FileBox.fromBuffer(buffer, fileNameAlias || fileName)
}

/**
Expand Down Expand Up @@ -187,7 +194,6 @@ module.exports = {
...require('./nextTick.js'),
...require('./paramsValid.js'),
...require('./log.js'),
getFileNameFromUrl,
getMediaFromUrl,
getBufferFile,
generateToken,
Expand Down

0 comments on commit 1f580a4

Please sign in to comment.