scrapebadger 0.1.9 → 0.2.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 +123 -0
- package/dist/{index-9Mu-b1MB.d.cts → index-BbCkdZXy.d.cts} +955 -2
- package/dist/{index-9Mu-b1MB.d.ts → index-BbCkdZXy.d.ts} +955 -2
- package/dist/index.d.cts +4 -85
- package/dist/index.d.ts +4 -85
- package/dist/index.js +701 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +694 -5
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.d.cts +2 -1
- package/dist/twitter/index.d.ts +2 -1
- package/dist/twitter/index.js +696 -0
- package/dist/twitter/index.js.map +1 -1
- package/dist/twitter/index.mjs +691 -1
- package/dist/twitter/index.mjs.map +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -202,6 +202,112 @@ const nearby = await client.twitter.geo.search({
|
|
|
202
202
|
const place = await client.twitter.geo.getDetail("5a110d312052166f");
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
+
### Stream Monitoring
|
|
206
|
+
|
|
207
|
+
Real-time tweet monitoring with WebSocket streaming and webhook delivery.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { ScrapeBadger, WebSocketStreamError } from "scrapebadger";
|
|
211
|
+
|
|
212
|
+
const client = new ScrapeBadger({ apiKey: "your-api-key" });
|
|
213
|
+
|
|
214
|
+
// Create a monitor
|
|
215
|
+
const monitor = await client.twitter.stream.createMonitor({
|
|
216
|
+
name: "Tech Leaders",
|
|
217
|
+
usernames: ["elonmusk", "naval", "sama"],
|
|
218
|
+
pollIntervalSeconds: 10,
|
|
219
|
+
webhookUrl: "https://example.com/webhook",
|
|
220
|
+
});
|
|
221
|
+
console.log(`Created: ${monitor.id}, tier: ${monitor.pricing_tier}`);
|
|
222
|
+
console.log(`Credits/hr: ${monitor.estimated_credits_per_hour}`);
|
|
223
|
+
|
|
224
|
+
// List monitors
|
|
225
|
+
const { monitors, total } = await client.twitter.stream.listMonitors({ status: "active" });
|
|
226
|
+
console.log(`${total} active monitors`);
|
|
227
|
+
|
|
228
|
+
// Pause / resume
|
|
229
|
+
await client.twitter.stream.pauseMonitor(monitor.id);
|
|
230
|
+
await client.twitter.stream.resumeMonitor(monitor.id);
|
|
231
|
+
|
|
232
|
+
// Delete
|
|
233
|
+
await client.twitter.stream.deleteMonitor(monitor.id);
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### EventEmitter streaming
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const stream = client.twitter.stream.connect({
|
|
240
|
+
reconnect: true,
|
|
241
|
+
reconnectDelaySeconds: 90,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
stream.on("connected", (e) => {
|
|
245
|
+
console.log("Connected, connection ID:", e.connectionId);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
stream.on("tweet", (event) => {
|
|
249
|
+
console.log(`@${event.authorUsername}: ${event.tweet.text}`);
|
|
250
|
+
console.log(` latency: ${event.latencyMs}ms`);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
stream.on("error", (err) => {
|
|
254
|
+
if (err instanceof WebSocketStreamError && err.code === 4001) {
|
|
255
|
+
console.error("API key rejected");
|
|
256
|
+
} else {
|
|
257
|
+
console.error("Stream error:", err.message);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
stream.on("close", () => console.log("Stream closed"));
|
|
262
|
+
|
|
263
|
+
// Later: graceful disconnect
|
|
264
|
+
stream.close();
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### AsyncIterator streaming
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { WebSocketStreamError } from "scrapebadger";
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
for await (const event of client.twitter.stream.connectIter({
|
|
274
|
+
reconnect: true,
|
|
275
|
+
reconnectDelaySeconds: 90,
|
|
276
|
+
})) {
|
|
277
|
+
if (event.type === "tweet") {
|
|
278
|
+
console.log(`@${event.authorUsername}: ${event.latencyMs}ms latency`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
} catch (err) {
|
|
282
|
+
if (err instanceof WebSocketStreamError) {
|
|
283
|
+
console.error("Stream failed:", err.message, err.code);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### Webhook signature verification
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import { verifyWebhookSignature } from "scrapebadger/twitter";
|
|
292
|
+
import express from "express";
|
|
293
|
+
|
|
294
|
+
const app = express();
|
|
295
|
+
|
|
296
|
+
app.post(
|
|
297
|
+
"/webhook",
|
|
298
|
+
express.raw({ type: "application/json" }),
|
|
299
|
+
(req, res) => {
|
|
300
|
+
const sig = req.headers["x-scrapebadger-signature"] as string;
|
|
301
|
+
if (!verifyWebhookSignature("my-webhook-secret", req.body, sig)) {
|
|
302
|
+
return res.status(401).json({ error: "Invalid signature" });
|
|
303
|
+
}
|
|
304
|
+
const event = JSON.parse(req.body.toString());
|
|
305
|
+
console.log("Received tweet:", event.tweet_id);
|
|
306
|
+
res.sendStatus(200);
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
```
|
|
310
|
+
|
|
205
311
|
## Error Handling
|
|
206
312
|
|
|
207
313
|
```typescript
|
|
@@ -267,10 +373,26 @@ const client = new ScrapeBadger({
|
|
|
267
373
|
- `client.twitter.communities` - Community operations
|
|
268
374
|
- `client.twitter.trends` - Trend operations
|
|
269
375
|
- `client.twitter.geo` - Geographic place operations
|
|
376
|
+
- `client.twitter.stream` - Real-time stream monitor management and WebSocket streaming
|
|
377
|
+
|
|
378
|
+
### Stream Client Methods
|
|
379
|
+
|
|
380
|
+
- `createMonitor(params)` - Create a stream monitor
|
|
381
|
+
- `listMonitors(options?)` - List monitors with optional status filter
|
|
382
|
+
- `getMonitor(id)` - Get a monitor by ID
|
|
383
|
+
- `updateMonitor(id, params)` - Partially update a monitor
|
|
384
|
+
- `pauseMonitor(id)` - Pause an active monitor
|
|
385
|
+
- `resumeMonitor(id)` - Resume a paused monitor
|
|
386
|
+
- `deleteMonitor(id)` - Delete a monitor (irreversible)
|
|
387
|
+
- `listDeliveryLogs(options?)` - List tweet delivery logs
|
|
388
|
+
- `listBillingLogs(options?)` - List billing activity logs
|
|
389
|
+
- `connect(options?)` - Connect via EventEmitter (`.on("tweet", handler)`)
|
|
390
|
+
- `connectIter(options?)` - Connect via AsyncIterator (`for await`)
|
|
270
391
|
|
|
271
392
|
### Utilities
|
|
272
393
|
|
|
273
394
|
- `collectAll(asyncIterator)` - Collect async iterator results into an array
|
|
395
|
+
- `verifyWebhookSignature(secret, body, header)` - Verify incoming webhook HMAC signature
|
|
274
396
|
|
|
275
397
|
### Exceptions
|
|
276
398
|
|
|
@@ -283,6 +405,7 @@ const client = new ScrapeBadger({
|
|
|
283
405
|
- `TimeoutError` - Request timeout
|
|
284
406
|
- `InsufficientCreditsError` - Out of credits
|
|
285
407
|
- `AccountRestrictedError` - Account restricted
|
|
408
|
+
- `WebSocketStreamError` - WebSocket stream failure (auth, limit, or network)
|
|
286
409
|
|
|
287
410
|
## Requirements
|
|
288
411
|
|