Skip to content

Commit

Permalink
feat(kaiheila): support card message
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 25, 2021
1 parent 7d53bc2 commit 41566d9
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 77 deletions.
127 changes: 50 additions & 77 deletions packages/adapter-kaiheila/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { AuthorInfo, Bot, MessageInfo } from 'koishi-core'
import { camelize, segment, pick, renameProperty, snakeCase } from 'koishi-utils'
import axios, { Method } from 'axios'
import * as Kaiheila from './types'
import * as KHL from './types'
import { adaptGroup, adaptAuthor, adaptUser } from './utils'

export interface KaiheilaMessageInfo extends MessageInfo {
Expand Down Expand Up @@ -69,69 +69,16 @@ export class KaiheilaBot extends Bot {
return result.data
}

private parseQuote(chain: segment.Chain) {
if (chain[0].type !== 'quote') return
return chain.shift().data.id
}

private parseNode(node: segment.Parsed) {
if (node.type === 'image') {
return { type: 'image', src: node.data.url, size: node.data.size }
} else if (node.type === 'button') {
return { type: 'button', text: node.data.content }
}
}

private parseCard(chain: segment.Chain) {
if (chain[0].type !== 'card') return
const node = chain.shift()
const card = { type: 'card', modules: [], ...pick(node.data, ['theme', 'color', 'size']) }
for (const node of chain) {
if (node.type === 'text') {
card.modules.push({ type: 'plain-text', content: node.data.content })
} else if (node.type === 'header') {
card.modules.push({ type: 'header', text: { type: 'plain-text', content: node.data.content } })
} else if (node.type === 'section') {
card.modules.push({
type: 'section',
mode: node.data.mode,
text: { type: 'kmarkdown', content: node.data.content },
accessory: this.parseNode(segment.from(node.data.accessory)),
})
} else if (node.type === 'divider') {
card.modules.push({ type: 'divider' })
}
}
return JSON.stringify([card])
}

private renderText(chain: segment.Chain) {
return chain.reduce<string>((prev, code) => {
const { type, data } = code
if (type === 'text') {
return prev + data.content
} else if (type === 'at') {
if (data.id) return prev + `@user#${data.id}`
if (data.type === 'all') return prev + '@全体成员'
if (data.type === 'here') return prev + '@在线成员'
if (data.role) return prev + `@role:${data.role};`
} else if (type === 'sharp') {
return prev + `#channel:${data.id};`
}
return prev
}, '')
}

async sendMessage(channelId: string, content: string) {
let path: string
const params: any = { type: 1 }
const params = {} as KHL.MessageParams
const session = this.createSession({ channelId, content })
if (channelId.length > 30) {
params.chatCode = channelId
session.subtype = 'private'
path = '/user-chat/create-msg'
} else {
params.channelId = channelId
params.targetId = channelId
session.subtype = 'group'
// FIXME this is incorrect but to workarournd ctx.group()
session.groupId = 'unknown'
Expand All @@ -141,22 +88,51 @@ export class KaiheilaBot extends Bot {
// trigger before-send
if (await this.app.serial(session, 'before-send', session)) return

// parse quote
const chain = segment.parse(session.content)
params.quote = this.parseQuote(chain)
let textBuffer = ''
const flush = async () => {
textBuffer = textBuffer.trim()
if (!textBuffer) return
params.type = KHL.Type.text
params.content = textBuffer
const message = await this.request('POST', path, params)
session.messageId = message.msgId
this.app.emit(session, 'send', session)
params.quote = null
textBuffer = ''
}

// parse card
const card = this.parseCard(chain)
if (card) {
params.type = Kaiheila.Type.card
params.content = card
} else {
params.content = this.renderText(chain)
const chain = segment.parse(content)
if (chain[0].type === 'quote') {
params.quote = chain.shift().data.id
}
for (const { type, data } of chain) {
if (type === 'text') {
textBuffer += data.content
} else if (type === 'at') {
if (data.id) {
textBuffer += `@user#${data.id}`
} else if (data.type === 'all') {
textBuffer += '@全体成员'
} else if (data.type === 'here') {
textBuffer += '@在线成员'
} else if (data.role) {
textBuffer += `@role:${data.role};`
}
} else if (type === 'sharp') {
textBuffer += `#channel:${data.id};`
} else if (type === 'card') {
await flush()
params.type = KHL.Type.card
params.content = JSON.stringify([JSON.parse(data.content)])
console.log(params)
const message = await this.request('POST', path, params)
session.messageId = message.msgId
this.app.emit(session, 'send', session)
}
}

const message = await this.request('POST', path, params)
this.app.emit(session, 'send', session)
return session.messageId = message.msgId
await flush()
return session.messageId
}

async sendPrivateMessage(targetId: string, content: string) {
Expand All @@ -173,29 +149,26 @@ export class KaiheilaBot extends Bot {
}

async editMessage(channelId: string, msgId: string, content: string) {
const chain = segment.parse(content)
const quote = this.parseQuote(chain)
content = this.renderText(chain)
if (channelId.length > 30) {
await this.request('POST', '/user-chat/update-msg', { msgId, content, quote })
await this.request('POST', '/user-chat/update-msg', { msgId, content })
} else {
await this.request('POST', '/message/update', { msgId, content, quote })
await this.request('POST', '/message/update', { msgId, content })
}
}

async getSelf() {
const data = adaptUser(await this.request<Kaiheila.Self>('GET', '/user/me'))
const data = adaptUser(await this.request<KHL.Self>('GET', '/user/me'))
renameProperty(data, 'selfId' as never, 'userId')
return data
}

async getGroupList() {
const { items } = await this.request<Kaiheila.GuildList>('GET', '/guild/list')
const { items } = await this.request<KHL.GuildList>('GET', '/guild/list')
return items.map(adaptGroup)
}

async getGroupMemberList() {
const { items } = await this.request<Kaiheila.GuildMemberList>('GET', '/guild/user-list')
const { items } = await this.request<KHL.GuildMemberList>('GET', '/guild/user-list')
return items.map(adaptAuthor)
}

Expand Down
10 changes: 10 additions & 0 deletions packages/adapter-kaiheila/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ export enum Type {
system = 255,
}

export interface MessageParams {
type: Type
msgId: string
chatCode: string
targetId: string
content: any
quote: string
nonce: string
}

export interface MessageBase {
type: Type
content: string
Expand Down

0 comments on commit 41566d9

Please sign in to comment.