Skip to content
Back to skills

Hootsuite Local Dev Loop

ASecurity

'Configure Hootsuite local development with hot reload and testing.

  • 2,688 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 29, 2026
ai-agentstypescriptbashtestingapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Scanned May 29, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill hootsuite-local-dev-loop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hootsuite Local Dev Loop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hootsuite Local Dev Loop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-hootsuite-local-dev-loop/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-hootsuite-local-dev-loop)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hootsuite-local-dev-loop
description: 'Configure Hootsuite local development with hot reload and testing.

  Use when setting up a development environment, configuring test workflows,

  or establishing a fast iteration cycle with Hootsuite.

  Trigger with phrases like "hootsuite dev setup", "hootsuite local development",

  "hootsuite dev environment", "develop with hootsuite".

  '
allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Grep
version: 1.0.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
tags:
- saas
- hootsuite
- social-media
compatibility: Designed for Claude Code
---
# Hootsuite Local Dev Loop

## Overview

Set up a development workflow for Hootsuite API integrations with mocked API responses, token management, and testing.

## Instructions

### Step 1: Project Structure

```
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
```

### Step 2: API Client with Auto Token Refresh

```typescript
// 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();
```

### Step 3: Mocked Tests

```typescript
// 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
  });
});
```

## Output

- API client with automatic token refresh
- Mocked test suite
- Project structure for Hootsuite integrations

## Resources

- [Hootsuite REST API](https://developer.hootsuite.com/docs/using-rest-apis)
- [Vitest](https://vitest.dev/)

## Next Steps

See `hootsuite-sdk-patterns` for production patterns.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…