@bernierllc/content-type-tweet
v1.2.0
Published
Tweet content type with 280-character validation, Twitter API publishing, thread support, and media attachments
Readme
@bernierllc/content-type-tweet
Tweet content type extending @bernierllc/content-type-text with 280-character validation, Twitter-aware text processing, thread support, media attachments, and Twitter API v2 publishing.
Installation
npm install @bernierllc/content-type-tweetFeatures
- 280-character validation using Twitter's official text parsing library
- Entity extraction - Automatic extraction of hashtags, mentions, and URLs
- Thread support - Create and publish multi-tweet threads
- Media attachments - Support for images, GIFs, and videos (up to 4)
- Poll support - Create tweets with polls (2-4 options)
- Twitter API v2 integration - Publish tweets directly to Twitter
- Scheduled tweets - Schedule tweets for future publishing
- Quote tweets - Quote existing tweets
- Reply support - Reply to tweets
Usage
Basic Tweet Creation
import { TweetContentType } from '@bernierllc/content-type-tweet';
const tweetType = new TweetContentType({
storage: {
type: 'file',
directory: './content/tweets',
},
twitter: {
appKey: process.env.TWITTER_APP_KEY!,
appSecret: process.env.TWITTER_APP_SECRET!,
accessToken: process.env.TWITTER_ACCESS_TOKEN,
accessSecret: process.env.TWITTER_ACCESS_SECRET,
authType: 'oauth1',
},
});
// Create a tweet
const result = await tweetType.createTweet({
content: 'Hello world! #TypeScript @bernierllc',
});
if (result.success) {
console.log(`Tweet created: ${result.data}`);
}Tweet Validation
// Validate tweet content before creating
const validation = tweetType.validateTweet('This is a test tweet!');
if (validation.data?.valid) {
console.log(`Valid tweet (${validation.data.characterCount}/280 characters)`);
} else {
console.log('Tweet exceeds character limit');
}Publishing Tweets
// Create and publish a tweet
const createResult = await tweetType.createTweet({
content: 'Hello from @bernierllc/content-type-tweet!',
});
if (createResult.success) {
const publishResult = await tweetType.publishTweet(createResult.data!);
if (publishResult.success) {
console.log(`Published: ${publishResult.tweetUrl}`);
}
}Tweet Threads
import { createThread } from '@bernierllc/content-type-tweet';
// Create a thread from multiple tweets
const thread = createThread([
'This is the first tweet in a thread.',
'This is the second tweet.',
'And this is the third tweet!',
]);
if (thread.success) {
// Publish the entire thread
const result = await tweetType.publishThread(thread.data!);
console.log(`Thread published: ${result.success}`);
}Media Attachments
// Create a tweet with media
const result = await tweetType.createTweet({
content: 'Check out these amazing photos! 📸',
media: [
{
type: 'image',
url: 'https://example.com/photo1.jpg',
altText: 'Beautiful sunset',
},
{
type: 'image',
url: 'https://example.com/photo2.jpg',
altText: 'Mountain landscape',
},
],
});Polls
// Create a tweet with a poll
const result = await tweetType.createTweet({
content: 'What is your favorite programming language?',
poll: {
options: ['TypeScript', 'JavaScript', 'Python', 'Go'],
durationMinutes: 1440, // 24 hours
},
});Scheduled Tweets
// Schedule a tweet for later
const createResult = await tweetType.createTweet({
content: 'This will be posted tomorrow!',
});
if (createResult.success) {
const tomorrow = new Date(Date.now() + 24 * 60 * 60 * 1000);
await tweetType.scheduleTweet(createResult.data!, tomorrow);
}API Reference
TweetContentType
Main class for managing tweet content.
Methods
createTweet(data: Partial<TweetContentMetadata>): Promise<TweetContentResult<string>>- Create a new tweetreadTweet(filePath: string): Promise<TweetContentResult<TweetContentMetadata>>- Read tweet from fileupdateTweet(filePath: string, data: Partial<TweetContentMetadata>): Promise<TweetContentResult<void>>- Update tweetdeleteTweet(filePath: string): Promise<TweetContentResult<void>>- Delete tweetpublishTweet(filePath: string): Promise<TweetPublishResult>- Publish tweet to TwitterpublishThread(thread: TweetThread): Promise<TweetContentResult<TweetPublishResult[]>>- Publish threadscheduleTweet(filePath: string, scheduledFor: Date): Promise<TweetContentResult<void>>- Schedule tweetvalidateTweet(content: string): TweetContentResult<{ valid: boolean; characterCount: number }>- Validate tweetregister(registry: ContentTypeRegistry): Promise<TweetContentResult<void>>- Register with content type registry
Validation Functions
validateTweetContent(content: string): TweetContentResult<TweetValidationResult>- Validate tweet using Twitter's parserextractHashtags(content: string): string[]- Extract hashtags from contentextractMentions(content: string): string[]- Extract mentions from contentextractUrls(content: string): string[]- Extract URLs from contentextractEntities(content: string)- Extract all entities (hashtags, mentions, URLs)isTweetValid(content: string): boolean- Check if tweet is validgetCharacterCount(content: string): number- Get weighted character count
Thread Functions
createThread(tweets: string[], threadId?: string): TweetContentResult<TweetThread>- Create thread from tweet arrayvalidateThread(thread: TweetThread): TweetContentResult<boolean>- Validate threadsplitIntoThread(text: string, maxLength?: number): TweetContentResult<string[]>- Split long text into thread
Configuration
Environment Variables
# Twitter API Configuration (required for publishing)
TWITTER_APP_KEY=your_app_key
TWITTER_APP_SECRET=your_app_secret
# OAuth 1.0a (for user authentication)
TWITTER_ACCESS_TOKEN=your_access_token
TWITTER_ACCESS_SECRET=your_access_secret
# OAuth 2.0 (alternative)
TWITTER_CLIENT_ID=your_client_id
TWITTER_CLIENT_SECRET=your_client_secret
# Bearer Token (for app-only authentication)
TWITTER_BEARER_TOKEN=your_bearer_token
# Authentication Type
TWITTER_AUTH_TYPE=oauth1 # oauth1 | oauth2
# Tweet Content Configuration (optional)
TWEET_STORAGE_DIR=./content/tweets # Default tweet storage directory
TWEET_STORAGE_TYPE=file # file | databaseIntegration Status
- Logger: not-applicable - Core content type package
- Docs-Suite: ready - TypeDoc format, complete API documentation
- NeverHub: optional - Tweet publishing events
Dependencies
- @bernierllc/content-type-registry ^1.0.3 - Content type registration
- @bernierllc/content-type-text ^1.0.1 - Base text content type
- zod - Runtime schema validation
- twitter-api-v2 - Twitter API v2 client
- twitter-text - Official Twitter text parser
- gray-matter - Frontmatter parsing
Dependent Packages
- @bernierllc/content-editor-service - Content editing orchestration
- @bernierllc/social-publisher - Multi-platform social publishing
- @bernierllc/content-management-suite - Complete content management ecosystem
License
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
See Also
- @bernierllc/content-type-text - Base text content type
- @bernierllc/content-type-registry - Content type registration
- @bernierllc/content-type-blog-post - Blog post content type
- @bernierllc/content-management-suite - Content management suite
