telegram-badge 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🛡️ Telegram Group Badge Generator
2
2
 
3
- [🇷🇺 Русская версия](README.ru.md) | [🇺🇸 English](README.md)
3
+ [🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
4
4
 
5
5
  [![Build Status](https://github.com/chatman-media/telegram-badge/workflows/CI/badge.svg)](https://github.com/chatman-media/telegram-badge/actions)
6
6
  [![npm version](https://badge.fury.io/js/telegram-badge.svg)](https://badge.fury.io/js/telegram-badge)
@@ -197,10 +197,6 @@ Build the project:
197
197
  npm run build
198
198
  ```
199
199
 
200
- ## 📚 Documentation
201
-
202
- For detailed documentation in Russian, see [README.ru.md](README.ru.md).
203
-
204
200
  ## 🤝 Contributing
205
201
 
206
202
  1. Fork the repository
package/README.ru.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🛡️ Telegram Group Badge Generator
2
2
 
3
- [🇷🇺 Русская версия](README.ru.md) | [🇺🇸 English](README.md)
3
+ [🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
4
4
 
5
5
  [![Build Status](https://github.com/chatman-media/telegram-badge/workflows/CI/badge.svg)](https://github.com/chatman-media/telegram-badge/actions)
6
6
  [![npm version](https://badge.fury.io/js/telegram-badge.svg)](https://badge.fury.io/js/telegram-badge)
@@ -83,6 +83,7 @@ bun dev
83
83
  | `label` | Текст метки | `Telegram` |
84
84
  | `color` | Цвет основной части бейджа | `2AABEE` (цвет Telegram) |
85
85
  | `labelColor` | Цвет метки бейджа | `555555` |
86
+ | `logo` | Показывать логотип Telegram | `true` |
86
87
 
87
88
  #### Доступные стили:
88
89
 
@@ -136,6 +137,12 @@ https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=
136
137
  ```
137
138
  ![Full Custom](https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=Сообщество&color=FF5733&labelColor=1A1A1A)
138
139
 
140
+ Бейдж без логотипа:
141
+ ```
142
+ https://telegram-badge.vercel.app/api/telegram-badge?logo=false
143
+ ```
144
+ ![No Logo](https://telegram-badge.vercel.app/api/telegram-badge?logo=false)
145
+
139
146
  ## 🧠 Возможности
140
147
 
141
148
  - 👥 Отображение количества участников в реальном времени
package/README.zh.md ADDED
@@ -0,0 +1,214 @@
1
+ # 🛡️ Telegram 群组徽章生成器
2
+
3
+ [🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
4
+
5
+ [![构建状态](https://github.com/chatman-media/telegram-badge/workflows/CI/badge.svg)](https://github.com/chatman-media/telegram-badge/actions)
6
+ [![npm 版本](https://badge.fury.io/js/telegram-badge.svg)](https://badge.fury.io/js/telegram-badge)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.5-blue.svg)](https://www.typescriptlang.org/)
8
+ [![许可证: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ 本项目生成显示 Telegram 群组当前成员数量的 SVG 徽章。非常适合在 GitHub README 文件或网站上展示社区活跃度。
11
+
12
+ ## 🚀 演示
13
+
14
+ ![Telegram 群组成员](https://telegram-badge.vercel.app/api/telegram-badge)
15
+
16
+ ---
17
+
18
+ ## 📦 技术栈
19
+
20
+ - Node.js / TypeScript
21
+ - Telegram Bot API
22
+ - Vercel(无服务器 API)
23
+ - Jest 测试框架
24
+
25
+ ---
26
+
27
+ ## 🛠 安装
28
+
29
+ 1. 克隆仓库:
30
+
31
+ ```bash
32
+ git clone https://github.com/chatman-media/telegram-badge.git
33
+ cd telegram-badge
34
+ ```
35
+
36
+ 2. 安装依赖:
37
+
38
+ ```bash
39
+ npm install
40
+ # 或
41
+ bun install
42
+ ```
43
+
44
+ 3. 创建 .env 文件并添加:
45
+
46
+ ```bash
47
+ BOT_TOKEN=your_telegram_bot_token
48
+ CHAT_ID=@your_group_username_or_chat_id
49
+ ```
50
+
51
+ **注意:** 对于公开群组/频道,机器人无需添加为成员。对于私有群组,机器人必须是群组成员。
52
+
53
+ ## 🧪 本地开发
54
+
55
+ ```bash
56
+ npm run dev
57
+ # 或
58
+ bun dev
59
+ ```
60
+
61
+ 在浏览器中打开:http://localhost:3000/api/telegram-badge
62
+
63
+ ## ☁️ 部署到 Vercel
64
+
65
+ 1. 将仓库部署到 vercel.com
66
+ 2. 在项目设置中添加环境变量:
67
+ - BOT_TOKEN
68
+ - CHAT_ID
69
+
70
+ ## 🧩 在 GitHub README 中使用
71
+
72
+ 在您的 README.md 中添加以下代码:
73
+
74
+ ```markdown
75
+ ![Telegram 群组徽章](https://telegram-badge.vercel.app/api/telegram-badge)
76
+ ```
77
+
78
+ ### 🎨 样式参数
79
+
80
+ 您可以使用以下参数自定义徽章外观:
81
+
82
+ | 参数 | 描述 | 默认值 |
83
+ |------|------|--------|
84
+ | `style` | 徽章样式 | `flat` |
85
+ | `label` | 标签文本 | `Telegram` |
86
+ | `color` | 主徽章颜色 | `2AABEE`(Telegram 颜色) |
87
+ | `labelColor` | 标签颜色 | `555555` |
88
+ | `logo` | 显示 Telegram 标志 | `true` |
89
+
90
+ #### 可用样式:
91
+
92
+ - `flat` - 扁平样式(默认)
93
+ - `plastic` - 带渐变的立体样式
94
+ - `flat-square` - 无圆角的扁平样式
95
+ - `for-the-badge` - 带大写字母的宽样式
96
+ - `social` - GitHub 社交样式
97
+
98
+ #### 示例:
99
+
100
+ 标准徽章(扁平样式):
101
+ ```
102
+ https://telegram-badge.vercel.app/api/telegram-badge
103
+ ```
104
+ ![Flat](https://telegram-badge.vercel.app/api/telegram-badge)
105
+
106
+ 立体样式徽章:
107
+ ```
108
+ https://telegram-badge.vercel.app/api/telegram-badge?style=plastic
109
+ ```
110
+ ![Plastic](https://telegram-badge.vercel.app/api/telegram-badge?style=plastic)
111
+
112
+ 方形扁平样式徽章:
113
+ ```
114
+ https://telegram-badge.vercel.app/api/telegram-badge?style=flat-square
115
+ ```
116
+ ![Flat-Square](https://telegram-badge.vercel.app/api/telegram-badge?style=flat-square)
117
+
118
+ for-the-badge 样式徽章:
119
+ ```
120
+ https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge
121
+ ```
122
+ ![For-The-Badge](https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge)
123
+
124
+ 社交样式徽章:
125
+ ```
126
+ https://telegram-badge.vercel.app/api/telegram-badge?style=social
127
+ ```
128
+ ![Social](https://telegram-badge.vercel.app/api/telegram-badge?style=social)
129
+
130
+ 自定义标签和颜色的徽章:
131
+ ```
132
+ https://telegram-badge.vercel.app/api/telegram-badge?label=加入聊天&color=00FF00
133
+ ```
134
+ ![Custom](https://telegram-badge.vercel.app/api/telegram-badge?label=加入聊天&color=00FF00)
135
+
136
+ 完全自定义徽章:
137
+ ```
138
+ https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=社区&color=FF5733&labelColor=1A1A1A
139
+ ```
140
+ ![Full Custom](https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=社区&color=FF5733&labelColor=1A1A1A)
141
+
142
+ 无标志徽章:
143
+ ```
144
+ https://telegram-badge.vercel.app/api/telegram-badge?logo=false
145
+ ```
146
+ ![No Logo](https://telegram-badge.vercel.app/api/telegram-badge?logo=false)
147
+
148
+ ## ✨ 功能特性
149
+
150
+ - 👥 实时显示成员数量
151
+ - 🎨 完全自定义徽章外观
152
+ - 🔒 支持 .env 和 Vercel 环境变量以安全存储令牌
153
+ - ⚡ 优化缓存以实现快速加载
154
+ - 🛡️ 错误处理和信息提示
155
+ - 🆓 在 Vercel 上正常使用免费
156
+ - 📡 可扩展显示活动/消息计数
157
+ - 🧪 使用 TypeScript 的完整测试套件
158
+
159
+ ## 🔧 API 使用
160
+
161
+ ### 作为 npm 包:
162
+
163
+ ```bash
164
+ npm install telegram-badge
165
+ ```
166
+
167
+ ```typescript
168
+ import badgeHandler from 'telegram-badge';
169
+
170
+ // 在您的无服务器函数中使用
171
+ export default badgeHandler;
172
+ ```
173
+
174
+ ### 直接 API 调用:
175
+
176
+ ```typescript
177
+ GET /api/telegram-badge?style=flat&label=成员&color=2AABEE&labelColor=555555
178
+ ```
179
+
180
+ ## 🧪 测试
181
+
182
+ 运行测试套件:
183
+
184
+ ```bash
185
+ npm test
186
+ ```
187
+
188
+ 运行类型检查:
189
+
190
+ ```bash
191
+ npm run type-check
192
+ ```
193
+
194
+ 构建项目:
195
+
196
+ ```bash
197
+ npm run build
198
+ ```
199
+
200
+ ## 🤝 贡献
201
+
202
+ 1. Fork 本仓库
203
+ 2. 创建您的功能分支(`git checkout -b feature/amazing-feature`)
204
+ 3. 提交您的更改(`git commit -m 'Add some amazing feature'`)
205
+ 4. 推送到分支(`git push origin feature/amazing-feature`)
206
+ 5. 打开一个 Pull Request
207
+
208
+ ## 📜 许可证
209
+
210
+ 本项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
211
+
212
+ ---
213
+
214
+ 由 [Chatman Media](https://github.com/chatman-media) 用 ❤️ 制作
@@ -7,18 +7,17 @@ const TELEGRAM_LOGO = `<svg xmlns="http://www.w3.org/2000/svg" fill="white" view
7
7
  </svg>`;
8
8
  function generateBadgeSVG(format) {
9
9
  const { label, message, color, labelColor, style, logo } = format;
10
- // Calculate logo space
11
- const logoSpace = logo ? 20 : 0;
10
+ const logoSpace = logo ? 25 : 0;
12
11
  // Better text width calculation
13
- const labelWidth = label.length * 6.5 + 20 + logoSpace;
14
- const messageWidth = message.length * 6.5 + 20;
12
+ // Always add logoSpace to width calculation
13
+ const labelWidth = label.length * 6.5 + 10 + logoSpace;
14
+ const messageWidth = message.length * 6.5 + 10;
15
15
  const totalWidth = labelWidth + messageWidth;
16
16
  // Create logo element
17
17
  const logoElement = logo ? `<image x="5" y="3" width="14" height="14" href="data:image/svg+xml;base64,${Buffer.from(TELEGRAM_LOGO).toString('base64')}"/>` : '';
18
18
  // For-the-badge style
19
19
  if (style === 'for-the-badge') {
20
- const logoForBadge = logo ? `<image x="8" y="7" width="14" height="14" href="data:image/svg+xml;base64,${Buffer.from(TELEGRAM_LOGO).toString('base64')}"/>` : '';
21
- const textOffset = logo ? 10 : 0;
20
+ const logoForBadge = logo ? `<image x="5" y="7" width="14" height="14" href="data:image/svg+xml;base64,${Buffer.from(TELEGRAM_LOGO).toString('base64')}"/>` : '';
22
21
  return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${totalWidth}" height="28" role="img" aria-label="${label}: ${message}">
23
22
  <title>${label}: ${message}</title>
24
23
  <g shape-rendering="crispEdges">
@@ -27,8 +26,8 @@ function generateBadgeSVG(format) {
27
26
  </g>
28
27
  ${logoForBadge}
29
28
  <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="100">
30
- <text x="${(labelWidth / 2 + textOffset) * 10}" y="185" transform="scale(.1)" fill="#fff" textLength="${(labelWidth - 20 - logoSpace) * 10}">${label.toUpperCase()}</text>
31
- <text x="${(labelWidth + messageWidth / 2) * 10}" y="185" font-weight="bold" transform="scale(.1)" fill="#fff" textLength="${(messageWidth - 20) * 10}">${message.toUpperCase()}</text>
29
+ <text x="${(labelWidth / 2 + (logo ? 10 : 0)) * 10}" y="175" transform="scale(.1)" fill="#fff" textLength="${label.length * 65}">${label.toUpperCase()}</text>
30
+ <text x="${(labelWidth + messageWidth / 2) * 10}" y="175" font-weight="bold" transform="scale(.1)" fill="#fff" textLength="${message.length * 65}">${message.toUpperCase()}</text>
32
31
  </g>
33
32
  </svg>`;
34
33
  }
@@ -40,14 +39,16 @@ function generateBadgeSVG(format) {
40
39
  <rect width="${labelWidth}" height="20" fill="${labelColor}"/>
41
40
  <rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
42
41
  </g>
42
+ ${logoElement}
43
43
  <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
44
- <text x="${labelWidth / 2 * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(labelWidth - 10) * 10}">${label}</text>
45
- <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(messageWidth - 10) * 10}">${message}</text>
44
+ <text x="${(labelWidth / 2 + (logo ? 10 : 0)) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${label.length * 65}">${label}</text>
45
+ <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${message.length * 65}">${message}</text>
46
46
  </g>
47
47
  </svg>`;
48
48
  }
49
49
  // Social style
50
50
  if (style === 'social') {
51
+ const socialLogoElement = logo ? `<image x="7" y="3" width="14" height="14" href="data:image/svg+xml;base64,${Buffer.from(TELEGRAM_LOGO).toString('base64')}"/>` : '';
51
52
  return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${totalWidth + 4}" height="20" style="border-radius: 3px" role="img" aria-label="${label}: ${message}">
52
53
  <title>${label}: ${message}</title>
53
54
  <linearGradient id="s" x2="0" y2="100%">
@@ -62,9 +63,10 @@ function generateBadgeSVG(format) {
62
63
  <rect x="${labelWidth + 2}" width="${messageWidth + 2}" height="20" fill="${color}"/>
63
64
  <rect width="${totalWidth + 4}" height="20" fill="url(#s)"/>
64
65
  </g>
66
+ ${socialLogoElement}
65
67
  <g fill="#333" text-anchor="middle" font-family="Helvetica,Arial,sans-serif" font-weight="700" font-size="110">
66
- <text x="${(labelWidth / 2 + 1) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(labelWidth - 10) * 10}">${label}</text>
67
- <text x="${(labelWidth + messageWidth / 2 + 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(messageWidth - 10) * 10}">${message}</text>
68
+ <text x="${(labelWidth / 2 + 1 + (logo ? 10 : 0)) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${label.length * 65}">${label}</text>
69
+ <text x="${(labelWidth + messageWidth / 2 + 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${message.length * 65}">${message}</text>
68
70
  </g>
69
71
  </svg>`;
70
72
  }
@@ -86,14 +88,14 @@ function generateBadgeSVG(format) {
86
88
  <rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
87
89
  <rect width="${totalWidth}" height="20" fill="url(#s)"/>
88
90
  </g>
91
+ ${logoElement}
89
92
  <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
90
- <text x="${labelWidth / 2 * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(labelWidth - 10) * 10}">${label}</text>
91
- <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(messageWidth - 10) * 10}">${message}</text>
93
+ <text x="${(labelWidth / 2 + (logo ? 10 : 0)) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${label.length * 65}">${label}</text>
94
+ <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${message.length * 65}">${message}</text>
92
95
  </g>
93
96
  </svg>`;
94
97
  }
95
98
  // Default flat style
96
- const textOffset = logo ? 10 : 0;
97
99
  return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${message}">
98
100
  <title>${label}: ${message}</title>
99
101
  <linearGradient id="s" x2="0" y2="100%">
@@ -110,10 +112,10 @@ function generateBadgeSVG(format) {
110
112
  </g>
111
113
  ${logoElement}
112
114
  <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
113
- <text aria-hidden="true" x="${(labelWidth / 2 + textOffset) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${(labelWidth - 10 - logoSpace) * 10}">${label}</text>
114
- <text x="${(labelWidth / 2 + textOffset) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(labelWidth - 10 - logoSpace) * 10}">${label}</text>
115
- <text aria-hidden="true" x="${(labelWidth + messageWidth / 2) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${(messageWidth - 10) * 10}">${message}</text>
116
- <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${(messageWidth - 10) * 10}">${message}</text>
115
+ <text aria-hidden="true" x="${(labelWidth / 2 + (logo ? 10 : 0)) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${label.length * 65}">${label}</text>
116
+ <text x="${(labelWidth / 2 + (logo ? 10 : 0)) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${label.length * 65}">${label}</text>
117
+ <text aria-hidden="true" x="${(labelWidth + messageWidth / 2) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${message.length * 65}">${message}</text>
118
+ <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${message.length * 65}">${message}</text>
117
119
  </g>
118
120
  </svg>`;
119
121
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "telegram-badge",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Generate Telegram group member count badges for GitHub README",
5
5
  "keywords": [
6
6
  "telegram",