-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8dbb244
commit 27cf462
Showing
7 changed files
with
193 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { readFile } from 'fs/promises' | ||
import { getLogger } from 'log4js' | ||
import { registerFont } from 'ultimate-text-to-image' | ||
|
||
export let defaultAvatar: Buffer | ||
export let mask: Buffer | ||
|
||
export const loadAssets = async (): Promise<void> => { | ||
// 获取 logger | ||
const logger = getLogger() | ||
// 读取默认的头像文件 | ||
defaultAvatar = await readFile('./src/assets/default_profile.png') | ||
logger.debug('读取到了默认的头像文件') | ||
// 读取遮罩文件 | ||
mask = await readFile('./src/assets/gradient-mask.png') | ||
logger.debug('读取到了遮罩文件') | ||
// 读取字体文件 | ||
registerFont('./src/assets/Alibaba-PuHuiTi-Regular.ttf', { | ||
family: 'AliBabaPuHui' | ||
}) | ||
logger.debug('已注册字体文件') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { InputFile } from 'grammy' | ||
import { getLogger } from 'log4js' | ||
import { defaultAvatar, mask } from './assets' | ||
import { token } from './config' | ||
import { Commnad, MyHandler } from './types' | ||
import { getArgsFromMessageText, jimpToInputFile, makeItAQuote } from './utils' | ||
|
||
const logger = getLogger() | ||
|
||
// 处理 quote 命令 | ||
const handleQuoteCommand: MyHandler = async (ctx) => { | ||
const msg = ctx.message! | ||
const { message_id: messageId } = msg | ||
const { id: chatId } = ctx.chat | ||
// 进行一些错误的判断 | ||
const replyMsg = ctx.message?.reply_to_message | ||
if (typeof replyMsg === 'undefined') { | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 没有获取到被回复的消息`) | ||
await ctx.reply('你并没有回复任何人哦', { | ||
reply_to_message_id: ctx.message?.message_id | ||
}) | ||
return | ||
} | ||
const sender = replyMsg.from | ||
if (typeof sender === 'undefined') { | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 没有获取到被回复者`) | ||
await ctx.reply('你回复的这条消息可能来自一个频道,获取不到作者呢', { | ||
reply_to_message_id: ctx.message?.message_id | ||
}) | ||
return | ||
} | ||
if (typeof replyMsg.text === 'undefined') { | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 没有获取到被回复消息的内容`) | ||
await ctx.reply('你回复的这条消息没有内容呢', { | ||
reply_to_message_id: ctx.message?.message_id | ||
}) | ||
return | ||
} | ||
const { message_id: replyId } = await ctx.reply('正在进行处理,请稍等...') | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 已成功发送“处理中”提示信息`) | ||
// 进行参数处理 | ||
const args = getArgsFromMessageText(msg.text) | ||
// 被回复者 id | ||
const username = sender.username ?? 'no_name' | ||
// 被回复的消息内容 | ||
const text = replyMsg.text | ||
// 被回复者的头像,这里取第一个 | ||
const avatar = (await ctx.api.getUserProfilePhotos(sender.id)).photos | ||
let quoted: InputFile | undefined | ||
if (avatar.length === 0) { | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 被回复的消息作者是没有头像的`) | ||
// 如果没有头像,使用默认头像进行图片的合成 | ||
const res = await makeItAQuote(defaultAvatar, mask, username, text, args) | ||
quoted = await jimpToInputFile(res) | ||
} else { | ||
// 有头像,使用头像组中的第一个进行图片的合成 | ||
const photo = avatar[0][0] | ||
// 尝试获取此文件 | ||
const file = await ctx.api.getFile(photo.file_id) | ||
if (typeof file.file_path === 'undefined') { | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 被回复的消息作者头像文件获取到了,但是没有路径`) | ||
return | ||
} | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 被回复的消息作者头像在 https://api.telegram.org/file/bot${token}/${file.file_path}`) | ||
const res = await makeItAQuote(`https://api.telegram.org/file/bot${token}/${file.file_path}`, mask, username, text, args) | ||
quoted = await jimpToInputFile(res) | ||
} | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 图片处理完成`) | ||
await ctx.replyWithPhoto(quoted, { | ||
reply_to_message_id: messageId | ||
}) | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 图片发送完成`) | ||
await ctx.api.deleteMessage(chatId, replyId) | ||
logger.debug(`[chat: ${chatId}, command: quote, msg: ${messageId}] 提示信息删除完成`) | ||
} | ||
|
||
// 导出命令集 | ||
export const commands: Commnad[] = [ | ||
new Commnad('quote', handleQuoteCommand) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Bot, Middleware } from 'grammy' | ||
import { getLogger } from 'log4js' | ||
|
||
/** | ||
* 命令参数 | ||
* 从消息中获取 | ||
*/ | ||
export interface ArgsFromMsg { | ||
quoteMarkLeft: string // 自定义引号字符,左侧 | ||
quoteMarkRight: string // 自定义引号字符,右侧 | ||
gray: boolean // 是否把头像处理成灰色 | ||
} | ||
|
||
// 获取 Bot 的 command 方法类型 | ||
type GetCommandFn = Bot['command'] | ||
export type BotCommandHandler = GetCommandFn extends (f: any, r: infer Rest) => any ? Rest : never | ||
export type CommandCtx = BotCommandHandler extends Middleware<infer Ctx> ? Ctx : never | ||
export type MyHandler = (ctx: CommandCtx) => Promise<void> | ||
|
||
/** | ||
* 命令 | ||
*/ | ||
export class Commnad { | ||
name: string // 命令名称 | ||
fn: MyHandler // 命令处理函数 | ||
|
||
constructor (name: string, fn: MyHandler) { | ||
this.name = name | ||
this.fn = fn | ||
} | ||
|
||
// 让 Bot 使用此命令 | ||
use = (bot: Bot): void => { | ||
bot.command(this.name, async (ctx) => { | ||
const logger = getLogger() | ||
try { | ||
const msg = ctx.message | ||
if (typeof msg === 'undefined') { | ||
logger.info(`收到 ${this.name} 命令,但获取不到消息内容,对话 ID: ${ctx.chat.id}`) | ||
return | ||
} | ||
logger.info(`收到 ${this.name} 命令,对话 ID: ${ctx.chat.id},消息 ID: ${msg.message_id}`) | ||
// 尝试执行命令处理器 | ||
await this.fn(ctx) | ||
} catch (e) { | ||
logger.error(`[${this.name} 命令,对话 ID: ${ctx.chat.id}] 处理出错:`, e) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters