### Install Dependencies for Development Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md After cloning the repository, run this command to install all necessary dependencies for development. ```bash npm install ``` -------------------------------- ### Complete Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md A comprehensive example showcasing client initialization, connectivity testing, profile retrieval, post and comment iteration, liking posts, adding comments, and creating status updates. ```APIDOC ## Complete Example ```typescript import { SubstackClient } from 'substack-api'; async function substackDashboard() { const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: 'example.substack.com' }); try { // Test connectivity const isConnected = await client.testConnectivity(); if (!isConnected) { throw new Error('Failed to connect to Substack API'); } // Get your profile const myProfile = await client.ownProfile(); console.log(`šŸ“Š Dashboard for ${myProfile.name} (@${myProfile.slug})`); console.log(`šŸ‘„ Followers: ${myProfile.followerCount}`); // Get recent posts with engagement console.log(` šŸ“„ Recent Posts:`); for await (const post of myProfile.posts({ limit: 5 })) { console.log(` "${post.title}"`); console.log(` šŸ“… ${post.publishedAt?.toLocaleDateString()}`); console.log(` šŸ’– ${post.reactions?.length || 0} reactions`); // Get recent comments const comments = []; for await (const comment of post.comments({ limit: 3 })) { comments.push(comment); } console.log(` šŸ’¬ ${comments.length} recent comments`); } // Get and interact with other profiles console.log(` šŸ‘„ Community Interaction:`); const otherProfile = await client.profileForSlug('interesting-writer'); console.log(`Found profile: ${otherProfile.name}`); // Like their recent post for await (const post of otherProfile.posts({ limit: 1 })) { await post.like(); console.log(`Liked: "${post.title}"`); // Add a supportive comment await post.addComment('Great insights! Thanks for sharing.'); console.log(`Added comment to: "${post.title}"`); break; } // Create a status update const statusNote = await myProfile.createNote({ body: 'šŸš€ Just published some new content! Exciting times ahead.' }); console.log(` šŸ“ Status update published: ${statusNote.id}`); } catch (error) { console.error('āŒ Dashboard error:', error.message); } } // Run the dashboard substackDashboard(); ``` ``` -------------------------------- ### Unit Test Structure Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/CONTRIBUTING.md Illustrates the basic structure of a unit test for the SubstackClient, including setup and a sample test case. ```typescript describe('SubstackClient', () => { let client: SubstackClient beforeEach(() => { client = new SubstackClient({ apiKey: 'test', hostname: 'test.com' }) }) test('should handle API responses correctly', () => { // Test implementation }) }) ``` -------------------------------- ### Install Substack API Client Source: https://github.com/jakub-k-slys/substack-api/blob/main/README.md Install the substack-api package using pnpm. ```bash pnpm add substack-api ``` -------------------------------- ### Cross-Platform Publishing Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/introduction.md Example of creating a draft post and then syncing it to other platforms like Medium and Twitter. ```typescript // Publish to Substack and sync elsewhere const post = await myProfile.createPost({ title: 'New Article', body: content, isDraft: false }); // Sync to other platforms await syncToMedium(post); await shareOnTwitter(post.canonicalUrl); ``` -------------------------------- ### Substack API Client Example Output Source: https://github.com/jakub-k-slys/substack-api/blob/main/samples/README.md This is an example of the expected output when running the Substack API client example application. It shows successful connection, profile information, recent posts, notes, and followed users. ```text šŸš€ Substack API Client Example āœ… Using API key from environment variables 🌐 Connected to: yourpub.substack.com šŸ“” Testing API connectivity... āœ… API connectivity verified šŸ‘¤ Fetching your profile... šŸ“‹ Profile Information: Name: Your Name Handle: @yourhandle URL: https://substack.com/@yourhandle šŸ“° Fetching your 3 most recent posts... 1. "Your Latest Post Title" Description: This is a preview of your post content... Published: 12/30/2024 Author: Your Name (@yourhandle) šŸ“ Fetching your 3 most recent notes... 1. "This is a sample note with some content that might be longer than the preview..." Date: 12/30/2024 Author: Your Name (@yourhandle) šŸ¤ Fetching users you follow... 1. Example Author (@exampleauthor) Bio: This is an example author bio... URL: https://substack.com/@exampleauthor ✨ Example completed successfully! ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Install the necessary Python packages for building documentation using Sphinx and MyST parser. ```bash pip install sphinx sphinx-rtd-theme myst-parser ``` -------------------------------- ### Comprehensive Substack API Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md A complete example demonstrating client initialization, connectivity testing, profile fetching, post iteration with comment retrieval, interacting with other profiles (liking, commenting), and creating status updates. Includes error handling. ```typescript import { SubstackClient } from 'substack-api'; async function substackDashboard() { const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: 'example.substack.com' }); try { // Test connectivity const isConnected = await client.testConnectivity(); if (!isConnected) { throw new Error('Failed to connect to Substack API'); } // Get your profile const myProfile = await client.ownProfile(); console.log(`šŸ“Š Dashboard for ${myProfile.name} (@${myProfile.slug})`); console.log(`šŸ‘„ Followers: ${myProfile.followerCount}`); // Get recent posts with engagement console.log(` šŸ“„ Recent Posts:`); for await (const post of myProfile.posts({ limit: 5 })) { console.log(` "${post.title}"`); console.log(` šŸ“… ${post.publishedAt?.toLocaleDateString()}`); console.log(` šŸ’– ${post.reactions?.length || 0} reactions`); // Get recent comments const comments = []; for await (const comment of post.comments({ limit: 3 })) { comments.push(comment); } console.log(` šŸ’¬ ${comments.length} recent comments`); } // Get and interact with other profiles console.log(` šŸ‘„ Community Interaction:`); const otherProfile = await client.profileForSlug('interesting-writer'); console.log(`Found profile: ${otherProfile.name}`); // Like their recent post for await (const post of otherProfile.posts({ limit: 1 })) { await post.like(); console.log(`Liked: "${post.title}"`); // Add a supportive comment await post.addComment('Great insights! Thanks for sharing.'); console.log(`Added comment to: "${post.title}"`); break; } // Create a status update const statusNote = await myProfile.createNote({ body: 'šŸš€ Just published some new content! Exciting times ahead.' }); console.log(` šŸ“ Status update published: ${statusNote.id}`); } catch (error) { console.error('āŒ Dashboard error:', error.message); } } // Run the dashboard substackDashboard(); ``` -------------------------------- ### Install Substack API with NPM Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md Use this command to install the substack-api package using npm. Ensure you have Node.js and npm installed. ```bash npm install substack-api ``` -------------------------------- ### Install Substack API with Yarn Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md Use this command to install the substack-api package using yarn. Ensure you have Node.js and yarn installed. ```bash yarn add substack-api ``` -------------------------------- ### Content Dashboard Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md A complete example demonstrating how to fetch and display performance metrics for recent posts and notes using the Substack API. It initializes the client, retrieves the user's profile, and iterates through posts and notes. ```typescript async function contentDashboard() { const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN! }); const myProfile = await client.ownProfile(); console.log(`šŸ“Š Content Dashboard for ${myProfile.name}`); // Recent posts performance console.log(`\nšŸ“„ Recent Posts:`); for await (const post of myProfile.posts({ limit: 5 })) { console.log(`\n "${post.title}"`); console.log(` šŸ“… ${post.publishedAt?.toLocaleDateString()}`); console.log(` šŸ’– ${post.reactions?.length || 0} reactions`); console.log(` šŸ’¬ ${post.commentCount} comments`); console.log(` šŸ”— ${post.canonicalUrl}`); } // Recent notes engagement console.log(`\nšŸ“ Recent Notes:`); for await (const note of myProfile.notes({ limit: 10 })) { console.log(`\n "${note.body.substring(0, 80)}..."`); console.log(` šŸ• ${note.createdAt.toLocaleDateString()}`); console.log(` šŸ’– ${note.reactions?.length || 0} reactions`); } } ``` -------------------------------- ### Environment Setup Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Shows how to configure the SubstackClient using environment variables for token and publication URL. ```APIDOC ## Environment Setup ### Description Configures the SubstackClient using environment variables for sensitive information like API tokens and publication URLs. ### Usage 1. Create a `.env` file in your project root: ``` SUBSTACK_TOKEN=your-connect-sid-cookie-value SUBSTACK_PUBLICATION_URL=yoursite.substack.com ``` 2. Load environment variables using a library like `dotenv`. ### Example ```typescript import dotenv from 'dotenv'; dotenv.config(); const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: process.env.SUBSTACK_PUBLICATION_URL }); ``` ``` -------------------------------- ### Run E2E Tests and Setup Source: https://github.com/jakub-k-slys/substack-api/blob/main/CONTRIBUTING.md Instructions for running end-to-end tests, which require setting up credentials in a .env file. ```bash # Setup credentials first cp .env.example .env # Edit .env and add your SUBSTACK_TOKEN npm run test:e2e npm run test:e2e:watch npm run test:all ``` -------------------------------- ### Verify Substack API Installation Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md Create and run this test file to verify your Substack API installation. Replace placeholders with your actual cookie and publication URL. ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' }); async function test() { try { const isConnected = await client.testConnectivity(); console.log('Connection status:', isConnected ? 'Connected' : 'Failed'); } catch (error) { console.error('Error:', error.message); } } test(); ``` -------------------------------- ### Newsletter Analytics Dashboard Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/introduction.md Example of tracking performance metrics for posts using async iteration to fetch and log reaction counts. ```typescript const myProfile = await client.ownProfile(); // Track performance metrics for await (const post of myProfile.posts({ limit: 10 })) { console.log(`"${post.title}": ${post.reactions?.length || 0} reactions`); } ``` -------------------------------- ### Initialize Substack API Client Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/introduction.md Demonstrates how to install the library, obtain an authentication cookie, and initialize the Substack client with a token. ```bash npm install substack-api ``` ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN! }); // Test connection const isConnected = await client.testConnectivity(); // Get your profile and start exploring const myProfile = await client.ownProfile(); console.log(`Welcome ${myProfile.name}!`); ``` -------------------------------- ### Setup E2E Environment Source: https://github.com/jakub-k-slys/substack-api/blob/main/tests/e2e/README.md Copy the environment template and edit the .env file with your Substack API credentials before running tests. ```bash cp .env.example .env # Edit .env and add your credentials SUBSTACK_TOKEN=your-token-here SUBSTACK_PUBLICATION_URL=yoursite.substack.com # optional ``` -------------------------------- ### Copy .env.example to .env Source: https://github.com/jakub-k-slys/substack-api/blob/main/samples/README.md Copy the example environment file to a new file named .env. This file will store your Substack API credentials. ```bash cp .env.example .env ``` -------------------------------- ### Run the Substack API Sample Source: https://github.com/jakub-k-slys/substack-api/blob/main/samples/README.md Execute the sample application using npm. This command will run the example, which can use environment variables or prompt for credentials. ```bash npm run sample ``` -------------------------------- ### Set Up .env File for E2E Tests Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Copy the example .env file and edit it with your Substack credentials. Ensure the .env file is not committed to version control. ```bash cp .env.example .env ``` ```bash SUBSTACK_API_KEY=your-connect-sid-cookie-value SUBSTACK_HOSTNAME=yoursite.substack.com # optional ``` -------------------------------- ### E2E Test Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/CONTRIBUTING.md An example of an end-to-end test that fetches real profile data. It includes a check for credentials before execution. ```typescript describe('SubstackClient E2E', () => { beforeAll(() => { if (!global.E2E_CONFIG.hasCredentials) { throw new Error('E2E tests require credentials') } }) test('should fetch real profile data', async () => { const profile = await client.profileForSlug('platformer') expect(profile.name).toBeTruthy() }) }) ``` -------------------------------- ### Note Interactions: like() Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Provides an example of how to like a note. ```APIDOC ### Interactions #### like() Like the note: ```typescript await note.like(); console.log('Note liked!'); ``` ``` -------------------------------- ### Community Engagement Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md An example showcasing how to engage with the Substack community by liking posts and adding comments to content from followed users, and creating a status update. It requires authentication with a SUBSTACK_TOKEN. ```typescript async function engageWithCommunity() { const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN! }); const myProfile = await client.ownProfile(); // Engage with people you follow console.log('šŸ¤ Engaging with community...'); for await (const user of myProfile.following({ limit: 10 })) { console.log(`\nChecking ${user.name}...`); // Like their recent post for await (const post of user.posts({ limit: 1 })) { await post.like(); console.log(` āœ… Liked: "${post.title}"`); // Add a supportive comment await post.addComment('Great insights! Thanks for sharing.'); console.log(` šŸ’¬ Added supportive comment`); break; } } // Create a status update const statusNote = await myProfile.createNote({ body: '🌟 Had a great day engaging with the community! So many brilliant writers on Substack.' }); console.log(`\nšŸ“ Status update posted: ${statusNote.id}`); } ``` -------------------------------- ### Post Interactions: like() Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Provides an example of how to like a post, which requires authentication. ```APIDOC ### Interactions #### like() Like the post (requires authentication): ```typescript await post.like(); console.log(`Liked: "${post.title}"`); ``` ``` -------------------------------- ### Comment Interactions: like() Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Provides an example of how to like a comment. ```APIDOC ### Interactions #### like() Like the comment: ```typescript await comment.like(); console.log('Comment liked!'); ``` ``` -------------------------------- ### Integration Test Example Source: https://github.com/jakub-k-slys/substack-api/blob/main/CONTRIBUTING.md Demonstrates parsing subscription data in an integration test, verifying key fields from a sample API response. ```typescript describe('Sample Data Integration', () => { test('should parse subscription data correctly', () => { const samplePath = join(samplesDir, 'subscription') const sampleData = JSON.parse(readFileSync(samplePath, 'utf8')) expect(sampleData.id).toBeDefined() expect(sampleData.membership_state).toBe('subscribed') }) }) ``` -------------------------------- ### Create Simple Note Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Publish a new short-form note using the builder pattern. This example demonstrates creating a basic note with a single paragraph. ```typescript // Simple note const note = await myProfile.newNote().paragraph().text('šŸš€ Just shipped a new feature! Excited to share what we\'ve been working on.').publish(); console.log(`Note published: ${note.id}`); ``` -------------------------------- ### Get Profile by Slug Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve a profile by its unique slug or handle. ```APIDOC ## Get Profile by Slug ### Description Retrieve a profile by its unique slug or handle. ### Method ```typescript const profile = await client.profileForSlug('example-user'); console.log(`${profile.name}: ${profile.bio || 'No bio available'}`); // Iterate through their recent posts for await (const post of profile.posts({ limit: 10 })) { console.log(`- ${post.title} by ${post.author.name} Published: ${post.publishedAt?.toLocaleDateString()}`); } ``` ### Parameters #### Path Parameters - **slug** (string) - Required - The unique slug or handle of the profile to retrieve. ### Response #### Success Response (200) - **name** (string) - The name of the profile. - **bio** (string) - The biography of the profile. - **posts** (function) - A function to retrieve posts associated with the profile. Accepts an optional `limit` parameter. ``` -------------------------------- ### Getting Posts Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Illustrates how to retrieve a specific post using its ID or slug and access its properties. ```APIDOC ### Getting Posts ```typescript // Get specific post by ID/slug const post = await client.postForId('my-awesome-post'); console.log(`Title: ${post.title}`); console.log(`Author: ${post.author.name}`); console.log(`Published: ${post.publishedAt?.toLocaleDateString()}`); console.log(`Comments: ${post.commentCount}`); console.log(`URL: ${post.canonicalUrl}`); ``` ``` -------------------------------- ### Clone Substack API Repository Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md Clone the Substack API repository to contribute to the library or run it from source. This is the first step for development installation. ```bash git clone https://github.com/jakub-k-slys/substack-api.git cd substack-api ``` -------------------------------- ### E2E Test Failure Example (Missing Credentials) Source: https://github.com/jakub-k-slys/substack-api/blob/main/tests/e2e/README.md Illustrates the error message displayed when E2E tests are run without the necessary Substack API credentials configured in the .env file. ```text āŒ Missing required Substack credentials. Set SUBSTACK_TOKEN and SUBSTACK_PUBLICATION_URL. Required environment variables: - SUBSTACK_TOKEN: Your Substack token (required) - SUBSTACK_PUBLICATION_URL: Your Substack publication URL (optional) ``` -------------------------------- ### Substack API Client Test Structure Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Example test structure for the Substack client using Jest. It includes setup for mocking API calls and handling successful requests and errors. ```typescript import { Substack, SubstackError } from './client'; describe('Substack', () => { let client: Substack; beforeEach(() => { client = new Substack(); }); it('should handle successful requests', async () => { // Test implementation }); it('should handle errors', async () => { // Test implementation }); }); ``` -------------------------------- ### Build Documentation Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Navigate to the docs directory and execute the make command to build the HTML documentation. ```bash cd docs make html ``` -------------------------------- ### Run Tests for Substack API Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/installation.md Execute the test suite to ensure the library is functioning correctly after installation or code changes. This is a crucial step in the development workflow. ```bash npm test ``` -------------------------------- ### Client Initialization Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Import the library and create a client instance with your authentication token and publication URL. ```APIDOC ## Client Initialization ### Description Import the library and create a client instance with your authentication token and publication URL. ### Method ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'yoursite.substack.com' // optional, defaults to 'substack.com' }); ``` ### Parameters #### Request Body - **token** (string) - Required - Your Substack `substack.sid` cookie value for authentication. - **publicationUrl** (string) - Optional - Your Substack publication URL. Defaults to 'substack.com'. ``` -------------------------------- ### Engaging with Content using Substack API Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md This example demonstrates how to like and comment on posts and notes from a specific Substack profile. It iterates through recent posts and notes, performing actions with error handling for cases where an action might have already been taken. ```typescript async function engageWithContent() { try { // Find interesting profiles to engage with const profile = await client.profileForSlug('thought-leader'); console.log(`šŸ¤ Engaging with ${profile.name}'s content...\n`); // Engage with their recent posts for await (const post of profile.posts({ limit: 3 })) { console.log(`šŸ“„ "${post.title}"`); // Like the post try { await post.like(); console.log(` āœ… Liked`); } catch (error) { console.log(` āš ļø Already liked or failed to like`); } // Add a thoughtful comment try { const comment = await post.addComment( 'Great insights! This really resonates with my experience. Thanks for sharing your perspective.' ); console.log(` šŸ’¬ Added comment: ${comment.id}`); } catch (error) { console.log(` āš ļø Failed to comment: ${error.message}`); } console.log(''); } // Engage with their notes for await (const note of profile.notes({ limit: 5 })) { console.log(`šŸ“ Note: "${note.body.substring(0, 50)}"...`); try { await note.like(); console.log(` āœ… Liked note`); } catch (error) { console.log(` āš ļø Already liked note or failed`); } // Occasionally comment on interesting notes if (note.body.toLowerCase().includes('tip') || note.body.includes('šŸ’”')) { try { const comment = await note.addComment('This is really helpful! šŸ’Æ'); console.log(` šŸ’¬ Commented on note: ${comment.id}`); } catch (error) { console.log(` āš ļø Failed to comment on note`); } } console.log(''); } } catch (error) { console.error('Error engaging with content:', error.message); } } ``` -------------------------------- ### Create Environment File Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Create a .env file for testing with your Substack API key and hostname. ```bash # .env SUBSTACK_API_KEY=your-connect-sid-cookie-value SUBSTACK_HOSTNAME=example.substack.com ``` -------------------------------- ### Initialize the Client Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Demonstrates how to initialize the SubstackClient with a connection token and an optional publication URL. ```APIDOC ## Initialize the Client ### Description Initializes the SubstackClient with your Substack connect.sid cookie and optionally your publication URL. ### Method `new SubstackClient(options: { token: string, publicationUrl?: string })` ### Parameters #### Constructor Parameters - **token** (string) - Required - Your Substack connect.sid cookie value. - **publicationUrl** (string) - Optional - Your Substack publication URL (e.g., 'example.substack.com'). ### Example ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' }); const isConnected = await client.testConnectivity(); if (!isConnected) { throw new Error('Failed to connect to Substack API'); } ``` ``` -------------------------------- ### Get Note by ID Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve a specific note by its ID. ```APIDOC ## Get Note by ID ### Description Retrieve a specific note by its ID. ### Method ```typescript const note = await client.noteForId('note-123'); console.log(`Note by ${note.author.name}: ${note.body}`); // Like a note await note.like(); // Add a comment to a note await note.addComment('Interesting perspective!'); ``` ### Parameters #### Path Parameters - **noteId** (string) - Required - The ID of the note to retrieve. ### Response #### Success Response (200) - **body** (string) - The content of the note. - **author** (object) - Information about the note author. - **like** (function) - A function to like the note. - **addComment** (function) - A function to add a comment to the note. Accepts comment text as a string parameter. ``` -------------------------------- ### Client Initialization and Connectivity Test Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Demonstrates how to initialize the SubstackClient and test the connection to the API. ```APIDOC ## Client Initialization and Connectivity Test ### Description Initialize the SubstackClient with your authentication token and publication URL, then test if the connection is successful. ### Method ```typescript new SubstackClient({ token: string, publicationUrl: string }) await client.testConnectivity() ``` ### Parameters #### Initialization Parameters - **token** (string) - Required - Your Substack Connect SID cookie value. - **publicationUrl** (string) - Required - The URL of your Substack publication (e.g., 'example.substack.com'). #### Request Example ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' }); // Test connectivity const isConnected = await client.testConnectivity(); console.log('Connected:', isConnected); ``` ### Response #### Success Response (boolean) - **isConnected** (boolean) - True if the connection is successful, false otherwise. #### Response Example ```json { "isConnected": true } ``` ``` -------------------------------- ### Get Post by ID Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve a specific post by its ID. ```APIDOC ## Get Post by ID ### Description Retrieve a specific post by its ID. ### Method ```typescript const post = await client.postForId('my-awesome-post'); console.log(`Title: ${post.title} Author: ${post.author.name} Published: ${post.publishedAt?.toLocaleDateString()}`); // Navigate to comments with async iteration for await (const comment of post.comments({ limit: 5 })) { console.log(`šŸ’¬ ${comment.author.name}: ${comment.body.substring(0, 100)}... šŸ‘ ${comment.reactions?.length || 0} reactions`); } ``` ### Parameters #### Path Parameters - **postId** (string) - Required - The ID of the post to retrieve. ### Response #### Success Response (200) - **title** (string) - The title of the post. - **author** (object) - Information about the post author. - **publishedAt** (Date) - The publication date of the post. - **comments** (function) - A function to retrieve comments for the post. Accepts an optional `limit` parameter. - **like** (function) - A function to like the post. - **addComment** (function) - A function to add a comment to the post. Accepts comment text as a string parameter. ``` -------------------------------- ### Initialize and Use Substack Client Source: https://github.com/jakub-k-slys/substack-api/blob/main/README.md Initialize the SubstackClient with authentication token and publication URL, then fetch profile posts and test connectivity. ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' }); const profile = await client.ownProfile(); for await (const post of profile.posts({ limit: 5 })) { console.log(`"${post.title}" - ${post.publishedAt?.toLocaleDateString()}`); } const isConnected = await client.testConnectivity(); ``` -------------------------------- ### Get Profile by ID Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve a profile by its unique ID. ```APIDOC ## Get Profile by ID ### Description Retrieve a profile by its unique ID. ### Method ```typescript const profileById = await client.profileForId(12345); ``` ### Parameters #### Path Parameters - **id** (number) - Required - The unique ID of the profile to retrieve. ``` -------------------------------- ### Initialize Substack Client and Test Connectivity Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Instantiate the SubstackClient with your token and publication URL. Then, test the connection to ensure the client is configured correctly. ```typescript import { SubstackClient } from 'substack-api'; const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' }); // Test connectivity const isConnected = await client.testConnectivity(); console.log('Connected:', isConnected); ``` -------------------------------- ### Get Profile by Slug Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Retrieves a read-only profile for a given username or slug. ```APIDOC ## Get Profile by Slug ### Description Fetches a read-only `Profile` entity using the user's unique slug (username). ### Method ```typescript client.profileForSlug(slug: string): Promise ``` ### Parameters #### Path Parameters - **slug** (string) - Required - The username or slug of the profile to retrieve. ### Request Example ```typescript // Get profile by username/slug const profile = await client.profileForSlug('example-user'); console.log(`${profile.name} (@${profile.slug})`); console.log(`Bio: ${profile.bio || 'No bio available'}`); console.log(`Followers: ${profile.followerCount}`); ``` ### Response #### Success Response (Profile) - **id** (number) - Unique user ID. - **name** (string) - Display name. - **slug** (string) - Username/handle. - **bio** (string, optional) - Profile bio. - **followerCount** (number) - Number of followers. - **isFollowing** (boolean) - Whether the authenticated user follows this profile. - **photo** (object, optional) - Profile photo details. - **url** (string) - URL of the profile photo. - **originalUrl** (string) - Original URL of the profile photo. #### Response Example ```json { "id": 12345, "name": "Example User", "slug": "example-user", "bio": "Just a sample user.", "followerCount": 150, "isFollowing": false, "photo": { "url": "https://example.com/photo.jpg", "originalUrl": "https://example.com/photo_original.jpg" } } ``` ``` -------------------------------- ### Getting Notes Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Shows how to retrieve a specific note by its ID and display its content and metadata. ```APIDOC ### Getting Notes ```typescript // Get specific note by ID const note = await client.noteForId('note-123'); console.log(`Note by ${note.author.name}:`); console.log(`${note.body}`); console.log(`Posted: ${note.createdAt.toLocaleDateString()}`); console.log(`Reactions: ${note.reactions?.length || 0}`); ``` ``` -------------------------------- ### Initialize Substack Client with Environment Variables Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Initialize the SubstackClient using environment variables for token and publication URL. Ensure .env file is configured. ```typescript // .env file // SUBSTACK_TOKEN=your-connect-sid-cookie-value // SUBSTACK_PUBLICATION_URL=yoursite.substack.com import dotenv from 'dotenv'; dotenv.config(); const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: process.env.SUBSTACK_PUBLICATION_URL }); ``` -------------------------------- ### Get Own Profile's Notes Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve a list of notes created by your authenticated profile. ```APIDOC ## Get Own Profile's Notes ### Description Retrieve a list of notes created by your authenticated profile. ### Method ```typescript const myProfile = await client.ownProfile(); for await (const note of myProfile.notes({ limit: 10 })) { console.log(`šŸ“ ${note.body.substring(0, 80)}... šŸ’– ${note.reactions?.length || 0} reactions`); } ``` ### Response #### Success Response (200) - **body** (string) - The content of the note. - **reactions** (array) - A list of reactions to the note. ``` -------------------------------- ### Get Own Profile Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Retrieves the authenticated user's profile with full access capabilities. ```APIDOC ## Get Own Profile ### Description Fetches the `OwnProfile` entity, representing the authenticated user's profile with write capabilities. ### Method ```typescript client.ownProfile(): Promise ``` ### Parameters None ### Request Example ```typescript const myProfile = await client.ownProfile(); console.log(`Welcome ${myProfile.name}!`); console.log(`Email: ${myProfile.email}`); console.log(`Followers: ${myProfile.followerCount}`); ``` ### Response #### Success Response (OwnProfile) - **id** (number) - Unique user ID. - **name** (string) - Display name. - **slug** (string) - Username/handle. - **bio** (string, optional) - Profile bio. - **followerCount** (number) - Number of followers. - **isFollowing** (boolean) - Whether the authenticated user follows this profile. - **photo** (object, optional) - Profile photo details. - **url** (string) - URL of the profile photo. - **originalUrl** (string) - Original URL of the profile photo. - **email** (string, optional) - The authenticated user's email address. - **isEmailConfirmed** (boolean) - Indicates if the user's email is confirmed. - **stripeCustomerId** (string, optional) - The Stripe customer ID for payments. #### Response Example ```json { "id": 98765, "name": "Authenticated User", "slug": "my-profile", "email": "user@example.com", "isEmailConfirmed": true, "followerCount": 500, "isFollowing": false, "stripeCustomerId": "cus_123abc" } ``` ``` -------------------------------- ### Get Profile's Notes Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Iterates over all notes published by a profile, with automatic pagination. ```APIDOC ## Get Profile's Notes ### Description Retrieves an async iterable of `Note` entities associated with a profile. Supports automatic pagination and optional limits. ### Method ```typescript profile.notes(options?: { limit?: number }): AsyncIterable ``` ### Parameters #### Query Parameters - **limit** (number, optional) - The maximum number of notes to retrieve. ### Request Example ```typescript // Get recent notes for await (const note of profile.notes({ limit: 20 })) { console.log(`šŸ“ ${note.body.substring(0, 100)}...`); console.log(` šŸ’– ${note.reactions?.length || 0} reactions`); } ``` ### Response #### Success Response (AsyncIterable) - **Note** objects, each containing details like `body` and `reactions`. #### Response Example (for each note) ```json { "id": "note-abc", "body": "This is the content of the note.", "reactions": [ { "userId": 67890, "type": "like" } ] } ``` ``` -------------------------------- ### Initialize Substack Client with Token Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Import and create an instance of the SubstackClient. Requires your substack.sid cookie value for authentication and optionally your publication URL. ```typescript import { SubstackClient } from 'substack-api'; // Create client instance const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'yoursite.substack.com' // optional, defaults to 'substack.com' }); // Test connectivity const isConnected = await client.testConnectivity(); console.log('Connected:', isConnected); ``` -------------------------------- ### Get Profile's Posts Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Iterates over all posts published by a profile, with automatic pagination. ```APIDOC ## Get Profile's Posts ### Description Retrieves an async iterable of `Post` entities associated with a profile. Supports automatic pagination and optional limits. ### Method ```typescript profile.posts(options?: { limit?: number }): AsyncIterable ``` ### Parameters #### Query Parameters - **limit** (number, optional) - The maximum number of posts to retrieve. ### Request Example ```typescript // Get all posts (automatic pagination) for await (const post of profile.posts()) { console.log(`šŸ“„ ${post.title}`); console.log(` Published: ${post.publishedAt?.toLocaleDateString()}`); console.log(` Author: ${post.author.name}`); } // Limit to recent posts for await (const post of profile.posts({ limit: 10 })) { console.log(`- ${post.title} (${post.publishedAt?.toLocaleDateString()})`); } ``` ### Response #### Success Response (AsyncIterable) - **Post** objects, each containing details like `title`, `publishedAt`, and `author`. #### Response Example (for each post) ```json { "id": "post-123", "title": "My Awesome Post", "publishedAt": "2023-10-27T10:00:00Z", "author": { "id": 12345, "name": "Example User", "slug": "example-user" } } ``` ``` -------------------------------- ### Initialize Substack Client with Environment Variables Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Configure the SubstackClient using environment variables for sensitive information like the authentication token and publication URL. Recommended for security. ```typescript const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: process.env.SUBSTACK_PUBLICATION_URL }); ``` -------------------------------- ### Get Profile by ID Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/entity-model.md Retrieves a read-only profile for a given numeric user ID. ```APIDOC ## Get Profile by ID ### Description Fetches a read-only `Profile` entity using the user's unique numeric ID. ### Method ```typescript client.profileForId(id: number): Promise ``` ### Parameters #### Path Parameters - **id** (number) - Required - The numeric ID of the profile to retrieve. ### Request Example ```typescript // Get profile by numeric ID const profileById = await client.profileForId(12345); console.log(`Found: ${profileById.name}`); ``` ### Response #### Success Response (Profile) - **id** (number) - Unique user ID. - **name** (string) - Display name. - **slug** (string) - Username/handle. - **bio** (string, optional) - Profile bio. - **followerCount** (number) - Number of followers. - **isFollowing** (boolean) - Whether the authenticated user follows this profile. - **photo** (object, optional) - Profile photo details. - **url** (string) - URL of the profile photo. - **originalUrl** (string) - Original URL of the profile photo. #### Response Example ```json { "id": 12345, "name": "Example User", "slug": "example-user", "followerCount": 150, "isFollowing": false } ``` ``` -------------------------------- ### Run Unit Tests Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Execute all unit tests for individual components. Use watch mode for development. ```bash npm test # Run all unit tests npm run test:watch # Run in watch mode for development ``` -------------------------------- ### Get Own Profile Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Retrieve your authenticated profile, which includes write capabilities for content creation. ```APIDOC ## Get Own Profile ### Description Retrieve your authenticated profile, which includes write capabilities for content creation. ### Method ```typescript const myProfile = await client.ownProfile(); console.log(`Welcome ${myProfile.name}! (@${myProfile.slug}) Followers: ${myProfile.followerCount}`); // Iterate through your posts for await (const post of myProfile.posts({ limit: 5 })) { console.log(`šŸ“„ "${post.title}" - ${post.publishedAt?.toLocaleDateString()} šŸ’– ${post.reactions?.length || 0} reactions`); } ``` ### Response #### Success Response (200) - **name** (string) - The name of the profile. - **slug** (string) - The unique handle/slug of the profile. - **followerCount** (number) - The number of followers the profile has. - **posts** (function) - A function to retrieve posts associated with the profile. Accepts an optional `limit` parameter. ``` -------------------------------- ### Get Your Own Profile Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Retrieves and displays details about the currently authenticated user's profile. ```APIDOC ## Get Your Own Profile ### Description Fetches the profile information for the user associated with the provided API token. ### Method `client.ownProfile(): Promise` ### Returns - **Promise** - A promise that resolves to a Profile object containing user details. ### Example ```typescript async function getMyProfile() { try { const myProfile = await client.ownProfile(); console.log(`Welcome ${myProfile.name}!`); console.log(`Username: @${myProfile.slug}`); console.log(`Email: ${myProfile.email || 'Not available'}`); console.log(`Followers: ${myProfile.followerCount}`); console.log(`Bio: ${myProfile.bio || 'No bio set'}`); return myProfile; } catch (error) { console.error('Failed to get profile:', error.message); throw error; } } ``` ``` -------------------------------- ### Initialize Substack Client with Token Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Initialize the SubstackClient with your substack.sid cookie and publication URL. Includes a connectivity test. ```typescript import { SubstackClient } from 'substack-api'; // Initialize with substack.sid cookie const client = new SubstackClient({ token: 'your-connect-sid-cookie-value', publicationUrl: 'example.substack.com' // optional }); // Test connection const isConnected = await client.testConnectivity(); if (!isConnected) { throw new Error('Failed to connect to Substack API'); } ``` -------------------------------- ### Cookie-Based Authentication Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/introduction.md Provides an example of initializing the SubstackClient using a session cookie for secure authentication. ```typescript const client = new SubstackClient({ token: 'your-connect-sid-cookie-value' // Extracted from browser }); ``` -------------------------------- ### Initialize Substack Client with Environment Variables Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Load environment variables using dotenv and initialize the SubstackClient. The SUBSTACK_TOKEN is required for authentication. ```typescript // Load environment variables import dotenv from 'dotenv'; dotenv.config(); const client = new SubstackClient({ token: process.env.SUBSTACK_TOKEN!, publicationUrl: process.env.SUBSTACK_PUBLICATION_URL }); ``` -------------------------------- ### Create a Simple Note Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Use the builder pattern to create and publish a simple text-based note through your authenticated profile. Suitable for quick updates. ```typescript const myProfile = await client.ownProfile(); // Create a simple note using builder pattern const note = await myProfile.newNote().paragraph().text('šŸš€ Just shipped a new feature! Excited to share what we\'ve been working on.').publish(); console.log(`Note published: ${note.id}`); ``` -------------------------------- ### Set Up Environment Variables for Substack API Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/quickstart.md Configure your environment variables in a .env file for authentication and publication URL. Ensure these are set before running your application. ```bash # .env file SUBSTACK_TOKEN=your-connect-sid-cookie-value SUBSTACK_PUBLICATION_URL=yoursite.substack.com ``` -------------------------------- ### Run All Tests (Unit and E2E) Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Execute both unit and end-to-end test suites to ensure comprehensive code coverage and stability. ```bash npm run test:all ``` -------------------------------- ### Get Other Profiles Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/examples.md Fetches profile information for other Substack users, either by their username (slug) or by their unique ID. ```APIDOC ## Get Other Profiles ### Description Retrieves profile details for other Substack users using their unique slug or ID. ### Methods - `client.profileForSlug(slug: string): Promise` - `client.profileForId(id: number): Promise` ### Parameters #### `profileForSlug` - **slug** (string) - Required - The unique username (slug) of the profile to retrieve. #### `profileForId` - **id** (number) - Required - The unique ID of the profile to retrieve. ### Returns - **Promise** - A promise that resolves to a Profile object. ### Example ```typescript async function exploreProfiles() { try { // Get profile by username const profile = await client.profileForSlug('interesting-writer'); console.log(`Found: ${profile.name} (@${profile.slug})`); console.log(`Followers: ${profile.followerCount}`); console.log(`Following them: ${profile.isFollowing ? 'Yes' : 'No'}`); // Get profile by ID const profileById = await client.profileForId(12345); console.log(`Profile by ID: ${profileById.name}`); return { profile, profileById }; } catch (error) { console.error('Error exploring profiles:', error.message); } } ``` ``` -------------------------------- ### TypeScript Configuration Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/development.md Example of strict TypeScript configuration settings in tsconfig.json, emphasizing strict type checking and interoperability. ```json { "compilerOptions": { "strict": true, "esModuleInterop": true, "declaration": true } } ``` -------------------------------- ### Create a New Note Source: https://github.com/jakub-k-slys/substack-api/blob/main/docs/api-reference.md Use the builder pattern to create a new note. This is the recommended approach for content creation. The note is published upon completion. ```typescript // Simple note const note = await myProfile.newNote().paragraph().text('Just shipped a new feature! šŸš€').publish(); // Complex note with formatting const complexNote = await myProfile .newNote() .paragraph() .text('Building something amazing...') .paragraph() .bold('Important update: ') .text('Check out our latest release!') .publish(); console.log(`Note created: ${note.id}`); ```