import type { GroupBaseInfo, TcPureContext } from 'tailchat-server-sdk'; import { TcService } from 'tailchat-server-sdk'; const badgeTemplate = (title: string, text: string) => { // 这个6.75计算的会不准、正确应该是5.5但是svg压缩时有误差 const titleWidth = calcWordWidth(title) * 6.75 + 10; const iconWidth = 20; const textWidth = calcWordWidth(text) * 6.75 + 20; const textOffset = 60; // Fork from https://shields.io/ return ` ${title}: ${text} ${title} ${text} `; }; /** * 邀请链接美化 */ class PrettyinviteService extends TcService { get serviceName() { return 'plugin:com.msgbyte.prettyinvite'; } onInit() { this.registerAction('badge', this.badge, { params: { inviteCode: 'string', }, }); this.registerAuthWhitelist(['/badge']); } async badge( ctx: TcPureContext<{ inviteCode: string; }> ) { const inviteCode = ctx.params.inviteCode; const inviteInfo: any = await ctx.call('group.invite.findInviteByCode', { code: inviteCode, }); if (!inviteInfo) { return { __raw: true, header: { 'content-type': 'image/svg+xml; charset=utf-8', }, html: badgeTemplate('Not Found', 'NaN'), }; } const groupId = inviteInfo.groupId; const group: GroupBaseInfo = await ctx.call('group.getGroupBasicInfo', { groupId: String(groupId), }); return { __raw: true, header: { 'content-type': 'image/svg+xml; charset=utf-8', }, html: badgeTemplate(group.name, String(group.memberCount)), }; } } export default PrettyinviteService; /** * 计算文本占据宽度 * 单位为字符宽度 */ function calcWordWidth(text: string): number { return text .split('') .map((char) => (char.charCodeAt(0) < 255 ? 1 : 2)) // 判断是否为ascii码 .reduce((prev, curr) => prev + curr, 0); }