telegram-badge 1.0.0 → 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 +134 -54
- package/README.ru.md +160 -0
- package/README.zh.md +214 -0
- package/dist/api/badge-generator.d.ts +9 -0
- package/dist/api/badge-generator.js +121 -0
- package/dist/api/telegram-badge.d.ts +2 -2
- package/dist/api/telegram-badge.js +50 -15
- package/package.json +20 -14
package/README.md
CHANGED
|
@@ -1,134 +1,214 @@
|
|
|
1
1
|
# 🛡️ Telegram Group Badge Generator
|
|
2
2
|
|
|
3
|
+
[🇷🇺 Русский](README.ru.md) | [🇺🇸 English](README.md) | [🇨🇳 中文](README.zh.md)
|
|
4
|
+
|
|
3
5
|
[](https://github.com/chatman-media/telegram-badge/actions)
|
|
4
6
|
[](https://badge.fury.io/js/telegram-badge)
|
|
5
7
|
[](https://www.typescriptlang.org/)
|
|
6
8
|
[](https://opensource.org/licenses/MIT)
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
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.
|
|
9
11
|
|
|
10
|
-
## 🚀
|
|
12
|
+
## 🚀 Demo
|
|
11
13
|
|
|
12
14
|

|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
|
-
## 📦
|
|
18
|
+
## 📦 Tech Stack
|
|
17
19
|
|
|
18
|
-
- Node.js /
|
|
20
|
+
- Node.js / TypeScript
|
|
19
21
|
- Telegram Bot API
|
|
20
22
|
- Vercel (Serverless API)
|
|
23
|
+
- Jest for testing
|
|
21
24
|
|
|
22
25
|
---
|
|
23
26
|
|
|
24
|
-
## 🛠
|
|
27
|
+
## 🛠 Installation
|
|
25
28
|
|
|
26
|
-
1.
|
|
29
|
+
1. Clone the repository:
|
|
27
30
|
|
|
28
31
|
```bash
|
|
29
32
|
git clone https://github.com/chatman-media/telegram-badge.git
|
|
30
33
|
cd telegram-badge
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
2.
|
|
36
|
+
2. Install dependencies:
|
|
34
37
|
|
|
35
38
|
```bash
|
|
36
39
|
npm install
|
|
37
|
-
#
|
|
40
|
+
# or
|
|
38
41
|
bun install
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
3.
|
|
44
|
+
3. Create a .env file and add:
|
|
42
45
|
|
|
43
46
|
```bash
|
|
44
47
|
BOT_TOKEN=your_telegram_bot_token
|
|
45
48
|
CHAT_ID=@your_group_username_or_chat_id
|
|
46
49
|
```
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
**Note:** For public groups/channels, the bot doesn't need to be added as a member. For private groups, the bot must be added to the group.
|
|
49
52
|
|
|
50
|
-
## 🧪
|
|
53
|
+
## 🧪 Local Development
|
|
51
54
|
|
|
52
55
|
```bash
|
|
53
56
|
npm run dev
|
|
54
|
-
#
|
|
57
|
+
# or
|
|
55
58
|
bun dev
|
|
56
59
|
```
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
Open in browser: http://localhost:3000/api/telegram-badge
|
|
62
|
+
|
|
63
|
+
## ☁️ Deploy to Vercel
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
• CHAT_ID
|
|
65
|
+
1. Deploy the repository to vercel.com
|
|
66
|
+
2. Add environment variables in project settings:
|
|
67
|
+
- BOT_TOKEN
|
|
68
|
+
- CHAT_ID
|
|
65
69
|
|
|
66
|
-
## 🧩
|
|
70
|
+
## 🧩 Usage in GitHub README
|
|
67
71
|
|
|
68
|
-
|
|
72
|
+
Add the following line to your README.md:
|
|
69
73
|
|
|
70
74
|
```markdown
|
|
71
75
|

|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
### 🎨
|
|
78
|
+
### 🎨 Styling Parameters
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
You can customize the badge appearance using the following parameters:
|
|
77
81
|
|
|
78
|
-
|
|
|
79
|
-
|
|
80
|
-
| `style` |
|
|
81
|
-
| `label` |
|
|
82
|
-
| `color` |
|
|
83
|
-
| `labelColor` |
|
|
82
|
+
| Parameter | Description | Default Value |
|
|
83
|
+
|-----------|-------------|---------------|
|
|
84
|
+
| `style` | Badge style | `flat` |
|
|
85
|
+
| `label` | Label text | `Telegram` |
|
|
86
|
+
| `color` | Main badge color | `2AABEE` (Telegram color) |
|
|
87
|
+
| `labelColor` | Label color | `555555` |
|
|
88
|
+
| `logo` | Show Telegram logo | `true` |
|
|
84
89
|
|
|
85
|
-
####
|
|
90
|
+
#### Available styles:
|
|
86
91
|
|
|
87
|
-
- `flat` -
|
|
88
|
-
- `plastic` -
|
|
89
|
-
- `flat-square` -
|
|
90
|
-
- `for-the-badge` -
|
|
91
|
-
- `social` -
|
|
92
|
+
- `flat` - flat style (default)
|
|
93
|
+
- `plastic` - plastic style with gradient
|
|
94
|
+
- `flat-square` - flat square style without rounded corners
|
|
95
|
+
- `for-the-badge` - wide style with uppercase letters
|
|
96
|
+
- `social` - GitHub social style
|
|
92
97
|
|
|
93
|
-
####
|
|
98
|
+
#### Examples:
|
|
94
99
|
|
|
95
|
-
|
|
100
|
+
Standard badge (flat style):
|
|
96
101
|
```
|
|
97
102
|
https://telegram-badge.vercel.app/api/telegram-badge
|
|
98
103
|
```
|
|
104
|
+

|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
Badge with plastic style:
|
|
101
107
|
```
|
|
102
|
-
https://telegram-badge.vercel.app/api/telegram-badge?
|
|
108
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=plastic
|
|
103
109
|
```
|
|
110
|
+

|
|
104
111
|
|
|
105
|
-
|
|
112
|
+
Badge with flat-square style:
|
|
106
113
|
```
|
|
107
|
-
https://telegram-badge.vercel.app/api/telegram-badge?
|
|
114
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=flat-square
|
|
108
115
|
```
|
|
116
|
+

|
|
109
117
|
|
|
110
|
-
|
|
118
|
+
Badge with for-the-badge style:
|
|
111
119
|
```
|
|
112
120
|
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge
|
|
113
121
|
```
|
|
122
|
+

|
|
123
|
+
|
|
124
|
+
Badge with social style:
|
|
125
|
+
```
|
|
126
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=social
|
|
127
|
+
```
|
|
128
|
+

|
|
129
|
+
|
|
130
|
+
Badge with custom label and color:
|
|
131
|
+
```
|
|
132
|
+
https://telegram-badge.vercel.app/api/telegram-badge?label=Join%20Chat&color=00FF00
|
|
133
|
+
```
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
Fully customized badge:
|
|
137
|
+
```
|
|
138
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=Community&color=FF5733&labelColor=1A1A1A
|
|
139
|
+
```
|
|
140
|
+

|
|
114
141
|
|
|
115
|
-
|
|
142
|
+
Badge without logo:
|
|
143
|
+
```
|
|
144
|
+
https://telegram-badge.vercel.app/api/telegram-badge?logo=false
|
|
116
145
|
```
|
|
117
|
-
https://telegram-badge.vercel.app/api/telegram-badge?
|
|
146
|
+

|
|
147
|
+
|
|
148
|
+
## ✨ Features
|
|
149
|
+
|
|
150
|
+
- 👥 Real-time member count display
|
|
151
|
+
- 🎨 Full badge appearance customization
|
|
152
|
+
- 🔒 Support for .env and Vercel environment variables for secure token storage
|
|
153
|
+
- ⚡ Optimized caching for fast loading
|
|
154
|
+
- 🛡️ Error handling with informative messages
|
|
155
|
+
- 🆓 Free on Vercel with normal usage
|
|
156
|
+
- 📡 Can be extended to show activity/message count
|
|
157
|
+
- 🧪 Comprehensive test suite with TypeScript
|
|
158
|
+
|
|
159
|
+
## 🔧 API Usage
|
|
160
|
+
|
|
161
|
+
### As npm package:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npm install telegram-badge
|
|
118
165
|
```
|
|
119
166
|
|
|
120
|
-
|
|
167
|
+
```typescript
|
|
168
|
+
import badgeHandler from 'telegram-badge';
|
|
121
169
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
- ⚡ Оптимизированное кэширование для быстрой загрузки
|
|
126
|
-
- 🛡️ Обработка ошибок с информативными сообщениями
|
|
127
|
-
- 🆓 Бесплатно на Vercel при обычной нагрузке
|
|
128
|
-
- 📡 Можно расширить до отображения активности / количества сообщений
|
|
170
|
+
// Use in your serverless function
|
|
171
|
+
export default badgeHandler;
|
|
172
|
+
```
|
|
129
173
|
|
|
130
|
-
|
|
174
|
+
### Direct API calls:
|
|
131
175
|
|
|
132
|
-
|
|
176
|
+
```typescript
|
|
177
|
+
GET /api/telegram-badge?style=flat&label=Members&color=2AABEE&labelColor=555555
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 🧪 Testing
|
|
181
|
+
|
|
182
|
+
Run the test suite:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
npm test
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Run type checking:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npm run type-check
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Build the project:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm run build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 🤝 Contributing
|
|
201
|
+
|
|
202
|
+
1. Fork the repository
|
|
203
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
204
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
205
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
206
|
+
5. Open a Pull Request
|
|
207
|
+
|
|
208
|
+
## 📜 License
|
|
209
|
+
|
|
210
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
211
|
+
|
|
212
|
+
---
|
|
133
213
|
|
|
134
|
-
|
|
214
|
+
Made with ❤️ by [Chatman Media](https://github.com/chatman-media)
|
package/README.ru.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# 🛡️ Telegram Group Badge Generator
|
|
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
|
+
|
|
10
|
+
Этот проект генерирует SVG-бейдж с текущим количеством участников вашей Telegram-группы. Идеально подходит для отображения активности сообщества в README на GitHub или на сайте.
|
|
11
|
+
|
|
12
|
+
## 🚀 Демо
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 📦 Стек
|
|
19
|
+
|
|
20
|
+
- Node.js / Bun
|
|
21
|
+
- Telegram Bot API
|
|
22
|
+
- Vercel (Serverless API)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🛠 Установка
|
|
27
|
+
|
|
28
|
+
1. Клонируйте репозиторий:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone https://github.com/chatman-media/telegram-badge.git
|
|
32
|
+
cd telegram-badge
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
2. Установите зависимости:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install
|
|
39
|
+
# или
|
|
40
|
+
bun install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. Создайте .env файл и добавьте:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
BOT_TOKEN=your_telegram_bot_token
|
|
47
|
+
CHAT_ID=@your_group_username_or_chat_id
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Примечание:** Для публичных групп/каналов бота не нужно добавлять в группу. Для приватных групп бот должен быть участником.
|
|
51
|
+
|
|
52
|
+
## 🧪 Локальный запуск
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm run dev
|
|
56
|
+
# или
|
|
57
|
+
bun dev
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Открой в браузере: http://localhost:3000/api/telegram-badge
|
|
61
|
+
|
|
62
|
+
## ☁️ Деплой на Vercel
|
|
63
|
+
1. Задеплойте репозиторий на vercel.com
|
|
64
|
+
2. В настройках проекта добавьте переменные окружения:
|
|
65
|
+
• BOT_TOKEN
|
|
66
|
+
• CHAT_ID
|
|
67
|
+
|
|
68
|
+
## 🧩 Использование в GitHub README
|
|
69
|
+
|
|
70
|
+
Добавьте следующую строку в ваш README.md:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+

|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 🎨 Параметры стилизации
|
|
77
|
+
|
|
78
|
+
Вы можете настроить внешний вид бейджа с помощью следующих параметров:
|
|
79
|
+
|
|
80
|
+
| Параметр | Описание | Значение по умолчанию |
|
|
81
|
+
|----------|----------|------------------------|
|
|
82
|
+
| `style` | Стиль бейджа | `flat` |
|
|
83
|
+
| `label` | Текст метки | `Telegram` |
|
|
84
|
+
| `color` | Цвет основной части бейджа | `2AABEE` (цвет Telegram) |
|
|
85
|
+
| `labelColor` | Цвет метки бейджа | `555555` |
|
|
86
|
+
| `logo` | Показывать логотип Telegram | `true` |
|
|
87
|
+
|
|
88
|
+
#### Доступные стили:
|
|
89
|
+
|
|
90
|
+
- `flat` - плоский стиль (по умолчанию)
|
|
91
|
+
- `plastic` - объемный стиль с градиентом
|
|
92
|
+
- `flat-square` - плоский стиль без закруглений
|
|
93
|
+
- `for-the-badge` - широкий стиль с заглавными буквами
|
|
94
|
+
- `social` - стиль как у GitHub
|
|
95
|
+
|
|
96
|
+
#### Примеры:
|
|
97
|
+
|
|
98
|
+
Стандартный бейдж (стиль flat):
|
|
99
|
+
```
|
|
100
|
+
https://telegram-badge.vercel.app/api/telegram-badge
|
|
101
|
+
```
|
|
102
|
+

|
|
103
|
+
|
|
104
|
+
Бейдж со стилем plastic:
|
|
105
|
+
```
|
|
106
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=plastic
|
|
107
|
+
```
|
|
108
|
+

|
|
109
|
+
|
|
110
|
+
Бейдж со стилем flat-square:
|
|
111
|
+
```
|
|
112
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=flat-square
|
|
113
|
+
```
|
|
114
|
+

|
|
115
|
+
|
|
116
|
+
Бейдж со стилем for-the-badge:
|
|
117
|
+
```
|
|
118
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge
|
|
119
|
+
```
|
|
120
|
+

|
|
121
|
+
|
|
122
|
+
Бейдж со стилем social:
|
|
123
|
+
```
|
|
124
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=social
|
|
125
|
+
```
|
|
126
|
+

|
|
127
|
+
|
|
128
|
+
Бейдж с кастомной меткой и цветом:
|
|
129
|
+
```
|
|
130
|
+
https://telegram-badge.vercel.app/api/telegram-badge?label=Наш%20Чат&color=00FF00
|
|
131
|
+
```
|
|
132
|
+

|
|
133
|
+
|
|
134
|
+
Полностью кастомизированный бейдж:
|
|
135
|
+
```
|
|
136
|
+
https://telegram-badge.vercel.app/api/telegram-badge?style=for-the-badge&label=Сообщество&color=FF5733&labelColor=1A1A1A
|
|
137
|
+
```
|
|
138
|
+

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

|
|
145
|
+
|
|
146
|
+
## 🧠 Возможности
|
|
147
|
+
|
|
148
|
+
- 👥 Отображение количества участников в реальном времени
|
|
149
|
+
- 🎨 Полная кастомизация внешнего вида бейджа
|
|
150
|
+
- 🔒 Поддержка .env и переменных Vercel для безопасного хранения токенов
|
|
151
|
+
- ⚡ Оптимизированное кэширование для быстрой загрузки
|
|
152
|
+
- 🛡️ Обработка ошибок с информативными сообщениями
|
|
153
|
+
- 🆓 Бесплатно на Vercel при обычной нагрузке
|
|
154
|
+
- 📡 Можно расширить до отображения активности / количества сообщений
|
|
155
|
+
|
|
156
|
+
⸻
|
|
157
|
+
|
|
158
|
+
📜 Лицензия
|
|
159
|
+
|
|
160
|
+
MIT
|
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/actions)
|
|
6
|
+
[](https://badge.fury.io/js/telegram-badge)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
本项目生成显示 Telegram 群组当前成员数量的 SVG 徽章。非常适合在 GitHub README 文件或网站上展示社区活跃度。
|
|
11
|
+
|
|
12
|
+
## 🚀 演示
|
|
13
|
+
|
|
14
|
+

|
|
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
|
+

|
|
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
|
+

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

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

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

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

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

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

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

|
|
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) 用 ❤️ 制作
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBadgeSVG = generateBadgeSVG;
|
|
4
|
+
// Telegram logo as base64 encoded SVG
|
|
5
|
+
const TELEGRAM_LOGO = `<svg xmlns="http://www.w3.org/2000/svg" fill="white" viewBox="0 0 24 24" width="14" height="14">
|
|
6
|
+
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.894 8.221l-1.97 9.28c-.145.658-.537.818-1.084.508l-3-2.21-1.446 1.394c-.14.18-.357.295-.6.295-.002 0-.003 0-.005 0l.213-3.054 5.56-5.022c.24-.213-.054-.334-.373-.121l-6.869 4.326-2.96-.924c-.64-.203-.658-.64.135-.954l11.566-4.458c.538-.196 1.006.128.832.941z"/>
|
|
7
|
+
</svg>`;
|
|
8
|
+
function generateBadgeSVG(format) {
|
|
9
|
+
const { label, message, color, labelColor, style, logo } = format;
|
|
10
|
+
const logoSpace = logo ? 25 : 0;
|
|
11
|
+
// Better text width calculation
|
|
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
|
+
const totalWidth = labelWidth + messageWidth;
|
|
16
|
+
// Create logo element
|
|
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
|
+
// For-the-badge style
|
|
19
|
+
if (style === 'for-the-badge') {
|
|
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')}"/>` : '';
|
|
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}">
|
|
22
|
+
<title>${label}: ${message}</title>
|
|
23
|
+
<g shape-rendering="crispEdges">
|
|
24
|
+
<rect width="${labelWidth}" height="28" fill="${labelColor}"/>
|
|
25
|
+
<rect x="${labelWidth}" width="${messageWidth}" height="28" fill="${color}"/>
|
|
26
|
+
</g>
|
|
27
|
+
${logoForBadge}
|
|
28
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="100">
|
|
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>
|
|
31
|
+
</g>
|
|
32
|
+
</svg>`;
|
|
33
|
+
}
|
|
34
|
+
// Flat-square style
|
|
35
|
+
if (style === 'flat-square') {
|
|
36
|
+
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}">
|
|
37
|
+
<title>${label}: ${message}</title>
|
|
38
|
+
<g shape-rendering="crispEdges">
|
|
39
|
+
<rect width="${labelWidth}" height="20" fill="${labelColor}"/>
|
|
40
|
+
<rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
41
|
+
</g>
|
|
42
|
+
${logoElement}
|
|
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 + (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
|
+
</g>
|
|
47
|
+
</svg>`;
|
|
48
|
+
}
|
|
49
|
+
// Social style
|
|
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')}"/>` : '';
|
|
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}">
|
|
53
|
+
<title>${label}: ${message}</title>
|
|
54
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
55
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
56
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
57
|
+
</linearGradient>
|
|
58
|
+
<clipPath id="r">
|
|
59
|
+
<rect width="${totalWidth + 4}" height="20" rx="3" fill="#fff"/>
|
|
60
|
+
</clipPath>
|
|
61
|
+
<g clip-path="url(#r)">
|
|
62
|
+
<rect width="${labelWidth + 2}" height="20" fill="${labelColor}"/>
|
|
63
|
+
<rect x="${labelWidth + 2}" width="${messageWidth + 2}" height="20" fill="${color}"/>
|
|
64
|
+
<rect width="${totalWidth + 4}" height="20" fill="url(#s)"/>
|
|
65
|
+
</g>
|
|
66
|
+
${socialLogoElement}
|
|
67
|
+
<g fill="#333" text-anchor="middle" font-family="Helvetica,Arial,sans-serif" font-weight="700" font-size="110">
|
|
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>
|
|
70
|
+
</g>
|
|
71
|
+
</svg>`;
|
|
72
|
+
}
|
|
73
|
+
// Plastic style
|
|
74
|
+
if (style === 'plastic') {
|
|
75
|
+
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}">
|
|
76
|
+
<title>${label}: ${message}</title>
|
|
77
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
78
|
+
<stop offset="0" stop-color="#fff" stop-opacity=".7"/>
|
|
79
|
+
<stop offset=".1" stop-color="#aaa" stop-opacity=".1"/>
|
|
80
|
+
<stop offset=".9" stop-color="#000" stop-opacity=".3"/>
|
|
81
|
+
<stop offset="1" stop-color="#000" stop-opacity=".5"/>
|
|
82
|
+
</linearGradient>
|
|
83
|
+
<clipPath id="r">
|
|
84
|
+
<rect width="${totalWidth}" height="20" rx="4" fill="#fff"/>
|
|
85
|
+
</clipPath>
|
|
86
|
+
<g clip-path="url(#r)">
|
|
87
|
+
<rect width="${labelWidth}" height="20" fill="${labelColor}"/>
|
|
88
|
+
<rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
89
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
90
|
+
</g>
|
|
91
|
+
${logoElement}
|
|
92
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
|
|
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>
|
|
95
|
+
</g>
|
|
96
|
+
</svg>`;
|
|
97
|
+
}
|
|
98
|
+
// Default flat style
|
|
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}">
|
|
100
|
+
<title>${label}: ${message}</title>
|
|
101
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
102
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
103
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
104
|
+
</linearGradient>
|
|
105
|
+
<clipPath id="r">
|
|
106
|
+
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
107
|
+
</clipPath>
|
|
108
|
+
<g clip-path="url(#r)">
|
|
109
|
+
<rect width="${labelWidth}" height="20" fill="${labelColor}"/>
|
|
110
|
+
<rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
111
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
112
|
+
</g>
|
|
113
|
+
${logoElement}
|
|
114
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
|
|
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>
|
|
119
|
+
</g>
|
|
120
|
+
</svg>`;
|
|
121
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default function handler(req:
|
|
1
|
+
import { VercelRequest, VercelResponse } from '@vercel/node';
|
|
2
|
+
export default function handler(req: VercelRequest, res: VercelResponse): Promise<void>;
|
|
@@ -34,8 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.default = handler;
|
|
37
|
-
const badge_maker_1 = require("badge-maker");
|
|
38
37
|
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const badge_generator_1 = require("./badge-generator");
|
|
39
39
|
const logger = {
|
|
40
40
|
info: (message, data = {}) => {
|
|
41
41
|
console.log(`[INFO] ${message}`, data);
|
|
@@ -106,11 +106,12 @@ const validateStyleOptions = (options) => {
|
|
|
106
106
|
const label = options.label || 'Telegram';
|
|
107
107
|
const color = options.color || '2AABEE';
|
|
108
108
|
const labelColor = options.labelColor || '555555';
|
|
109
|
-
|
|
109
|
+
const logo = options.logo !== false; // Logo by default
|
|
110
|
+
return { style, label, color, labelColor, logo };
|
|
110
111
|
};
|
|
111
112
|
const createBadge = (members, options) => {
|
|
112
|
-
const { style, label, color, labelColor } = validateStyleOptions(options);
|
|
113
|
-
logger.debug('Creating badge', { style, label, color, labelColor });
|
|
113
|
+
const { style, label, color, labelColor, logo } = validateStyleOptions(options);
|
|
114
|
+
logger.debug('Creating badge', { style, label, color, labelColor, logo });
|
|
114
115
|
const normalizedColor = color.replace(/^#/, '');
|
|
115
116
|
const normalizedLabelColor = labelColor.replace(/^#/, '');
|
|
116
117
|
const format = {
|
|
@@ -118,9 +119,10 @@ const createBadge = (members, options) => {
|
|
|
118
119
|
message: `${members} members`,
|
|
119
120
|
color: `#${normalizedColor}`,
|
|
120
121
|
labelColor: `#${normalizedLabelColor}`,
|
|
121
|
-
style
|
|
122
|
+
style,
|
|
123
|
+
logo
|
|
122
124
|
};
|
|
123
|
-
return (0,
|
|
125
|
+
return (0, badge_generator_1.generateBadgeSVG)(format);
|
|
124
126
|
};
|
|
125
127
|
const createErrorBadge = (errorMessage) => {
|
|
126
128
|
const format = {
|
|
@@ -128,9 +130,10 @@ const createErrorBadge = (errorMessage) => {
|
|
|
128
130
|
message: errorMessage,
|
|
129
131
|
color: '#e05d44',
|
|
130
132
|
labelColor: '#555555',
|
|
131
|
-
style: 'flat'
|
|
133
|
+
style: 'flat',
|
|
134
|
+
logo: false
|
|
132
135
|
};
|
|
133
|
-
return (0,
|
|
136
|
+
return (0, badge_generator_1.generateBadgeSVG)(format);
|
|
134
137
|
};
|
|
135
138
|
const setCacheHeaders = (res, svg) => {
|
|
136
139
|
res.setHeader("Content-Type", "image/svg+xml");
|
|
@@ -146,12 +149,43 @@ const setCacheHeaders = (res, svg) => {
|
|
|
146
149
|
logger.debug('Cache headers set');
|
|
147
150
|
};
|
|
148
151
|
async function handler(req, res) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
// Global error handler
|
|
153
|
+
process.on('uncaughtException', (error) => {
|
|
154
|
+
console.error('[UNCAUGHT EXCEPTION]', error);
|
|
155
|
+
if (!res.headersSent) {
|
|
156
|
+
const errorBadge = createErrorBadge('Uncaught Error');
|
|
157
|
+
res.status(500).send(errorBadge);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
process.on('unhandledRejection', (reason) => {
|
|
161
|
+
console.error('[UNHANDLED REJECTION]', reason);
|
|
162
|
+
if (!res.headersSent) {
|
|
163
|
+
const errorBadge = createErrorBadge('Unhandled Rejection');
|
|
164
|
+
res.status(500).send(errorBadge);
|
|
165
|
+
}
|
|
153
166
|
});
|
|
154
167
|
try {
|
|
168
|
+
logger.info('Function started', {
|
|
169
|
+
query: req.query,
|
|
170
|
+
userAgent: req.headers['user-agent'],
|
|
171
|
+
referer: req.headers['referer'] || 'unknown',
|
|
172
|
+
env: {
|
|
173
|
+
hasToken: !!process.env.BOT_TOKEN,
|
|
174
|
+
hasChatId: !!process.env.CHAT_ID
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// Early check for environment variables
|
|
178
|
+
if (!process.env.BOT_TOKEN || !process.env.CHAT_ID) {
|
|
179
|
+
logger.error('Missing environment variables', {
|
|
180
|
+
BOT_TOKEN: !!process.env.BOT_TOKEN,
|
|
181
|
+
CHAT_ID: !!process.env.CHAT_ID
|
|
182
|
+
});
|
|
183
|
+
const errorBadge = createErrorBadge('Missing Config');
|
|
184
|
+
res.setHeader("Content-Type", "image/svg+xml");
|
|
185
|
+
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
186
|
+
res.status(500).send(errorBadge);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
155
189
|
const { token, chatId } = validateEnvironment();
|
|
156
190
|
logger.debug('Environment validated', { chatId });
|
|
157
191
|
const ifNoneMatch = req.headers['if-none-match'];
|
|
@@ -168,9 +202,10 @@ async function handler(req, res) {
|
|
|
168
202
|
logger.info('Member count fetched', { members });
|
|
169
203
|
const badgeOptions = {
|
|
170
204
|
style: req.query.style,
|
|
171
|
-
label: req.query.label,
|
|
172
|
-
color: req.query.color,
|
|
173
|
-
labelColor: req.query.labelColor
|
|
205
|
+
label: Array.isArray(req.query.label) ? req.query.label[0] : req.query.label,
|
|
206
|
+
color: Array.isArray(req.query.color) ? req.query.color[0] : req.query.color,
|
|
207
|
+
labelColor: Array.isArray(req.query.labelColor) ? req.query.labelColor[0] : req.query.labelColor,
|
|
208
|
+
logo: req.query.logo !== 'false' // Logo enabled by default, only disabled with logo=false
|
|
174
209
|
};
|
|
175
210
|
const svg = createBadge(members, badgeOptions);
|
|
176
211
|
logger.debug('Badge created');
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "telegram-badge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Generate Telegram group member count badges for GitHub README",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"telegram",
|
|
7
|
+
"badge",
|
|
8
|
+
"svg",
|
|
9
|
+
"group",
|
|
10
|
+
"members",
|
|
11
|
+
"api"
|
|
12
|
+
],
|
|
6
13
|
"author": "Chatman Media",
|
|
7
14
|
"license": "MIT",
|
|
8
15
|
"repository": {
|
|
@@ -23,25 +30,24 @@
|
|
|
23
30
|
"LICENSE"
|
|
24
31
|
],
|
|
25
32
|
"scripts": {
|
|
26
|
-
"dev": "vercel dev",
|
|
27
|
-
"start": "vercel dev",
|
|
33
|
+
"dev": "node -p \"console.log('Use: npx vercel dev')\"",
|
|
34
|
+
"start": "node -p \"console.log('Use: npx vercel dev')\"",
|
|
28
35
|
"test": "jest",
|
|
29
|
-
"build": "
|
|
36
|
+
"build": "echo 'Build handled by Vercel'",
|
|
37
|
+
"build:local": "tsc",
|
|
30
38
|
"type-check": "tsc --noEmit",
|
|
31
|
-
"prepublishOnly": "npm run build && npm test",
|
|
32
|
-
"prepack": "npm run build"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"badge-maker": "^5.0.2"
|
|
39
|
+
"prepublishOnly": "npm run build:local && npm test",
|
|
40
|
+
"prepack": "npm run build:local"
|
|
36
41
|
},
|
|
37
42
|
"devDependencies": {
|
|
38
|
-
"@types/jest": "^29.5.
|
|
43
|
+
"@types/jest": "^29.5.14",
|
|
39
44
|
"@types/node": "^24.0.15",
|
|
45
|
+
"@vercel/node": "^2.3.0",
|
|
40
46
|
"dotenv": "^17.2.0",
|
|
41
47
|
"jest": "^30.0.4",
|
|
42
48
|
"node-fetch": "^2.7.0",
|
|
43
|
-
"
|
|
44
|
-
"ts-
|
|
45
|
-
"
|
|
49
|
+
"ts-jest": "^29.4.0",
|
|
50
|
+
"ts-node": "^10.9.2",
|
|
51
|
+
"typescript": "^5.8.3"
|
|
46
52
|
}
|
|
47
53
|
}
|