telegram-badge 1.0.1 → 1.1.1
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 +3 -5
- package/README.ru.md +10 -1
- package/README.zh.md +216 -0
- package/dist/api/badge-generator.js +21 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# 🛡️ Telegram Group Badge Generator
|
|
2
2
|
|
|
3
|
-
[🇷🇺
|
|
3
|
+
[🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
|
|
4
4
|
|
|
5
5
|
[](https://github.com/chatman-media/telegram-badge/actions)
|
|
6
6
|
[](https://badge.fury.io/js/telegram-badge)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://dev.to/chatman-media/show-your-telegram-group-member-count-in-github-readme-46pl)
|
|
10
|
+
[](https://x.com/chatman_media/status/1947399700795244694)
|
|
9
11
|
|
|
10
12
|
This project generates SVG badges with the current member count of your Telegram group. Perfect for displaying community activity in GitHub README files or on websites.
|
|
11
13
|
|
|
@@ -197,10 +199,6 @@ Build the project:
|
|
|
197
199
|
npm run build
|
|
198
200
|
```
|
|
199
201
|
|
|
200
|
-
## 📚 Documentation
|
|
201
|
-
|
|
202
|
-
For detailed documentation in Russian, see [README.ru.md](README.ru.md).
|
|
203
|
-
|
|
204
202
|
## 🤝 Contributing
|
|
205
203
|
|
|
206
204
|
1. Fork the repository
|
package/README.ru.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# 🛡️ Telegram Group Badge Generator
|
|
2
2
|
|
|
3
|
-
[🇷🇺
|
|
3
|
+
[🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
|
|
4
4
|
|
|
5
5
|
[](https://github.com/chatman-media/telegram-badge/actions)
|
|
6
6
|
[](https://badge.fury.io/js/telegram-badge)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://dev.to/chatman-media/show-your-telegram-group-member-count-in-github-readme-46pl)
|
|
10
|
+
[](https://x.com/chatman_media/status/1947399700795244694)
|
|
9
11
|
|
|
10
12
|
Этот проект генерирует SVG-бейдж с текущим количеством участников вашей Telegram-группы. Идеально подходит для отображения активности сообщества в README на GitHub или на сайте.
|
|
11
13
|
|
|
@@ -83,6 +85,7 @@ bun dev
|
|
|
83
85
|
| `label` | Текст метки | `Telegram` |
|
|
84
86
|
| `color` | Цвет основной части бейджа | `2AABEE` (цвет Telegram) |
|
|
85
87
|
| `labelColor` | Цвет метки бейджа | `555555` |
|
|
88
|
+
| `logo` | Показывать логотип Telegram | `true` |
|
|
86
89
|
|
|
87
90
|
#### Доступные стили:
|
|
88
91
|
|
|
@@ -136,6 +139,12 @@ https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=
|
|
|
136
139
|
```
|
|
137
140
|

|
|
138
141
|
|
|
142
|
+
Бейдж без логотипа:
|
|
143
|
+
```
|
|
144
|
+
https://telegram-badge.vercel.app/api/telegram-badge?logo=false
|
|
145
|
+
```
|
|
146
|
+

|
|
147
|
+
|
|
139
148
|
## 🧠 Возможности
|
|
140
149
|
|
|
141
150
|
- 👥 Отображение количества участников в реальном времени
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# 🛡️ Telegram 群组徽章生成器
|
|
2
|
+
|
|
3
|
+
[🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
[](https://github.com/chatman-media/telegram-badge/actions)
|
|
6
|
+
[](https://badge.fury.io/js/telegram-badge)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://dev.to/chatman-media/show-your-telegram-group-member-count-in-github-readme-46pl)
|
|
10
|
+
[](https://x.com/chatman_media/status/1947399700795244694)
|
|
11
|
+
|
|
12
|
+
本项目生成显示 Telegram 群组当前成员数量的 SVG 徽章。非常适合在 GitHub README 文件或网站上展示社区活跃度。
|
|
13
|
+
|
|
14
|
+
## 🚀 演示
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 📦 技术栈
|
|
21
|
+
|
|
22
|
+
- Node.js / TypeScript
|
|
23
|
+
- Telegram Bot API
|
|
24
|
+
- Vercel(无服务器 API)
|
|
25
|
+
- Jest 测试框架
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🛠 安装
|
|
30
|
+
|
|
31
|
+
1. 克隆仓库:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/chatman-media/telegram-badge.git
|
|
35
|
+
cd telegram-badge
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. 安装依赖:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install
|
|
42
|
+
# 或
|
|
43
|
+
bun install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
3. 创建 .env 文件并添加:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
BOT_TOKEN=your_telegram_bot_token
|
|
50
|
+
CHAT_ID=@your_group_username_or_chat_id
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**注意:** 对于公开群组/频道,机器人无需添加为成员。对于私有群组,机器人必须是群组成员。
|
|
54
|
+
|
|
55
|
+
## 🧪 本地开发
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run dev
|
|
59
|
+
# 或
|
|
60
|
+
bun dev
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
在浏览器中打开:http://localhost:3000/api/telegram-badge
|
|
64
|
+
|
|
65
|
+
## ☁️ 部署到 Vercel
|
|
66
|
+
|
|
67
|
+
1. 将仓库部署到 vercel.com
|
|
68
|
+
2. 在项目设置中添加环境变量:
|
|
69
|
+
- BOT_TOKEN
|
|
70
|
+
- CHAT_ID
|
|
71
|
+
|
|
72
|
+
## 🧩 在 GitHub README 中使用
|
|
73
|
+
|
|
74
|
+
在您的 README.md 中添加以下代码:
|
|
75
|
+
|
|
76
|
+
```markdown
|
|
77
|
+

|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 🎨 样式参数
|
|
81
|
+
|
|
82
|
+
您可以使用以下参数自定义徽章外观:
|
|
83
|
+
|
|
84
|
+
| 参数 | 描述 | 默认值 |
|
|
85
|
+
|------|------|--------|
|
|
86
|
+
| `style` | 徽章样式 | `flat` |
|
|
87
|
+
| `label` | 标签文本 | `Telegram` |
|
|
88
|
+
| `color` | 主徽章颜色 | `2AABEE`(Telegram 颜色) |
|
|
89
|
+
| `labelColor` | 标签颜色 | `555555` |
|
|
90
|
+
| `logo` | 显示 Telegram 标志 | `true` |
|
|
91
|
+
|
|
92
|
+
#### 可用样式:
|
|
93
|
+
|
|
94
|
+
- `flat` - 扁平样式(默认)
|
|
95
|
+
- `plastic` - 带渐变的立体样式
|
|
96
|
+
- `flat-square` - 无圆角的扁平样式
|
|
97
|
+
- `for-the-badge` - 带大写字母的宽样式
|
|
98
|
+
- `social` - GitHub 社交样式
|
|
99
|
+
|
|
100
|
+
#### 示例:
|
|
101
|
+
|
|
102
|
+
标准徽章(扁平样式):
|
|
103
|
+
```
|
|
104
|
+
https://telegram-badge.vercel.app/api/telegram-badge
|
|
105
|
+
```
|
|
106
|
+

|
|
107
|
+
|
|
108
|
+
立体样式徽章:
|
|
109
|
+
```
|
|
110
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=plastic
|
|
111
|
+
```
|
|
112
|
+

|
|
113
|
+
|
|
114
|
+
方形扁平样式徽章:
|
|
115
|
+
```
|
|
116
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=flat-square
|
|
117
|
+
```
|
|
118
|
+

|
|
119
|
+
|
|
120
|
+
for-the-badge 样式徽章:
|
|
121
|
+
```
|
|
122
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge
|
|
123
|
+
```
|
|
124
|
+

|
|
125
|
+
|
|
126
|
+
社交样式徽章:
|
|
127
|
+
```
|
|
128
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=social
|
|
129
|
+
```
|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
自定义标签和颜色的徽章:
|
|
133
|
+
```
|
|
134
|
+
https://telegram-badge.vercel.app/api/telegram-badge?label=加入聊天&color=00FF00
|
|
135
|
+
```
|
|
136
|
+

|
|
137
|
+
|
|
138
|
+
完全自定义徽章:
|
|
139
|
+
```
|
|
140
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=社区&color=FF5733&labelColor=1A1A1A
|
|
141
|
+
```
|
|
142
|
+

|
|
143
|
+
|
|
144
|
+
无标志徽章:
|
|
145
|
+
```
|
|
146
|
+
https://telegram-badge.vercel.app/api/telegram-badge?logo=false
|
|
147
|
+
```
|
|
148
|
+

|
|
149
|
+
|
|
150
|
+
## ✨ 功能特性
|
|
151
|
+
|
|
152
|
+
- 👥 实时显示成员数量
|
|
153
|
+
- 🎨 完全自定义徽章外观
|
|
154
|
+
- 🔒 支持 .env 和 Vercel 环境变量以安全存储令牌
|
|
155
|
+
- ⚡ 优化缓存以实现快速加载
|
|
156
|
+
- 🛡️ 错误处理和信息提示
|
|
157
|
+
- 🆓 在 Vercel 上正常使用免费
|
|
158
|
+
- 📡 可扩展显示活动/消息计数
|
|
159
|
+
- 🧪 使用 TypeScript 的完整测试套件
|
|
160
|
+
|
|
161
|
+
## 🔧 API 使用
|
|
162
|
+
|
|
163
|
+
### 作为 npm 包:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm install telegram-badge
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import badgeHandler from 'telegram-badge';
|
|
171
|
+
|
|
172
|
+
// 在您的无服务器函数中使用
|
|
173
|
+
export default badgeHandler;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 直接 API 调用:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
GET /api/telegram-badge?style=flat&label=成员&color=2AABEE&labelColor=555555
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 🧪 测试
|
|
183
|
+
|
|
184
|
+
运行测试套件:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
npm test
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
运行类型检查:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npm run type-check
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
构建项目:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
npm run build
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🤝 贡献
|
|
203
|
+
|
|
204
|
+
1. Fork 本仓库
|
|
205
|
+
2. 创建您的功能分支(`git checkout -b feature/amazing-feature`)
|
|
206
|
+
3. 提交您的更改(`git commit -m 'Add some amazing feature'`)
|
|
207
|
+
4. 推送到分支(`git push origin feature/amazing-feature`)
|
|
208
|
+
5. 打开一个 Pull Request
|
|
209
|
+
|
|
210
|
+
## 📜 许可证
|
|
211
|
+
|
|
212
|
+
本项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
由 [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
|
-
|
|
11
|
-
const logoSpace = logo ? 20 : 0;
|
|
10
|
+
const logoSpace = logo ? 25 : 0;
|
|
12
11
|
// Better text width calculation
|
|
13
|
-
|
|
14
|
-
const
|
|
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="
|
|
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 +
|
|
31
|
-
<text x="${(labelWidth + messageWidth / 2) * 10}" y="
|
|
29
|
+
<text x="${(labelWidth / 2 + (logo ? 7 : 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="${
|
|
45
|
-
<text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${
|
|
44
|
+
<text x="${(labelWidth / 2 + (logo ? 7 : 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="${
|
|
67
|
-
<text x="${(labelWidth + messageWidth / 2 + 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${
|
|
68
|
+
<text x="${(labelWidth / 2 + 1 + (logo ? 7 : 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="${
|
|
91
|
-
<text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${
|
|
93
|
+
<text x="${(labelWidth / 2 + (logo ? 7 : 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 +
|
|
114
|
-
<text x="${(labelWidth / 2 +
|
|
115
|
-
<text aria-hidden="true" x="${(labelWidth + messageWidth / 2) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${
|
|
116
|
-
<text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff" textLength="${
|
|
115
|
+
<text aria-hidden="true" x="${(labelWidth / 2 + (logo ? 7 : 0)) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${label.length * 65}">${label}</text>
|
|
116
|
+
<text x="${(labelWidth / 2 + (logo ? 7 : 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
|
}
|