feishu-cc 0.1.0__tar.gz
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.
- feishu_cc-0.1.0/PKG-INFO +323 -0
- feishu_cc-0.1.0/README.md +290 -0
- feishu_cc-0.1.0/pyproject.toml +75 -0
- feishu_cc-0.1.0/setup.cfg +4 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/PKG-INFO +323 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/SOURCES.txt +16 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/dependency_links.txt +1 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/entry_points.txt +3 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/requires.txt +7 -0
- feishu_cc-0.1.0/src/feishu_cc.egg-info/top_level.txt +1 -0
- feishu_cc-0.1.0/src/feishu_notify/__init__.py +38 -0
- feishu_cc-0.1.0/src/feishu_notify/cli.py +199 -0
- feishu_cc-0.1.0/src/feishu_notify/config.py +193 -0
- feishu_cc-0.1.0/src/feishu_notify/i18n.py +206 -0
- feishu_cc-0.1.0/src/feishu_notify/py.typed +1 -0
- feishu_cc-0.1.0/src/feishu_notify/sender.py +151 -0
- feishu_cc-0.1.0/tests/test_config.py +111 -0
- feishu_cc-0.1.0/tests/test_sender.py +125 -0
feishu_cc-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feishu-cc
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Feishu (Lark) bot messaging and remote control for Claude Code and terminals
|
|
5
|
+
Author-email: Step Tian <step@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/steptian/feishu-notify
|
|
8
|
+
Project-URL: Documentation, https://github.com/steptian/feishu-notify#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/steptian/feishu-notify.git
|
|
10
|
+
Project-URL: Issues, https://github.com/steptian/feishu-notify/issues
|
|
11
|
+
Keywords: feishu,lark,claude-code,notification,remote-control,bot
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Communications :: Chat
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Terminals
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
Requires-Dist: lark-oapi>=1.4.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
31
|
+
Requires-Dist: sphinx>=7.0; extra == "dev"
|
|
32
|
+
Requires-Dist: sphinx-rtd-theme>=2.0; extra == "dev"
|
|
33
|
+
|
|
34
|
+
# feishu-notify
|
|
35
|
+
|
|
36
|
+
[](https://badge.fury.io/py/feishu-notify)
|
|
37
|
+
[](https://pypi.org/project/feishu-notify/)
|
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
|
39
|
+
|
|
40
|
+
飞书 (Lark) 机器人消息推送与远程控制。支持从飞书远程操控 Claude Code 或其他终端。
|
|
41
|
+
|
|
42
|
+
**English** | [中文](#中文文档)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- 🔔 **Instant Push** - Auto-notify on task completion
|
|
49
|
+
- 🎮 **Remote Control** - Send commands from Feishu to terminal
|
|
50
|
+
- 🪟 **Multi-window** - On-duty mode for window management
|
|
51
|
+
- 📱 **Mobile Friendly** - Optimized output for mobile reading
|
|
52
|
+
- 🎴 **Interactive Cards** - Window list with card display
|
|
53
|
+
- 🌐 **i18n** - Chinese and English support
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# From PyPI (recommended)
|
|
59
|
+
pip install feishu-notify
|
|
60
|
+
|
|
61
|
+
# From source
|
|
62
|
+
git clone https://github.com/steptian/feishu-notify.git
|
|
63
|
+
cd feishu-notify
|
|
64
|
+
pip install -e .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### 1. Configure Feishu App
|
|
70
|
+
|
|
71
|
+
1. Visit [Feishu Open Platform](https://open.feishu.cn/app) to create an app
|
|
72
|
+
2. Get **App ID** and **App Secret**
|
|
73
|
+
3. Configure permissions: `im:message`, `im:message:send_as_bot`
|
|
74
|
+
4. Publish the app and add to a group chat
|
|
75
|
+
|
|
76
|
+
### 2. Set Environment Variables
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Create config directory
|
|
80
|
+
mkdir -p ~/.config/feishu-notify
|
|
81
|
+
|
|
82
|
+
# Create .env file
|
|
83
|
+
cat > ~/.config/feishu-notify/.env << 'EOF'
|
|
84
|
+
FEISHU_APP_ID=cli_xxxxxxxxxx
|
|
85
|
+
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxx
|
|
86
|
+
EOF
|
|
87
|
+
|
|
88
|
+
chmod 600 ~/.config/feishu-notify/.env
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Start Long Polling Client
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
feishu-notify start
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Or run directly:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
python -m feishu_notify.client
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 4. Configure Claude Code Hook (Optional but Recommended)
|
|
104
|
+
|
|
105
|
+
Edit `~/.claude/settings.json`:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"hooks": {
|
|
110
|
+
"Stop": [
|
|
111
|
+
{
|
|
112
|
+
"matcher": "",
|
|
113
|
+
"hooks": [
|
|
114
|
+
{
|
|
115
|
+
"type": "command",
|
|
116
|
+
"command": "feishu-notify hook"
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Usage
|
|
126
|
+
|
|
127
|
+
### From Feishu
|
|
128
|
+
|
|
129
|
+
Send messages directly (no prefix needed):
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
帮我写一个冒泡排序
|
|
133
|
+
今天上海天气怎么样?
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Window management:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
/windows # View active windows (interactive card)
|
|
140
|
+
/switch 1 # Switch to window 1
|
|
141
|
+
/on-duty # View current on-duty window
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### In Claude Code
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
feishu-notify send "Title" "Content" # Send custom notification
|
|
148
|
+
feishu-notify send "Task done" # Send simple notification
|
|
149
|
+
feishu-notify test # Test push
|
|
150
|
+
feishu-notify config --check # Validate configuration
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Command Line
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
feishu-notify send "Title" "Content" # Send notification
|
|
157
|
+
feishu-notify test # Test
|
|
158
|
+
feishu-notify config --check # Check config
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### As a Python Library
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from feishu_notify import send_to_feishu, Config
|
|
165
|
+
|
|
166
|
+
# Load config from environment
|
|
167
|
+
config = Config.from_env()
|
|
168
|
+
config.validate()
|
|
169
|
+
|
|
170
|
+
# Send message
|
|
171
|
+
send_to_feishu("Hello from Python!", config=config)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Architecture
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
┌─────────────┐ ┌─────────────┐
|
|
178
|
+
│ Feishu App │◄────WebSocket────►│ Client │
|
|
179
|
+
└─────────────┘ └──────┬──────┘
|
|
180
|
+
│
|
|
181
|
+
▼
|
|
182
|
+
┌─────────────┐
|
|
183
|
+
│ tmux session│
|
|
184
|
+
│(Claude Code)│
|
|
185
|
+
└─────────────┘
|
|
186
|
+
▲
|
|
187
|
+
│
|
|
188
|
+
┌──────┴──────┐
|
|
189
|
+
│ Stop Hook │
|
|
190
|
+
│ (auto-reply)│
|
|
191
|
+
└─────────────┘
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## File Structure
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
feishu-notify/
|
|
198
|
+
├── src/feishu_notify/
|
|
199
|
+
│ ├── __init__.py
|
|
200
|
+
│ ├── cli.py # CLI entry point
|
|
201
|
+
│ ├── client.py # WebSocket client
|
|
202
|
+
│ ├── config.py # Configuration management
|
|
203
|
+
│ ├── sender.py # Message sending
|
|
204
|
+
│ └── i18n.py # Internationalization
|
|
205
|
+
├── tests/
|
|
206
|
+
│ ├── test_config.py
|
|
207
|
+
│ └── test_sender.py
|
|
208
|
+
├── skills/ # Claude Code Skill
|
|
209
|
+
│ └── feishu-notify/
|
|
210
|
+
│ └── SKILL.md
|
|
211
|
+
├── pyproject.toml
|
|
212
|
+
└── README.md
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Configuration
|
|
216
|
+
|
|
217
|
+
### Environment Variables
|
|
218
|
+
|
|
219
|
+
| Variable | Required | Description |
|
|
220
|
+
|----------|----------|-------------|
|
|
221
|
+
| `FEISHU_APP_ID` | ✅ | Feishu App ID |
|
|
222
|
+
| `FEISHU_APP_SECRET` | ✅ | Feishu App Secret |
|
|
223
|
+
| `FEISHU_WEBHOOK_URL` | ❌ | Group bot webhook (for simple push) |
|
|
224
|
+
| `FEISHU_NOTIFY_LANG` | ❌ | Language: `zh` (default) or `en` |
|
|
225
|
+
|
|
226
|
+
### Multi-window Scenario
|
|
227
|
+
|
|
228
|
+
When you have multiple Claude Code windows, use **on-duty mode**:
|
|
229
|
+
|
|
230
|
+
1. In Claude Code terminal: `feishu-notify on-duty`
|
|
231
|
+
2. Messages from Feishu will only go to the on-duty window
|
|
232
|
+
3. Switch windows: Send `/windows` in Feishu → Click to switch
|
|
233
|
+
|
|
234
|
+
## Troubleshooting
|
|
235
|
+
|
|
236
|
+
### Message Send Failed
|
|
237
|
+
|
|
238
|
+
1. Check `.env` configuration is correct
|
|
239
|
+
2. Check if Feishu app is published
|
|
240
|
+
3. Check if app is added to group chat
|
|
241
|
+
|
|
242
|
+
### Reply Not Sent to Feishu
|
|
243
|
+
|
|
244
|
+
1. Confirm Stop Hook is configured
|
|
245
|
+
2. Confirm long polling client is running
|
|
246
|
+
3. Check logs: `tail -f /tmp/feishu-longpoll.log`
|
|
247
|
+
|
|
248
|
+
## Development
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Install dev dependencies
|
|
252
|
+
pip install -e ".[dev]"
|
|
253
|
+
|
|
254
|
+
# Run tests
|
|
255
|
+
pytest
|
|
256
|
+
|
|
257
|
+
# Run tests with coverage
|
|
258
|
+
pytest --cov=feishu_notify
|
|
259
|
+
|
|
260
|
+
# Type check
|
|
261
|
+
pyright src/
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 中文文档
|
|
271
|
+
|
|
272
|
+
飞书机器人消息推送与远程控制 Skill,支持从飞书远程操控 Claude Code。
|
|
273
|
+
|
|
274
|
+
### 特性
|
|
275
|
+
|
|
276
|
+
- 🔔 **即时推送** - 任务完成自动通知到飞书
|
|
277
|
+
- 🎮 **远程控制** - 从飞书发送命令到 Claude Code
|
|
278
|
+
- 🪟 **多窗口管理** - 值班模式,指定窗口接收消息
|
|
279
|
+
- 📱 **手机友好** - 输出优化,适合手机阅读
|
|
280
|
+
- 🎴 **交互卡片** - 窗口列表卡片展示
|
|
281
|
+
|
|
282
|
+
### 安装
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
pip install feishu-notify
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 快速开始
|
|
289
|
+
|
|
290
|
+
1. 配置飞书应用并获取 App ID 和 App Secret
|
|
291
|
+
2. 创建 `~/.config/feishu-notify/.env` 文件
|
|
292
|
+
3. 运行 `feishu-notify start` 启动长连接客户端
|
|
293
|
+
|
|
294
|
+
### 使用方式
|
|
295
|
+
|
|
296
|
+
从飞书发消息(无需前缀):
|
|
297
|
+
```
|
|
298
|
+
帮我写一个冒泡排序
|
|
299
|
+
今天上海天气怎么样?
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
窗口管理:
|
|
303
|
+
```
|
|
304
|
+
/windows # 查看活跃窗口
|
|
305
|
+
/switch 1 # 切换到窗口 1
|
|
306
|
+
/on-duty # 查看当前值班窗口
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### 故障排除
|
|
310
|
+
|
|
311
|
+
**消息发送失败**
|
|
312
|
+
1. 检查 `.env` 配置是否正确
|
|
313
|
+
2. 检查飞书应用是否已发布
|
|
314
|
+
3. 检查应用是否已添加到群聊
|
|
315
|
+
|
|
316
|
+
**回复没有发送到飞书**
|
|
317
|
+
1. 确认 Stop Hook 已配置
|
|
318
|
+
2. 确认长连接客户端正在运行
|
|
319
|
+
3. 检查日志:`tail -f /tmp/feishu-longpoll.log`
|
|
320
|
+
|
|
321
|
+
### 许可证
|
|
322
|
+
|
|
323
|
+
MIT
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# feishu-notify
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/feishu-notify)
|
|
4
|
+
[](https://pypi.org/project/feishu-notify/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
飞书 (Lark) 机器人消息推送与远程控制。支持从飞书远程操控 Claude Code 或其他终端。
|
|
8
|
+
|
|
9
|
+
**English** | [中文](#中文文档)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- 🔔 **Instant Push** - Auto-notify on task completion
|
|
16
|
+
- 🎮 **Remote Control** - Send commands from Feishu to terminal
|
|
17
|
+
- 🪟 **Multi-window** - On-duty mode for window management
|
|
18
|
+
- 📱 **Mobile Friendly** - Optimized output for mobile reading
|
|
19
|
+
- 🎴 **Interactive Cards** - Window list with card display
|
|
20
|
+
- 🌐 **i18n** - Chinese and English support
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# From PyPI (recommended)
|
|
26
|
+
pip install feishu-notify
|
|
27
|
+
|
|
28
|
+
# From source
|
|
29
|
+
git clone https://github.com/steptian/feishu-notify.git
|
|
30
|
+
cd feishu-notify
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Configure Feishu App
|
|
37
|
+
|
|
38
|
+
1. Visit [Feishu Open Platform](https://open.feishu.cn/app) to create an app
|
|
39
|
+
2. Get **App ID** and **App Secret**
|
|
40
|
+
3. Configure permissions: `im:message`, `im:message:send_as_bot`
|
|
41
|
+
4. Publish the app and add to a group chat
|
|
42
|
+
|
|
43
|
+
### 2. Set Environment Variables
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Create config directory
|
|
47
|
+
mkdir -p ~/.config/feishu-notify
|
|
48
|
+
|
|
49
|
+
# Create .env file
|
|
50
|
+
cat > ~/.config/feishu-notify/.env << 'EOF'
|
|
51
|
+
FEISHU_APP_ID=cli_xxxxxxxxxx
|
|
52
|
+
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxx
|
|
53
|
+
EOF
|
|
54
|
+
|
|
55
|
+
chmod 600 ~/.config/feishu-notify/.env
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Start Long Polling Client
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
feishu-notify start
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or run directly:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python -m feishu_notify.client
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Configure Claude Code Hook (Optional but Recommended)
|
|
71
|
+
|
|
72
|
+
Edit `~/.claude/settings.json`:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"hooks": {
|
|
77
|
+
"Stop": [
|
|
78
|
+
{
|
|
79
|
+
"matcher": "",
|
|
80
|
+
"hooks": [
|
|
81
|
+
{
|
|
82
|
+
"type": "command",
|
|
83
|
+
"command": "feishu-notify hook"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
### From Feishu
|
|
95
|
+
|
|
96
|
+
Send messages directly (no prefix needed):
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
帮我写一个冒泡排序
|
|
100
|
+
今天上海天气怎么样?
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Window management:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
/windows # View active windows (interactive card)
|
|
107
|
+
/switch 1 # Switch to window 1
|
|
108
|
+
/on-duty # View current on-duty window
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### In Claude Code
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
feishu-notify send "Title" "Content" # Send custom notification
|
|
115
|
+
feishu-notify send "Task done" # Send simple notification
|
|
116
|
+
feishu-notify test # Test push
|
|
117
|
+
feishu-notify config --check # Validate configuration
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Command Line
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
feishu-notify send "Title" "Content" # Send notification
|
|
124
|
+
feishu-notify test # Test
|
|
125
|
+
feishu-notify config --check # Check config
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### As a Python Library
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from feishu_notify import send_to_feishu, Config
|
|
132
|
+
|
|
133
|
+
# Load config from environment
|
|
134
|
+
config = Config.from_env()
|
|
135
|
+
config.validate()
|
|
136
|
+
|
|
137
|
+
# Send message
|
|
138
|
+
send_to_feishu("Hello from Python!", config=config)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Architecture
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
┌─────────────┐ ┌─────────────┐
|
|
145
|
+
│ Feishu App │◄────WebSocket────►│ Client │
|
|
146
|
+
└─────────────┘ └──────┬──────┘
|
|
147
|
+
│
|
|
148
|
+
▼
|
|
149
|
+
┌─────────────┐
|
|
150
|
+
│ tmux session│
|
|
151
|
+
│(Claude Code)│
|
|
152
|
+
└─────────────┘
|
|
153
|
+
▲
|
|
154
|
+
│
|
|
155
|
+
┌──────┴──────┐
|
|
156
|
+
│ Stop Hook │
|
|
157
|
+
│ (auto-reply)│
|
|
158
|
+
└─────────────┘
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## File Structure
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
feishu-notify/
|
|
165
|
+
├── src/feishu_notify/
|
|
166
|
+
│ ├── __init__.py
|
|
167
|
+
│ ├── cli.py # CLI entry point
|
|
168
|
+
│ ├── client.py # WebSocket client
|
|
169
|
+
│ ├── config.py # Configuration management
|
|
170
|
+
│ ├── sender.py # Message sending
|
|
171
|
+
│ └── i18n.py # Internationalization
|
|
172
|
+
├── tests/
|
|
173
|
+
│ ├── test_config.py
|
|
174
|
+
│ └── test_sender.py
|
|
175
|
+
├── skills/ # Claude Code Skill
|
|
176
|
+
│ └── feishu-notify/
|
|
177
|
+
│ └── SKILL.md
|
|
178
|
+
├── pyproject.toml
|
|
179
|
+
└── README.md
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Configuration
|
|
183
|
+
|
|
184
|
+
### Environment Variables
|
|
185
|
+
|
|
186
|
+
| Variable | Required | Description |
|
|
187
|
+
|----------|----------|-------------|
|
|
188
|
+
| `FEISHU_APP_ID` | ✅ | Feishu App ID |
|
|
189
|
+
| `FEISHU_APP_SECRET` | ✅ | Feishu App Secret |
|
|
190
|
+
| `FEISHU_WEBHOOK_URL` | ❌ | Group bot webhook (for simple push) |
|
|
191
|
+
| `FEISHU_NOTIFY_LANG` | ❌ | Language: `zh` (default) or `en` |
|
|
192
|
+
|
|
193
|
+
### Multi-window Scenario
|
|
194
|
+
|
|
195
|
+
When you have multiple Claude Code windows, use **on-duty mode**:
|
|
196
|
+
|
|
197
|
+
1. In Claude Code terminal: `feishu-notify on-duty`
|
|
198
|
+
2. Messages from Feishu will only go to the on-duty window
|
|
199
|
+
3. Switch windows: Send `/windows` in Feishu → Click to switch
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
### Message Send Failed
|
|
204
|
+
|
|
205
|
+
1. Check `.env` configuration is correct
|
|
206
|
+
2. Check if Feishu app is published
|
|
207
|
+
3. Check if app is added to group chat
|
|
208
|
+
|
|
209
|
+
### Reply Not Sent to Feishu
|
|
210
|
+
|
|
211
|
+
1. Confirm Stop Hook is configured
|
|
212
|
+
2. Confirm long polling client is running
|
|
213
|
+
3. Check logs: `tail -f /tmp/feishu-longpoll.log`
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Install dev dependencies
|
|
219
|
+
pip install -e ".[dev]"
|
|
220
|
+
|
|
221
|
+
# Run tests
|
|
222
|
+
pytest
|
|
223
|
+
|
|
224
|
+
# Run tests with coverage
|
|
225
|
+
pytest --cov=feishu_notify
|
|
226
|
+
|
|
227
|
+
# Type check
|
|
228
|
+
pyright src/
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 中文文档
|
|
238
|
+
|
|
239
|
+
飞书机器人消息推送与远程控制 Skill,支持从飞书远程操控 Claude Code。
|
|
240
|
+
|
|
241
|
+
### 特性
|
|
242
|
+
|
|
243
|
+
- 🔔 **即时推送** - 任务完成自动通知到飞书
|
|
244
|
+
- 🎮 **远程控制** - 从飞书发送命令到 Claude Code
|
|
245
|
+
- 🪟 **多窗口管理** - 值班模式,指定窗口接收消息
|
|
246
|
+
- 📱 **手机友好** - 输出优化,适合手机阅读
|
|
247
|
+
- 🎴 **交互卡片** - 窗口列表卡片展示
|
|
248
|
+
|
|
249
|
+
### 安装
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
pip install feishu-notify
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 快速开始
|
|
256
|
+
|
|
257
|
+
1. 配置飞书应用并获取 App ID 和 App Secret
|
|
258
|
+
2. 创建 `~/.config/feishu-notify/.env` 文件
|
|
259
|
+
3. 运行 `feishu-notify start` 启动长连接客户端
|
|
260
|
+
|
|
261
|
+
### 使用方式
|
|
262
|
+
|
|
263
|
+
从飞书发消息(无需前缀):
|
|
264
|
+
```
|
|
265
|
+
帮我写一个冒泡排序
|
|
266
|
+
今天上海天气怎么样?
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
窗口管理:
|
|
270
|
+
```
|
|
271
|
+
/windows # 查看活跃窗口
|
|
272
|
+
/switch 1 # 切换到窗口 1
|
|
273
|
+
/on-duty # 查看当前值班窗口
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 故障排除
|
|
277
|
+
|
|
278
|
+
**消息发送失败**
|
|
279
|
+
1. 检查 `.env` 配置是否正确
|
|
280
|
+
2. 检查飞书应用是否已发布
|
|
281
|
+
3. 检查应用是否已添加到群聊
|
|
282
|
+
|
|
283
|
+
**回复没有发送到飞书**
|
|
284
|
+
1. 确认 Stop Hook 已配置
|
|
285
|
+
2. 确认长连接客户端正在运行
|
|
286
|
+
3. 检查日志:`tail -f /tmp/feishu-longpoll.log`
|
|
287
|
+
|
|
288
|
+
### 许可证
|
|
289
|
+
|
|
290
|
+
MIT
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "feishu-cc"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Feishu (Lark) bot messaging and remote control for Claude Code and terminals"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Step Tian", email = "step@example.com"}
|
|
13
|
+
]
|
|
14
|
+
keywords = ["feishu", "lark", "claude-code", "notification", "remote-control", "bot"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Communications :: Chat",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Terminals",
|
|
29
|
+
]
|
|
30
|
+
requires-python = ">=3.9"
|
|
31
|
+
dependencies = [
|
|
32
|
+
"lark-oapi>=1.4.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=7.0",
|
|
38
|
+
"pytest-cov>=4.0",
|
|
39
|
+
"sphinx>=7.0",
|
|
40
|
+
"sphinx-rtd-theme>=2.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
feishu-notify = "feishu_notify.cli:main"
|
|
45
|
+
feishu-notify-client = "feishu_notify.client:main"
|
|
46
|
+
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://github.com/steptian/feishu-notify"
|
|
49
|
+
Documentation = "https://github.com/steptian/feishu-notify#readme"
|
|
50
|
+
Repository = "https://github.com/steptian/feishu-notify.git"
|
|
51
|
+
Issues = "https://github.com/steptian/feishu-notify/issues"
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.packages.find]
|
|
54
|
+
where = ["src"]
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.package-data]
|
|
57
|
+
feishu_notify = ["py.typed"]
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
testpaths = ["tests"]
|
|
61
|
+
python_files = ["test_*.py"]
|
|
62
|
+
python_classes = ["Test*"]
|
|
63
|
+
python_functions = ["test_*"]
|
|
64
|
+
addopts = "-v --tb=short"
|
|
65
|
+
|
|
66
|
+
[tool.coverage.run]
|
|
67
|
+
source = ["src/feishu_notify"]
|
|
68
|
+
branch = true
|
|
69
|
+
|
|
70
|
+
[tool.coverage.report]
|
|
71
|
+
exclude_lines = [
|
|
72
|
+
"pragma: no cover",
|
|
73
|
+
"if TYPE_CHECKING:",
|
|
74
|
+
"raise NotImplementedError",
|
|
75
|
+
]
|