Skip to content

Commit

Permalink
fix: button, interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
XxLittleCxX committed Oct 10, 2023
1 parent f5d6750 commit f129772
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 71 deletions.
70 changes: 44 additions & 26 deletions adapters/discord/src/message.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Dict, h, Logger, MessageEncoder, Quester, Schema, Universal } from '@satorijs/satori'
import FormData from 'form-data'
import { DiscordBot } from './bot'
import { ActionRow, Button, Channel, ComponentType, Message } from './types'
import { ActionRow, Button, ButtonStyles, Channel, ComponentType, Message } from './types'
import { decodeMessage, sanitize } from './utils'

type RenderMode = 'default' | 'figure'
Expand All @@ -26,8 +26,6 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
private mode: RenderMode = 'default'
private listType: 'ol' | 'ul' = null
private rows: ActionRow[] = []
private buttonGroupState = false

private async getUrl() {
const input = this.options?.session?.discord
if (input?.t === 'INTERACTION_CREATE') {
Expand Down Expand Up @@ -152,7 +150,8 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {

async flush() {
const content = this.buffer.trim()
if (!content) return
this.trimButtons()
if (!content && !this.rows.length) return
this.addition.components = this.rows
await this.post({ ...this.addition, content })
this.buffer = ''
Expand All @@ -161,30 +160,56 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
}

decodeButton(attrs: Dict, label: string): Button {
let style = ButtonStyles.PRIMARY
if (attrs.class === 'secondary') style = ButtonStyles.SECONDARY
if (attrs.class === 'danger') style = ButtonStyles.DANGER
if (attrs.class === 'success') style = ButtonStyles.SUCCESS
if (attrs.type === 'link') {
return {
type: ComponentType.BUTTON,
url: attrs.href,
label,
style: 5,
style: ButtonStyles.LINK,
}
} else if (attrs.type === 'action') {
} else if (attrs.type === 'input') {
return {
type: ComponentType.BUTTON,
custom_id: attrs.id,
custom_id: `input${attrs.id}:${attrs.text}`,
label,
style: 1,
style,
}
} else if (attrs.type === 'input') {
} else {
return {
type: ComponentType.BUTTON,
custom_id: 'input:' + attrs.text,
custom_id: attrs.id,
label,
style: 1,
style,
}
}
}

lastRow() {
if (!this.rows.length) {
this.rows.push({
type: ComponentType.ACTION_ROW,
components: [],
})
}
let last = this.rows[this.rows.length - 1]
if (last.components.length >= 5) {
this.rows.push({
type: ComponentType.ACTION_ROW,
components: [],
})
last = this.rows[this.rows.length - 1]
}
return last
}

trimButtons() {
if (this.rows.length && this.rows[this.rows.length - 1].components.length === 0) this.rows.pop()
}

async visit(element: h) {
const { type, attrs, children } = element
if (type === 'text') {
Expand Down Expand Up @@ -357,27 +382,20 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
}
}
} else if (type === 'button') {
if (this.buttonGroupState) {
const last = this.rows[this.rows.length - 1]
last.components.push(this.decodeButton(
attrs, children.join(''),
))
} else {
this.rows.push({
type: ComponentType.ACTION_ROW,
components: [
this.decodeButton(attrs, children.join('')),
],
})
}
const last = this.lastRow()
last.components.push(this.decodeButton(
attrs, children.join(''),
))
} else if (type === 'button-group') {
this.buttonGroupState = true
this.rows.push({
type: ComponentType.ACTION_ROW,
components: [],
})
await this.render(children)
this.buttonGroupState = false
this.rows.push({
type: ComponentType.ACTION_ROW,
components: [],
})
} else if (type === 'message' && attrs.forward) {
this.stack.unshift(new State('forward'))
await this.render(children)
Expand Down
16 changes: 8 additions & 8 deletions adapters/discord/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo
const webhook = await bot.ensureWebhook(input.d.channel_id)
// koishi's webhook
if (webhook.id === input.d.webhook_id) return
} catch (e) {}
} catch (e) { }
}
session.type = 'message'
await decodeMessage(bot, input.d, session.event.message = {}, session.event)
Expand Down Expand Up @@ -248,11 +248,11 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo
session.event.argv = decodeArgv(data, command)
} else if (input.t === 'INTERACTION_CREATE' && input.d.type === Discord.Interaction.Type.MODAL_SUBMIT) {
const data = input.d.data as Discord.InteractionData.ModalSubmit
if (!data.custom_id.startsWith('input:')) return
if (!data.custom_id.startsWith('input') && !data.custom_id.includes(':')) return
// @ts-ignore
const user_input = data.components[0].components[0].value
await bot.internal.createInteractionResponse(input.d.id, input.d.token, {
type: Discord.Interaction.CallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
type: Discord.Interaction.CallbackType.DEFERRED_UPDATE_MESSAGE,
})
session.type = 'interaction/command'
session.isDirect = !input.d.guild_id
Expand All @@ -264,27 +264,27 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo
session.content = user_input
} else if (input.t === 'INTERACTION_CREATE' && input.d.type === Discord.Interaction.Type.MESSAGE_COMPONENT) {
const id = (input.d.data as Discord.InteractionData.MessageComponent).custom_id
if (id.startsWith('input:')) {
if (id.startsWith('input') && id.includes(':')) {
await bot.internal.createInteractionResponse(input.d.id, input.d.token, {
type: Discord.Interaction.CallbackType.MODAL,
data: {
custom_id: id,
title: 'title',
title: 'Input',
components: [{
type: Discord.ComponentType.ACTION_ROW,
components: [{
custom_id: id,
type: Discord.ComponentType.TEXT_INPUT,
label: 'auto complete',
value: id.slice('input:'.length),
label: 'Command',
value: id.slice(id.indexOf(':') + 1),
style: 1,
}],
}],
},
})
} else {
await bot.internal.createInteractionResponse(input.d.id, input.d.token, {
type: Discord.Interaction.CallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
type: Discord.Interaction.CallbackType.DEFERRED_UPDATE_MESSAGE,
})
}
session.type = 'interaction/button'
Expand Down
51 changes: 32 additions & 19 deletions adapters/qq/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ export class QQGuildMessageEncoder extends MessageEncoder<QQGuildBot> {
export class QQMessageEncoder extends MessageEncoder<QQBot> {
private content: string = ''
private useMarkdown = false
private rows: QQ.InlineKeyboardRow[] = []
private buttonGroupState = false
private rows: QQ.Button[][] = []
async flush() {
if (!this.content.trim() && !this.rows.map(v => v.buttons).flat().length) return
if (!this.content.trim() && !this.rows.flat().length) return
this.trimButtons()
const data: QQ.SendMessageParams = {
content: this.content,
msg_type: 0,
Expand All @@ -162,7 +162,7 @@ export class QQMessageEncoder extends MessageEncoder<QQBot> {
if (this.rows.length) {
data.keyboard = {
content: {
rows: this.rows,
rows: this.exportButtons(),
},
}
}
Expand Down Expand Up @@ -215,20 +215,42 @@ export class QQMessageEncoder extends MessageEncoder<QQBot> {
render_data: {
label,
visited_label: label,
style: 0,
style: attrs.class === 'primary' ? 1 : 0,
},
action: {
type: attrs.type === 'input' ? 2
: (attrs.type === 'link' ? 0 : 1),
permission: {
type: 2,
},
data: attrs.data,
data: attrs.type === 'input'
? attrs.text : attrs.type === 'link'
? attrs.href : attrs.id,
},
}
return result
}

lastRow() {
if (!this.rows.length) this.rows.push([])
let last = this.rows[this.rows.length - 1]
if (last.length >= 5) {
this.rows.push([])
last = this.rows[this.rows.length - 1]
}
return last
}

trimButtons() {
if (this.rows.length && this.rows[this.rows.length - 1].length === 0) this.rows.pop()
}

exportButtons() {
return this.rows.map(v => ({
buttons: v,
})) as QQ.InlineKeyboardRow[]
}

async visit(element: h) {
const { type, attrs, children } = element
if (type === 'text') {
Expand All @@ -239,22 +261,13 @@ export class QQMessageEncoder extends MessageEncoder<QQBot> {
await this.sendFile(type, attrs)
} else if (type === 'button-group') {
this.useMarkdown = true
this.buttonGroupState = true
this.rows.push({ buttons: [] })
this.rows.push([])
await this.render(children)
this.buttonGroupState = false
this.rows.push([])
} else if (type === 'button') {
this.useMarkdown = true
if (this.buttonGroupState) {
const last = this.rows[this.rows.length - 1]
last.buttons.push(this.decodeButton(attrs, children.join('')))
} else {
this.rows.push({
buttons: [
this.decodeButton(attrs, children.join('')),
],
})
}
const last = this.lastRow()
last.push(this.decodeButton(attrs, children.join('')))
} else if (type === 'message') {
await this.flush()
await this.render(children)
Expand Down
7 changes: 5 additions & 2 deletions adapters/qq/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,14 @@ export async function adaptSession(bot: QQBot, input: QQ.DispatchPayload) {
session.userId = input.d.data.resolved.user_id
if (input.d.chat_type === QQ.ChatType.GROUP) {
session.guildId = input.d.group_open_id
session.channelId = session.guildId
session.channelId = input.d.group_open_id
session.isDirect = false
} else if (input.d.chat_type === QQ.ChatType.CHANNEL) {
session.channelId = session.userId
session.channelId = input.d.channel_id
session.isDirect = false // ?
} else if (input.d.chat_type === QQ.ChatType.DIRECT) {
session.isDirect = true
session.channelId = session.userId
}
session.event.button = {
id: input.d.data.resolved.button_id,
Expand Down
41 changes: 25 additions & 16 deletions adapters/telegram/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export class TelegramMessageEncoder extends MessageEncoder<TelegramBot> {
private payload: Dict
private mode: RenderMode = 'default'
private rows: Telegram.InlineKeyboardButton[][] = []
private buttonGroupState = false

constructor(bot: TelegramBot, channelId: string, guildId?: string, options?: Universal.SendOptions) {
super(bot, channelId, guildId, options)
Expand Down Expand Up @@ -71,6 +70,7 @@ export class TelegramMessageEncoder extends MessageEncoder<TelegramBot> {
// send previous asset if there is any
await this.sendAsset()
} else if (this.payload.caption) {
this.trimButtons()
const result = await this.bot.internal.sendMessage({
chat_id: this.payload.chat_id,
text: this.payload.caption,
Expand All @@ -95,19 +95,33 @@ export class TelegramMessageEncoder extends MessageEncoder<TelegramBot> {
text: label,
url: attrs.href,
}
} else if (attrs.type === 'action') {
} else if (attrs.type === 'input') {
return {
text: label,
callback_data: attrs.id,
switch_inline_query_current_chat: attrs.text,
}
} else if (attrs.type === 'input') {
} else {
return {
text: label,
switch_inline_query_current_chat: attrs.text,
callback_data: attrs.id,
}
}
}

lastRow() {
if (!this.rows.length) this.rows.push([])
let last = this.rows[this.rows.length - 1]
if (last.length >= 5) {
this.rows.push([])
last = this.rows[this.rows.length - 1]
}
return last
}

trimButtons() {
if (this.rows.length && this.rows[this.rows.length - 1].length === 0) this.rows.pop()
}

async visit(element: h) {
const { type, attrs, children } = element
if (type === 'text') {
Expand Down Expand Up @@ -145,20 +159,15 @@ export class TelegramMessageEncoder extends MessageEncoder<TelegramBot> {
} else if (type === 'quote') {
await this.flush()
this.payload.reply_to_message_id = attrs.id
} else if (type === 'button' && attrs.type) {
if (this.buttonGroupState) {
const last = this.rows[this.rows.length - 1]
last.push(this.decodeButton(
attrs, children.join(''),
))
} else {
this.rows.push([this.decodeButton(attrs, children.join(''))])
}
} else if (type === 'button') {
const last = this.lastRow()
last.push(this.decodeButton(
attrs, children.join(''),
))
} else if (type === 'button-group') {
this.buttonGroupState = true
this.rows.push([])
await this.render(children)
this.buttonGroupState = false
this.rows.push([])
} else if (type === 'message') {
if (this.mode === 'figure') {
await this.render(children)
Expand Down

0 comments on commit f129772

Please sign in to comment.