{"id":29554728,"url":"https://github.com/rohittcodes/auto-crosspost","last_synced_at":"2025-09-12T18:25:44.103Z","repository":{"id":304117412,"uuid":"1017787033","full_name":"rohittcodes/auto-crosspost","owner":"rohittcodes","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-11T06:32:07.000Z","size":417,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-11T10:20:38.167Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rohittcodes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T05:20:18.000Z","updated_at":"2025-07-11T06:32:10.000Z","dependencies_parsed_at":"2025-07-11T10:23:01.980Z","dependency_job_id":"e4e492b1-1399-46c6-a8bc-924f777513f2","html_url":"https://github.com/rohittcodes/auto-crosspost","commit_stats":null,"previous_names":["rohittcodes/auto-crosspost"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rohittcodes/auto-crosspost","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohittcodes%2Fauto-crosspost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohittcodes%2Fauto-crosspost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohittcodes%2Fauto-crosspost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohittcodes%2Fauto-crosspost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rohittcodes","download_url":"https://codeload.github.com/rohittcodes/auto-crosspost/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohittcodes%2Fauto-crosspost/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265720600,"owners_count":23817269,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-18T07:31:41.601Z","updated_at":"2025-07-18T07:33:13.498Z","avatar_url":"https://github.com/rohittcodes.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Auto-CrossPost SDK\n\nA TypeScript SDK for automatically cross-posting markdown/MDX blog posts to multiple platforms including Dev.to and Hashnode.\n\n## Features\n\n- 🚀 **Multi-platform support**: Dev.to and Hashnode integration\n- 📝 **Markdown parsing**: Full frontmatter support with automatic content extraction\n- 🔄 **Retry logic**: Built-in retry mechanisms with exponential backoff\n- 🏷️ **Tag management**: Platform-specific tag validation and transformation\n- 📊 **Comprehensive logging**: Detailed logging for debugging and monitoring\n- 🎯 **TypeScript first**: Full type safety and IntelliSense support\n- 🧪 **Highly testable**: Modular architecture with dependency injection\n- 🛡️ **Error handling**: Robust error handling with custom error types\n- 📦 **Batch processing**: Process multiple posts with concurrency control\n- 👀 **File watching**: Automatically process new/changed posts\n- ⏰ **Scheduling**: Cron-based scheduling for recurring operations\n- 🎛️ **Queue management**: Advanced job queue with retry logic\n\n## Installation\n\n```bash\nnpm install auto-crosspost\n```\n\n## Quick Start\n\n### 1. Configuration\n\nCreate a configuration file `crosspost.config.json`:\n\n```json\n{\n  \"platforms\": {\n    \"devto\": {\n      \"apiKey\": \"your-devto-api-key\",\n      \"defaultTags\": [\"webdev\", \"programming\"]\n    },\n    \"hashnode\": {\n      \"token\": \"your-hashnode-token\",\n      \"publicationId\": \"your-publication-id\",\n      \"defaultTags\": [\"webdev\", \"programming\"]\n    }\n  },\n  \"defaults\": {\n    \"publishStatus\": \"published\",\n    \"tags\": [\"crosspost\"]\n  },\n  \"options\": {\n    \"logLevel\": \"info\",\n    \"retryAttempts\": 3\n  }\n}\n```\n\n### 2. Basic Usage\n\n```typescript\nimport { AutoCrossPost } from 'auto-crosspost';\nimport config from './crosspost.config.json';\n\nconst sdk = new AutoCrossPost(config);\n\n// Cross-post from a markdown file\nconst result = await sdk.crossPostFromFile('./my-blog-post.md');\n\nconsole.log(`Posted to ${result.successful} platforms successfully!`);\n```\n\n### 3. CLI Usage\n\nGenerate a configuration file:\n```bash\nnpx auto-crosspost config\n```\n\nCross-post a markdown file:\n```bash\nnpx auto-crosspost post ./my-blog-post.md\n```\n\nTest platform authentication:\n```bash\nnpx auto-crosspost test\n```\n\nList posts from a platform:\n```bash\nnpx auto-crosspost list devto --limit 5\n```\n\n### 4. GitHub Actions Integration\n\nAutomate your cross-posting with GitHub Actions. Add this workflow to `.github/workflows/crosspost.yml`:\n\n```yaml\nname: Auto CrossPost\n\non:\n  push:\n    branches: [main]\n    paths: ['posts/**/*.md']\n\njobs:\n  crosspost:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '18'\n      - run: npm install -g auto-crosspost\n      - name: Cross-post changed files\n        env:\n          DEVTO_API_KEY: ${{ secrets.DEVTO_API_KEY }}\n          HASHNODE_ACCESS_TOKEN: ${{ secrets.HASHNODE_ACCESS_TOKEN }}\n          HASHNODE_PUBLICATION_ID: ${{ secrets.HASHNODE_PUBLICATION_ID }}\n        run: |\n          echo '{\"platforms\":{\"devto\":{\"apiKey\":\"'$DEVTO_API_KEY'\"},\"hashnode\":{\"accessToken\":\"'$HASHNODE_ACCESS_TOKEN'\",\"publicationId\":\"'$HASHNODE_PUBLICATION_ID'\"}}}' \u003e config.json\n          git diff --name-only HEAD~1 HEAD -- '*.md' | xargs -I {} auto-crosspost post \"{}\" --config config.json\n```\n\nGenerate workflows with the built-in generator:\n```bash\nnpx auto-crosspost github-actions generate basic\nnpx auto-crosspost github-actions validate workflow .github/workflows/crosspost.yml\n```\n\nSee our [GitHub Actions Examples](./examples/github-actions/) for more advanced workflows.\n\n## API Reference\n\n### AutoCrossPost Class\n\n#### Constructor\n```typescript\nnew AutoCrossPost(config: CrossPostConfig, logger?: Logger)\n```\n\n#### Methods\n\n##### `crossPost(post: Post, platforms?: string[]): Promise\u003cBatchCrossPostResult\u003e`\nCross-post a post object to specified platforms.\n\n##### `crossPostFromFile(filePath: string, platforms?: string[]): Promise\u003cBatchCrossPostResult\u003e`\nCross-post from a markdown file.\n\n##### `crossPostFromContent(content: string, platforms?: string[]): Promise\u003cBatchCrossPostResult\u003e`\nCross-post from markdown content string.\n\n##### `updatePost(platformId: string, post: Post, platform: string): Promise\u003cPlatformPost\u003e`\nUpdate an existing post on a specific platform.\n\n##### `deletePost(platformId: string, platform: string): Promise\u003cboolean\u003e`\nDelete a post from a specific platform.\n\n##### `getPost(platformId: string, platform: string): Promise\u003cPlatformPost\u003e`\nRetrieve a post from a specific platform.\n\n##### `listPosts(platform: string, options?: ListOptions): Promise\u003cPlatformPost[]\u003e`\nList posts from a specific platform.\n\n##### `testAuthentication(): Promise\u003cRecord\u003cstring, boolean\u003e\u003e`\nTest authentication for all configured platforms.\n\n### Frontmatter Support\n\nThe SDK supports rich frontmatter in your markdown files:\n\n```yaml\n---\ntitle: \"My Awesome Blog Post\"\ndescription: \"A comprehensive guide to building awesome things\"\ntags: [\"javascript\", \"typescript\", \"webdev\"]\npublished: true\ndate: \"2025-01-15\"\ncanonical_url: \"https://myblog.com/awesome-post\"\ncover_image: \"https://myblog.com/images/cover.jpg\"\n\n# Platform-specific overrides\ndevto:\n  tags: [\"javascript\", \"beginners\"]\nhashnode:\n  subtitle: \"Learn the fundamentals\"\n---\n```\n\n### Error Handling\n\nThe SDK provides detailed error types for better debugging:\n\n```typescript\nimport { CrossPostError, AuthenticationError, ValidationError } from 'auto-crosspost';\n\ntry {\n  await sdk.crossPostFromFile('./post.md');\n} catch (error) {\n  if (error instanceof AuthenticationError) {\n    console.error('Authentication failed:', error.message);\n  } else if (error instanceof ValidationError) {\n    console.error('Validation error:', error.message);\n  } else if (error instanceof CrossPostError) {\n    console.error('Cross-post error:', error.message, error.platform);\n  }\n}\n```\n\n## Platform-Specific Features\n\n### Dev.to\n- REST API integration\n- Support for organization posting\n- Tag validation (max 4 tags, alphanumeric only)\n- Article analytics (views, reactions, comments)\n\n### Hashnode\n- GraphQL API integration\n- Publication support\n- Rich metadata handling\n- Advanced tag management\n\n## Advanced Usage\n\n### Custom Logger Integration\n\n```typescript\nimport winston from 'winston';\n\nconst logger = winston.createLogger({\n  level: 'info',\n  format: winston.format.json(),\n  transports: [\n    new winston.transports.File({ filename: 'crosspost.log' })\n  ]\n});\n\nconst sdk = new AutoCrossPost(config, logger);\n```\n\n### Platform-Specific Posting\n\n```typescript\n// Post only to Dev.to\nawait sdk.crossPost(post, ['devto']);\n\n// Post only to Hashnode\nawait sdk.crossPost(post, ['hashnode']);\n```\n\n### Batch Operations\n\n```typescript\nconst posts = [post1, post2, post3];\nconst results = await Promise.all(\n  posts.map(post =\u003e sdk.crossPost(post))\n);\n```\n\n## Batch Processing\n\nFor processing multiple posts at once:\n\n```typescript\nimport { BatchProcessor, BatchProgressReporter } from 'auto-crosspost';\n\n// Create batch processor\nconst processor = new BatchProcessor({\n  concurrency: 3,    // Process 3 files simultaneously\n  delay: 1000,       // Wait 1 second between requests\n  skipDrafts: true   // Skip unpublished posts\n});\n\n// Process multiple files\nconst files = ['post1.md', 'post2.md', 'post3.md'];\nconst results = await processor.processFiles(files);\n\n// Track progress\nconst reporter = new BatchProgressReporter(files.length);\nresults.forEach(result =\u003e reporter.reportProgress(result));\nreporter.printFinalReport();\n```\n\n### File Watching\n\nAutomatically process posts when files change:\n\n```typescript\nimport { FileWatcher } from 'auto-crosspost';\n\nconst watcher = new FileWatcher('./posts', {\n  ignoreInitial: false,  // Process existing files on startup\n  skipDrafts: true,      // Skip draft posts\n  concurrency: 2         // Process 2 files at once\n});\n\n// Watcher will automatically queue and process new/changed posts\nconsole.log('Watching for file changes...');\n```\n\n### Scheduling\n\nSchedule recurring batch operations:\n\n```typescript\nimport { CrossPostScheduler } from 'auto-crosspost';\n\nconst scheduler = new CrossPostScheduler({\n  batchOptions: {\n    concurrency: 2,\n    delay: 2000,\n    skipDrafts: true\n  }\n});\n\n// Schedule daily at 9:00 AM\nscheduler.scheduleDaily('09:00', './posts');\n\n// Schedule weekly on Monday at 10:00 AM\nscheduler.scheduleWeekly(1, '10:00', './posts');\n\n// Custom cron expression\nscheduler.scheduleCustom('0 */6 * * *', './posts'); // Every 6 hours\n```\n\n### Queue Management\n\nUse the job queue for complex workflows:\n\n```typescript\nimport { CrossPostQueue } from 'auto-crosspost';\n\nconst queue = new CrossPostQueue({ concurrency: 5 });\n\n// Listen for events\nqueue.on('jobCompleted', (job) =\u003e {\n  console.log(`✅ Job completed: ${job.id}`);\n});\n\nqueue.on('jobFailed', (job) =\u003e {\n  console.log(`❌ Job failed: ${job.error}`);\n});\n\n// Add jobs\nawait queue.addJob({\n  type: 'crosspost',\n  post: {\n    title: 'My Post',\n    content: 'Post content...',\n    tags: ['demo'],\n    publishStatus: 'published'\n  }\n});\n\n// Monitor status\nconst status = queue.getStatus();\nconsole.log(`Processing: ${status.processingJobs}, Pending: ${status.pendingJobs}`);\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature-name`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin feature-name`\n5. Submit a pull request\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build the project\nnpm run build\n\n# Run tests\nnpm test\n\n# Run linting\nnpm run lint\n```\n\n## API Keys Setup\n\n### Dev.to API Key\n1. Go to [Dev.to Settings](https://dev.to/settings/extensions)\n2. Generate a new API key\n3. Add it to your configuration file\n\n### Hashnode Token\n1. Go to [Hashnode Settings](https://hashnode.com/settings/developer)\n2. Generate a personal access token\n3. Find your publication ID from your publication's settings\n4. Add both to your configuration file\n\n## License\n\nMIT\n\n## Support\n\nFor issues and questions:\n- GitHub Issues: [Create an issue](https://github.com/rohittcodes/auto-crosspost/issues)\n- Documentation: [Full documentation](https://github.com/rohittcodes/auto-crosspost/wiki)\n\n---\n\nMade with ❤️ for the developer community\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohittcodes%2Fauto-crosspost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frohittcodes%2Fauto-crosspost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohittcodes%2Fauto-crosspost/lists"}