docs: expand JavaScript SDK documentation
This commit is contained in:
+31
-114
@@ -2,13 +2,15 @@
|
||||
|
||||
TypeScript SDK for the Socialhose Public API.
|
||||
|
||||
Use it from backend TypeScript/JavaScript to fetch campaigns, analytics, mentions, mailing lists, and SDK-composed entity analytics with authentication, retries, timeouts, and caching handled consistently.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install @socialhose/api
|
||||
```
|
||||
|
||||
Node 18+ is required because the SDK uses the built-in `fetch`, `Response`, and `AbortSignal.timeout` APIs. You can pass a custom `fetch` implementation if needed.
|
||||
Node 18+ is required because the SDK uses built-in `fetch`, `Response`, and `AbortSignal.timeout`. You can pass a custom `fetch` implementation if needed.
|
||||
|
||||
## Quickstart
|
||||
|
||||
@@ -28,6 +30,14 @@ const mentions = await socialhose.getMentions({
|
||||
console.log(mentions.count, mentions.results[0]?.content);
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Usage guide](./docs/GUIDE.md) — what the SDK is, setup, common workflows, operational guidance.
|
||||
- [API reference](./docs/API.md) — every public class, function, method, option, and exported type.
|
||||
- [Entity analytics](./docs/ENTITY_ANALYTICS.md) — how term-level analytics are built, accuracy safeguards, rate-limit guidance.
|
||||
- [Caching and retries](./docs/CACHING_AND_RETRIES.md) — cache contract, retry policy, failure semantics.
|
||||
- [Examples](./examples) — runnable TypeScript examples.
|
||||
|
||||
## Configuration
|
||||
|
||||
```ts
|
||||
@@ -42,127 +52,29 @@ const socialhose = new SocialhoseClient({
|
||||
|
||||
The SDK sends `Authorization: Api-Key <key>` and a browser-like `User-Agent` by default. The user-agent is intentional: the current Socialhose API edge rejects some non-browser requests.
|
||||
|
||||
## Endpoints
|
||||
## Main capabilities
|
||||
|
||||
### Campaigns
|
||||
- `getCampaigns()`
|
||||
- `getCampaign(id)`
|
||||
- Campaign discovery: `getCampaigns()`, `getCampaign(id)`, `getCampaignIdByMatch(match)`.
|
||||
- Analytics: `getOverview()`, `getTimeline()`, `getSentiment()`, `getShareOfVoice()`, `getPlatforms()`, `getTopKeywords()`, `getTrending()`, `getTopMentions()`.
|
||||
- Mentions: `getMentions()` with campaign, date, platform, sentiment, text search, pagination, and ordering filters.
|
||||
- Mailing lists: `getMailingLists()`, `inviteMailingListMember()`.
|
||||
- Entity analytics: `getEntityBrief()`, `getEntityStats()`, `getEntityBriefs()`.
|
||||
- Low-level access: `get(path, params)`, `post(path, body)`.
|
||||
- Caching: built-in `MemoryCache`, disabling via `NoopCache`, or any custom `Cache` implementation.
|
||||
|
||||
### Analytics
|
||||
- `getOverview(filters)`
|
||||
- `getTimeline(filters)`
|
||||
- `getSentiment(filters)`
|
||||
- `getShareOfVoice(filters)`
|
||||
- `getPlatforms(filters)`
|
||||
- `getTopKeywords(filters)`
|
||||
- `getTrending(filters)`
|
||||
- `getTopMentions(filters)`
|
||||
## Entity analytics warning
|
||||
|
||||
### Mentions
|
||||
- `getMentions(filters)`
|
||||
|
||||
### Mailing Lists
|
||||
- `getMailingLists()`
|
||||
- `inviteMailingListMember(listId, invite)`
|
||||
|
||||
### Entity Analytics
|
||||
- `getEntityBrief(term, campaignId?)` — one request: count + top-20 engagement sample with derived sentiment/platform
|
||||
- `getEntityStats(term, campaignId?)` — full dashboard: exact sentiment faceting, exact platform mix, 14-day cumulative-differenced timeline, 7d momentum
|
||||
- `getEntityBriefs(terms, campaignId?, concurrency?)` — batch entity resolution with bounded concurrency (default 20)
|
||||
- `getCampaignIdByMatch(substring)` — resolve a live campaign ID by matching its name
|
||||
|
||||
### Low-Level
|
||||
- `get(path, params)` for direct GET access
|
||||
- `post(path, body)` for direct POST access
|
||||
|
||||
## Filtering examples
|
||||
Entity analytics fan out multiple `/mentions/` requests per term. Use `cacheTtlMs`, `revalidateSeconds`, or a persistent shared cache to stay under the approximate 60 req/min API-key rate limit.
|
||||
|
||||
```ts
|
||||
await socialhose.getOverview({
|
||||
campaign_ids: 'campaign-id',
|
||||
date_from: '2026-05-01',
|
||||
date_to: '2026-05-29',
|
||||
platforms: 'twitter,reddit',
|
||||
sentiments: 'negative',
|
||||
});
|
||||
|
||||
await socialhose.getTimeline({
|
||||
campaign_ids: 'campaign-id',
|
||||
interval: 'day',
|
||||
const stats = await socialhose.getEntityStats('RSF', 'campaign-id', {
|
||||
revalidateSeconds: 900,
|
||||
});
|
||||
```
|
||||
|
||||
## Custom Caching
|
||||
|
||||
The SDK ships with `MemoryCache` (in-memory, per-entry TTL) and `NoopCache` (no caching). You can inject your own by implementing the `Cache` interface:
|
||||
|
||||
```ts
|
||||
import { SocialhoseClient, Cache } from '@socialhose/api';
|
||||
|
||||
class RedisCache implements Cache {
|
||||
async get(key: string) { /* redis.get(key) */ }
|
||||
async set(key: string, value: unknown, ttlMs: number) { /* redis.set(key, value, 'PX', ttlMs) */ }
|
||||
async delete(key: string) { /* redis.del(key) */ }
|
||||
}
|
||||
|
||||
const socialhose = new SocialhoseClient({
|
||||
apiKey: process.env.SOCIALHOSE_API_KEY!,
|
||||
cache: new RedisCache(),
|
||||
});
|
||||
```
|
||||
|
||||
Pass `revalidateSeconds` per request to control per-call TTL in your cache implementation:
|
||||
|
||||
```ts
|
||||
await socialhose.getMentions(
|
||||
{ content_search: 'ozempic' },
|
||||
{ revalidateSeconds: 3600 },
|
||||
);
|
||||
```
|
||||
|
||||
## Entity Analytics
|
||||
|
||||
Search across all mentions for a specific term, person, or organization:
|
||||
|
||||
```ts
|
||||
// Quick count + top mentions
|
||||
const brief = await socialhose.getEntityBrief('Burhan');
|
||||
console.log(brief.total, brief.sentiment, brief.platformMix);
|
||||
|
||||
// Full dashboard: exact distributions, timeline, momentum
|
||||
const stats = await socialhose.getEntityStats('RSF', 'campaign-id');
|
||||
console.log(
|
||||
stats.total,
|
||||
stats.momentumPct, // last 7 days vs prior 7
|
||||
stats.sentiment, // exact (facets reconcile) or estimated (from sample)
|
||||
stats.sparkline, // 14-day daily volume
|
||||
);
|
||||
|
||||
// Batch resolve many entities with bounded concurrency
|
||||
const briefs = await socialhose.getEntityBriefs(
|
||||
['Burhan', 'Hemedti', 'SAF', 'RSF'],
|
||||
'campaign-id',
|
||||
10, // concurrency
|
||||
);
|
||||
```
|
||||
|
||||
Entity analytics fan out multiple requests per entity (sentiment faceting: 3 calls; platform mix: 6 calls; timeline: 15 calls). Set `cacheTtlMs` or inject a persistent cache to stay under the ~60 req/min rate limit.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
**Cloudflare UA blocking.** The Socialhose API sits behind Cloudflare, which rejects some non-browser User-Agent headers. The SDK defaults to a Chrome 124 UA — don't change it unless you've verified the new UA works.
|
||||
|
||||
**Entity timeline uses cumulative differencing.** The analytics timeline endpoint is campaign-scoped and ignores `content_search`. The SDK facets `/mentions/` by day using cumulative `date_from`-only queries and subtracts consecutive counts. This avoids the API's `date_to` inclusivity bug: overlapping `[date_from, date_to]` windows share a day and double-count it. Don't "simplify" this to day windows.
|
||||
|
||||
**Sentiment reconciliation checks.** The `getEntityStats` exact sentiment and platform distributions validate that facet counts reconcile with the known total (e.g., positive + negative + neutral === total). If they don't match, the API silently dropped the `content_search` filter — the SDK falls back to estimates from the brief's sample rather than showing wrong data.
|
||||
|
||||
**Rate limit ~60 req/min per API key.** Entity analytics fan out many parallel requests. Use the `cache` option with a persistent store (Redis, Next.js Data Cache) to keep warm loads under the limit.
|
||||
|
||||
**Never expose the API key to the browser.** This SDK is designed for server-side use. Always set `SOCIALHOSE_API_KEY` as a server-side environment variable.
|
||||
|
||||
## Errors
|
||||
|
||||
Failed requests throw `SocialhoseError` with `status`, `path`, and response `body` when available.
|
||||
Failed requests throw `SocialhoseError` with `status`, `path`, `body`, and `cause` when available.
|
||||
|
||||
```ts
|
||||
import { SocialhoseError } from '@socialhose/api';
|
||||
@@ -176,12 +88,17 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
## Publishing
|
||||
## Development
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm test
|
||||
pnpm typecheck
|
||||
pnpm build
|
||||
npm publish --access public --provenance
|
||||
```
|
||||
|
||||
Publishing:
|
||||
|
||||
```bash
|
||||
npm publish --access public --provenance
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user