TypeScript SDK¶
The official TypeScript/JavaScript client library for AMP.
Installation¶
Quick Start¶
import { AMP } from '@ubiship/amp';
const client = new AMP('amp_live_xxxxxxxxxxxxx');
// Create a mission
const mission = await client.missions.create({
name: 'TypeScript SDK Test',
objectives: ['Test the SDK'],
platforms: ['twitter'],
duration_days: 7,
});
console.log(`Created mission: ${mission.id}`);
Configuration¶
Client Options¶
const client = new AMP('amp_live_xxx', {
baseURL: 'https://custom.api.url',
timeout: 60000,
maxRetries: 3,
});
Environment Variables¶
Resources¶
Missions¶
// List missions
const missions = await client.missions.list({
status: 'active',
limit: 20,
});
// Create mission
const mission = await client.missions.create({
name: 'My Mission',
objectives: ['Drive awareness'],
platforms: ['twitter', 'linkedin'],
constraints: {
tone: 'professional',
cadence: 'daily',
posts_per_day: 2,
require_approval: true,
},
duration_days: 30,
});
// Get mission
const mission = await client.missions.retrieve('msn_xxx');
// Update mission
const mission = await client.missions.update('msn_xxx', {
constraints: {
posts_per_day: 3,
},
});
// Pause mission
const mission = await client.missions.pause('msn_xxx');
// Resume mission
const mission = await client.missions.resume('msn_xxx');
// Delete mission
await client.missions.delete('msn_xxx');
// Get status
const status = await client.missions.status('msn_xxx');
Content¶
// List content
const content = await client.content.list({
mission_id: 'msn_xxx',
status: 'pending_review',
});
// Get content
const item = await client.content.retrieve('cnt_xxx');
// Preview content
const preview = await client.content.preview('cnt_xxx');
// Approve content
const approved = await client.content.approve('cnt_xxx', {
notes: 'Looks good',
});
// Reject content
const rejected = await client.content.reject('cnt_xxx', {
reason: 'Too casual',
feedback: 'Use professional tone',
regenerate: true,
});
// Schedule content
const scheduled = await client.content.schedule('cnt_xxx', {
scheduled_for: '2024-01-16T14:00:00Z',
});
Analytics¶
// Overview
const overview = await client.analytics.overview({
period: '30d',
});
// Mission analytics
const analytics = await client.analytics.mission('msn_xxx');
// Costs
const costs = await client.analytics.costs({
period: '30d',
});
// Performance breakdown
const performance = await client.analytics.performance({
period: '30d',
breakdown: ['platform', 'type'],
});
Error Handling¶
import { AMP, AMPError, RateLimitError, NotFoundError } from '@ubiship/amp';
try {
const mission = await client.missions.retrieve('msn_xxx');
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Mission not found');
} else if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
await sleep(error.retryAfter * 1000);
} else if (error instanceof AMPError) {
console.log(`API error: ${error.code} - ${error.message}`);
} else {
throw error;
}
}
Pagination¶
Automatic Iteration¶
// Async iterator
for await (const mission of client.missions.list({ limit: 20 })) {
console.log(mission.id);
}
Manual Pagination¶
let page = await client.missions.list({ limit: 20 });
while (true) {
for (const mission of page.data) {
console.log(mission.id);
}
if (!page.has_more) break;
page = await client.missions.list({
limit: 20,
starting_after: page.data[page.data.length - 1].id,
});
}
Webhooks¶
Express Middleware¶
import express from 'express';
import { AMP } from '@ubiship/amp';
const app = express();
const client = new AMP('amp_live_xxx');
app.post('/webhooks/amp', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-amp-signature'] as string;
const timestamp = req.headers['x-amp-timestamp'] as string;
try {
const event = client.webhooks.constructEvent(
req.body,
signature,
timestamp,
process.env.WEBHOOK_SECRET!
);
switch (event.type) {
case 'content.published':
console.log('Content published:', event.data.content_id);
break;
case 'mission.completed':
console.log('Mission completed:', event.data.mission_id);
break;
}
res.status(200).send('OK');
} catch (err) {
res.status(401).send('Invalid signature');
}
});
TypeScript Types¶
import type {
Mission,
MissionCreateParams,
Content,
ContentStatus,
Platform,
Analytics,
} from '@ubiship/amp';
function processMission(mission: Mission): void {
console.log(mission.id, mission.status);
}
const params: MissionCreateParams = {
name: 'Typed Mission',
objectives: ['Type safety'],
platforms: ['twitter' as Platform],
duration_days: 30,
};
Testing¶
import { AMP, MockAMP } from '@ubiship/amp';
// Use test mode
const client = new AMP('amp_test_xxx');
// Or use mock client
const mockClient = new MockAMP();
mockClient.missions.create.mockResolvedValue({
id: 'msn_test',
status: 'active',
});
// Jest example
jest.mock('@ubiship/amp');
const mockedAMP = jest.mocked(AMP);
Node.js & Browser¶
The SDK works in both Node.js and browser environments:
// Node.js
import { AMP } from '@ubiship/amp';
// Browser (with bundler)
import { AMP } from '@ubiship/amp';
// Browser (CDN)
<script src="https://cdn.amp.dev/sdk/amp.min.js"></script>
<script>
const client = new AMP.default('amp_live_xxx');
</script>
Browser Security
Never expose your API key in client-side code. Use a backend proxy for browser applications.