Skip to content

Commit

Permalink
3.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
idranme committed Jun 11, 2024
1 parent 5396082 commit 230a65e
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 50 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-plugin-adapter-red",
"description": "Red Protocol Adapter for Koishi",
"version": "3.1.9",
"version": "3.2.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"files": [
Expand All @@ -26,7 +26,7 @@
"url": "https://github.com/idranme/koishi-plugin-adapter-red/issues"
},
"peerDependencies": {
"koishi": "^4.17.3"
"koishi": "^4.17.7"
},
"devDependencies": {
"@koishijs/plugin-server": "^3.2.1",
Expand Down
26 changes: 12 additions & 14 deletions src/assets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, sanitize, trimSlash, Quester, Dict } from 'koishi'
import { Context, sanitize, trimSlash, HTTP, Dict } from 'koishi'
import { RedBot } from './bot'
import { Message } from './types'
import { Readable } from 'node:stream'
Expand Down Expand Up @@ -45,22 +45,21 @@ export class RedAssets<C extends Context = Context> {
this.bot.ctx.on('server/ready', () => {
this.bot.logger.info(`assets are located at ${this.selfUrl}${this.path}`)

this.bot.ctx.server.get(this.path, async (ctx, next) => {
ctx.body = '200 OK'
ctx.status = 200
return next()
this.bot.ctx.server.get(this.path, async (koa) => {
koa.body = '200 OK'
koa.status = 200
})

this.bot.ctx.server.get(this.path + '/:data', async (ctx, next) => {
const data = ctx.params['data']
this.bot.ctx.server.get(this.path + '/:data', async (koa) => {
const data = koa.params['data']
let payload: Dict
if (data.endsWith('=')) {
payload = JSON.parse(Buffer.from(data, 'base64').toString())
} else {
payload = JSON.parse(Buffer.from(data, 'base64url').toString())
}
const mime = payload.mime
let file: Quester.Response<ReadableStream>
let file: HTTP.Response<ReadableStream>
try {
file = await this.bot.internal.getFileStream({
msgId: payload.msgId,
Expand All @@ -69,7 +68,7 @@ export class RedAssets<C extends Context = Context> {
elementId: payload.elementId,
})
} catch (err) {
if (!Quester.Error.is(err)) {
if (!HTTP.Error.is(err)) {
throw err
}
if (mime.includes('image')) {
Expand All @@ -83,15 +82,14 @@ export class RedAssets<C extends Context = Context> {
file ||= err.response
}

ctx.status = file.status
const contentType = file.headers.get('content-type')
if (contentType) {
ctx.type = contentType
koa.type = contentType
} else if (file.status === 200) {
ctx.type = mime
koa.type = mime
}
ctx.body = file.data instanceof ArrayBuffer ? Buffer.from(file.data) : Readable.fromWeb(file.data)
return next()
koa.body = file.data instanceof ArrayBuffer ? Buffer.from(file.data) : Readable.fromWeb(file.data)
koa.status = file.status
})
})
}
Expand Down
11 changes: 6 additions & 5 deletions src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Bot, Context, Schema, Quester, Universal } from 'koishi'
import { Bot, Context, Schema, HTTP, Universal } from 'koishi'
import { WsClient } from './ws'
import { Message } from './types'
import { RedMessageEncoder } from './message'
Expand All @@ -12,7 +12,7 @@ export class RedBot<C extends Context = Context> extends Bot<C, RedBot.Config> {
optional: ['ffmpeg', 'silk']
}
static MessageEncoder = RedMessageEncoder
http: Quester
http: HTTP
internal: Internal
redSeq: Map<string, string[]>
redAssets: RedAssets
Expand Down Expand Up @@ -118,7 +118,8 @@ export class RedBot<C extends Context = Context> extends Bot<C, RedBot.Config> {
}
}

async getMessageList(channelId: string, next?: string) {
async getMessageList(channelId: string, next?: string, direction: Universal.Direction = 'before') {
if (direction !== 'before') throw new Error('Unsupported direction.')
const { msgList } = await this.internal.getMessages({
peer: getPeer(channelId),
offsetMsgId: next,
Expand Down Expand Up @@ -152,7 +153,7 @@ export class RedBot<C extends Context = Context> extends Bot<C, RedBot.Config> {
}

export namespace RedBot {
export interface Config extends Quester.Config, WsClient.Options {
export interface Config extends HTTP.Config, WsClient.Options {
token: string
selfId: string
path: string
Expand All @@ -170,7 +171,7 @@ export namespace RedBot {
selfUrl: Schema.string().role('link').description('Koishi 服务暴露在公网的地址。缺省时将使用全局配置。')
}).description('资源设置'),
WsClient.Options,
Quester.createConfig('http://127.0.0.1:16530/'),
HTTP.createConfig('http://127.0.0.1:16530/'),
Schema.object({
splitMixedContent: Schema.boolean().default(false).description('是否自动在接收到的混合内容间插入空格。')
}).description('高级设置'),
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ type RedEvents = {
[T in keyof Red.GatewayEvents as `red/${ParamCase<T>}`]: (input: Red.GatewayEvents[T], bot: RedBot) => void
}

declare module '@satorijs/core' {
declare module 'koishi' {
interface Events extends RedEvents { }
}
}
4 changes: 2 additions & 2 deletions src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Quester } from 'koishi'
import { HTTP } from 'koishi'
import * as Red from './types'

export class Internal {
constructor(private http: Quester) { }
constructor(private http: HTTP) { }

uploadFile(file: FormData) {
return this.http.post<Red.UploadResponse>('/api/upload', file)
Expand Down
26 changes: 13 additions & 13 deletions src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,20 @@ export class RedMessageEncoder<C extends Context = Context> extends MessageEncod
elementType: 1,
textElement: {
atType: 0,
content,
content
}
})
}

private async image(attrs: Dict) {
const url = attrs.src || attrs.url.toString()
const { data, mime, filename } = await this.fetchFile(url, attrs)
if (mime?.includes('text')) {
const { data, type, filename } = await this.fetchFile(url, attrs)
if (type?.includes('text')) {
this.bot.logger.warn(`try to send an image using a URL that may not be pointing to the image, which is ${url}`)
}
const form = new FormData()
const blob = new Blob([data], { type: mime || 'application/octet-stream' })
form.append('file', blob, 'file' + extname(filename))
const value = new Blob([data], { type })
form.append('file', value, 'file' + extname(filename))
const file = await this.bot.internal.uploadFile(form)

const picType = {
Expand All @@ -97,10 +97,10 @@ export class RedMessageEncoder<C extends Context = Context> extends MessageEncod
}

private async file(attrs: Dict) {
const { data, filename, mime } = await this.fetchFile(attrs.src || attrs.url, attrs)
const { data, filename, type } = await this.fetchFile(attrs.src || attrs.url, attrs)
const form = new FormData()
const blob = new Blob([data], { type: mime || 'application/octet-stream' })
form.append('file', blob, filename)
const value = new Blob([data], { type })
form.append('file', value, filename)
const res = await this.bot.internal.uploadFile(form)

this.payload.elements.push({
Expand Down Expand Up @@ -158,8 +158,8 @@ export class RedMessageEncoder<C extends Context = Context> extends MessageEncod
duration ||= Math.round(ctx.silk.getDuration(voice) / 1000)

const form = new FormData()
const blob = new Blob([voice], { type: 'audio/amr' })
form.append('file', blob, 'file.amr')
const value = new Blob([voice], { type: 'audio/amr' })
form.append('file', value, 'file.amr')
const file = await this.bot.internal.uploadFile(form)

this.payload.elements.push({
Expand All @@ -179,11 +179,11 @@ export class RedMessageEncoder<C extends Context = Context> extends MessageEncod
}

private async video(attrs: Dict) {
const { data, filename, mime } = await this.fetchFile(attrs.src || attrs.url, attrs)
const { data, filename, type } = await this.fetchFile(attrs.src || attrs.url, attrs)

const form = new FormData()
const blob = new Blob([data], { type: mime || 'application/octet-stream' })
form.append('file', blob, 'file' + extname(filename))
const value = new Blob([data], { type })
form.append('file', value, 'file' + extname(filename))
const file = await this.bot.internal.uploadFile(form)

let filePath = file.ntFilePath.replaceAll('\\', '/')
Expand Down
17 changes: 10 additions & 7 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ export async function decodeMessage(
const { atType, atUid, content, atNtUin } = v.textElement
if (atType === 1) {
newElement = h('at', { type: 'all' })
}
if (atType === 2) {
} else if (atType === 2) {
newElement = h.at(atNtUin || atUid, { name: content.replace('@', '') })
}
newElement ||= h.text(v.textElement.content)
Expand Down Expand Up @@ -140,9 +139,8 @@ export async function decodeMessage(
}
case 7: {
if (quoted) continue
const { replayMsgSeq, replayMsgId } = v.replyElement
const key = `${data.chatType}/${data.peerUin}/${replayMsgSeq}`
const [msgId, firstElementId] = replayMsgId !== '0' ? [replayMsgId] : (bot.redSeq.get(key) ?? [])
const key = `${data.chatType}/${data.peerUin}/${v.replyElement}`
const [msgId, firstElementId] = bot.redSeq.get(key) ?? []
const record = data.records[0]
const elements = record && await parse(record, msgId, firstElementId, true)
message.quote = {
Expand All @@ -161,7 +159,12 @@ export async function decodeMessage(
const { width = 200, height = 200 } = supportSize?.[0] ?? {}
const name = faceName.replace('[', '').replace(']', '')
const url = `https://gxh.vip.qq.com/club/item/parcel/item/${emojiId.slice(0, 2)}/${emojiId}/raw${width}.gif`
newElement = h('red:mface', { id: emojiId, name, key, packageId: String(emojiPackageId) }, [h.image(url, { width, height })])
newElement = h('red:mface', {
id: emojiId,
name,
key,
packageId: String(emojiPackageId)
}, [h.image(url, { width, height })])
break
}
}
Expand Down Expand Up @@ -201,7 +204,7 @@ export async function decodeMessage(
return message
}

const decodeGuildChannelId = (data: Message) => {
function decodeGuildChannelId(data: Message) {
if (data.chatType === 2) {
return [data.peerUin, data.peerUin]
} else if (data.chatType === 100) {
Expand Down
6 changes: 3 additions & 3 deletions src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, R
return this.bot.dispatch(this.bot.session({
type: 'internal',
_type: 'red/unsafe-notify',
_data: parsed.payload[0],
_data: parsed.payload[0]
}))
} else if (parsed.type === 'message::recv') {
this.bot.dispatch(this.bot.session({
type: 'internal',
_type: 'red/unsafe-message',
_data: parsed.payload[0],
_data: parsed.payload[0]
}))
}

Expand All @@ -53,6 +53,6 @@ export namespace WsClient {
}

export const Options: Schema<Options> = Schema.intersect([
Adapter.WsClientConfig,
Adapter.WsClientConfig
])
}
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
"rootDir": "src",
"outDir": "lib",
"target": "es2022",
"module": "commonjs",
"module": "esnext",
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"incremental": true,
"skipLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "node",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "@satorijs/element",
"types": [
Expand Down

0 comments on commit 230a65e

Please sign in to comment.