From hootsuite-pack
Sets up local dev for Hootsuite API integrations with TypeScript OAuth client, auto token refresh, project structure, and mocked tests.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hootsuite-pack:hootsuite-local-dev-loopThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Set up a development workflow for Hootsuite API integrations with mocked API responses, token management, and testing.
Set up a development workflow for Hootsuite API integrations with mocked API responses, token management, and testing.
hootsuite-integration/
├── src/
│ ├── hootsuite/
│ │ ├── client.ts # API client with token refresh
│ │ ├── auth.ts # OAuth 2.0 flow
│ │ ├── publishing.ts # Message scheduling
│ │ └── analytics.ts # Metrics retrieval
│ └── index.ts
├── tests/
│ ├── fixtures/ # Mock API responses
│ │ ├── profiles.json
│ │ └── messages.json
│ └── publishing.test.ts
├── .env.local
└── package.json
// src/hootsuite/client.ts
import 'dotenv/config';
class HootsuiteClient {
private accessToken: string;
private refreshToken: string;
private expiresAt: number;
private base = 'https://platform.hootsuite.com/v1';
constructor() {
this.accessToken = process.env.HOOTSUITE_ACCESS_TOKEN!;
this.refreshToken = process.env.HOOTSUITE_REFRESH_TOKEN!;
this.expiresAt = Date.now() + 3600000;
}
async request(path: string, options: RequestInit = {}) {
if (Date.now() > this.expiresAt - 60000) await this.refresh();
const response = await fetch(`${this.base}${path}`, {
...options,
headers: { 'Authorization': `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', ...options.headers },
});
if (!response.ok) throw new Error(`Hootsuite API ${response.status}: ${await response.text()}`);
return response.json();
}
private async refresh() {
const res = await fetch('https://platform.hootsuite.com/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': `Basic ${Buffer.from(`${process.env.HOOTSUITE_CLIENT_ID}:${process.env.HOOTSUITE_CLIENT_SECRET}`).toString('base64')}` },
body: new URLSearchParams({ grant_type: 'refresh_token', refresh_token: this.refreshToken }),
});
const tokens = await res.json();
this.accessToken = tokens.access_token;
this.refreshToken = tokens.refresh_token;
this.expiresAt = Date.now() + tokens.expires_in * 1000;
}
}
export const hootsuite = new HootsuiteClient();
// tests/publishing.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
const mockFetch = vi.fn();
vi.stubGlobal('fetch', mockFetch);
describe('Hootsuite Publishing', () => {
beforeEach(() => vi.clearAllMocks());
it('should schedule a message', async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => ({ data: [{ id: 'msg_123', state: 'SCHEDULED' }] }),
});
// Test scheduling logic
});
it('should list social profiles', async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => ({ data: [{ id: 'prof_1', type: 'TWITTER', socialNetworkUsername: 'test' }] }),
});
// Test profile listing
});
});
See hootsuite-sdk-patterns for production patterns.
7plugins reuse this skill
First indexed Jul 10, 2026
Showing the 6 earliest of 7 plugins
npx claudepluginhub luxdevnet/claude-plus-lux --plugin hootsuite-packSets up local dev for Hootsuite API integrations with TypeScript OAuth client, auto token refresh, project structure, and mocked tests.
Configures Intercom local development with testing, mocking, and hot reload for fast iteration against a dev workspace.
Guides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.