@ascegu/teamily 1.0.32 → 1.0.33
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 +14 -14
- package/package.json +1 -1
- package/src/upload.ts +9 -16
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Integrates [Teamily](https://teamily.ai/) with OpenClaw as a self-hosted team me
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
openclaw plugins install @
|
|
8
|
+
openclaw plugins install @teamily/teamily
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Or update an existing install:
|
|
@@ -26,10 +26,10 @@ openclaw channel configure teamily
|
|
|
26
26
|
|
|
27
27
|
### Server Settings
|
|
28
28
|
|
|
29
|
-
| Field | Description | Default
|
|
30
|
-
| -------- | --------------------- |
|
|
31
|
-
| `apiURL` | Teamily REST API URL | `https://imserver
|
|
32
|
-
| `wsURL` | Teamily WebSocket URL | `wss://imserver
|
|
29
|
+
| Field | Description | Default |
|
|
30
|
+
| -------- | --------------------- | --------------------------------------- |
|
|
31
|
+
| `apiURL` | Teamily REST API URL | `https://imserver.teamily.ai/im_api` |
|
|
32
|
+
| `wsURL` | Teamily WebSocket URL | `wss://imserver.teamily.ai/msg_gateway` |
|
|
33
33
|
|
|
34
34
|
### Bot Account Settings
|
|
35
35
|
|
|
@@ -56,8 +56,8 @@ channels:
|
|
|
56
56
|
teamily:
|
|
57
57
|
enabled: true
|
|
58
58
|
server:
|
|
59
|
-
apiURL: https://imserver
|
|
60
|
-
wsURL: wss://imserver
|
|
59
|
+
apiURL: https://imserver.teamily.ai/im_api
|
|
60
|
+
wsURL: wss://imserver.teamily.ai/msg_gateway
|
|
61
61
|
accounts:
|
|
62
62
|
default:
|
|
63
63
|
userID: "bot-user-id"
|
|
@@ -89,12 +89,12 @@ openclaw message send teamily:user:userID --media /path/to/image.jpg
|
|
|
89
89
|
|
|
90
90
|
Supported media types are auto-detected by file extension:
|
|
91
91
|
|
|
92
|
-
| Extension
|
|
93
|
-
|
|
|
94
|
-
| `.jpg`, `.png`, `.gif`, etc.
|
|
95
|
-
| `.mp4`, `.mov`, `.webm`
|
|
96
|
-
| `.mp3`, `.m4a`, `.wav`
|
|
97
|
-
| `.pdf`, `.doc`, `.
|
|
92
|
+
| Extension | Type |
|
|
93
|
+
| ----------------------------------------------------- | ----- |
|
|
94
|
+
| `.jpg`, `.png`, `.gif`, etc. | Image |
|
|
95
|
+
| `.mp4`, `.mov`, `.webm` | Video |
|
|
96
|
+
| `.mp3`, `.m4a`, `.wav` | Audio |
|
|
97
|
+
| `.pdf`, `.doc`, `.zip`, `.json`, `.txt`, `.csv`, etc. | File |
|
|
98
98
|
|
|
99
99
|
## Group Chat Behavior
|
|
100
100
|
|
|
@@ -130,9 +130,9 @@ src/
|
|
|
130
130
|
config-schema.ts Zod config schema (server, accounts, DM security)
|
|
131
131
|
accounts.ts Account resolution and listing
|
|
132
132
|
normalize.ts Target ID normalization (user:ID, group:ID)
|
|
133
|
+
upload.ts Media category detection, MIME types, MP4 metadata parsing, video snapshot extraction
|
|
133
134
|
probe.ts Health check via REST API
|
|
134
135
|
runtime.ts Plugin runtime store
|
|
135
|
-
send.ts REST API message/media send (fallback path)
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
## License
|
package/package.json
CHANGED
package/src/upload.ts
CHANGED
|
@@ -131,9 +131,7 @@ export interface SnapshotResult {
|
|
|
131
131
|
height: number;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
export async function extractVideoSnapshot(
|
|
135
|
-
videoBuf: Buffer,
|
|
136
|
-
): Promise<SnapshotResult | null> {
|
|
134
|
+
export async function extractVideoSnapshot(videoBuf: Buffer): Promise<SnapshotResult | null> {
|
|
137
135
|
const { execFile } = await import("node:child_process");
|
|
138
136
|
const { promisify } = await import("node:util");
|
|
139
137
|
const { writeFile, readFile, unlink, mkdtemp } = await import("node:fs/promises");
|
|
@@ -147,12 +145,9 @@ export async function extractVideoSnapshot(
|
|
|
147
145
|
const outPath = path.join(dir, "snapshot.jpg");
|
|
148
146
|
|
|
149
147
|
await writeFile(inPath, videoBuf);
|
|
150
|
-
await execFileAsync("ffmpeg", [
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"-frames:v", "1",
|
|
154
|
-
outPath,
|
|
155
|
-
], { timeout: 15_000 });
|
|
148
|
+
await execFileAsync("ffmpeg", ["-y", "-i", inPath, "-frames:v", "1", outPath], {
|
|
149
|
+
timeout: 15_000,
|
|
150
|
+
});
|
|
156
151
|
|
|
157
152
|
const snap = await readFile(outPath);
|
|
158
153
|
if (snap.length === 0) {
|
|
@@ -250,12 +245,7 @@ interface BoxInfo {
|
|
|
250
245
|
}
|
|
251
246
|
|
|
252
247
|
/** Find a box by type within [start, end) range. */
|
|
253
|
-
function findBox(
|
|
254
|
-
buf: Buffer,
|
|
255
|
-
start: number,
|
|
256
|
-
end: number,
|
|
257
|
-
type: string,
|
|
258
|
-
): BoxInfo | null {
|
|
248
|
+
function findBox(buf: Buffer, start: number, end: number, type: string): BoxInfo | null {
|
|
259
249
|
let offset = start;
|
|
260
250
|
while (offset + 8 <= end) {
|
|
261
251
|
let size = buf.readUInt32BE(offset);
|
|
@@ -282,7 +272,10 @@ function findBox(
|
|
|
282
272
|
function parseJpegDimensions(buf: Buffer): { width: number; height: number } {
|
|
283
273
|
let i = 0;
|
|
284
274
|
while (i + 1 < buf.length) {
|
|
285
|
-
if (buf[i] !== 0xff) {
|
|
275
|
+
if (buf[i] !== 0xff) {
|
|
276
|
+
i++;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
286
279
|
const marker = buf[i + 1];
|
|
287
280
|
// SOF0–SOF3 (0xC0–0xC3): baseline, progressive, etc.
|
|
288
281
|
if (marker >= 0xc0 && marker <= 0xc3 && i + 9 < buf.length) {
|