npm package: @jboltle/plugin-linkedin
Description: LinkedIn plugin for ElizaOS that enables agents to post content on LinkedIn.
Latest version: 1.0.2

# @elizaos/plugin-linkedin

LinkedIn plugin for ElizaOS that enables agents to post content on LinkedIn.

## Features

- **LinkedIn Posting**: Create and publish posts to LinkedIn feed
- **Personal & Organization Posting**: Support for both personal profiles and organization pages
- **Media Upload**: Upload and attach images, videos, and documents to posts
- **Content Validation**: Validate post content against LinkedIn's guidelines
- **Rate Limiting**: Built-in rate limiting to respect LinkedIn API limits
- **Retry Logic**: Automatic retry with exponential backoff for failed requests
- **Mentions & Hashtags**: Support for LinkedIn mentions and hashtags
- **Event System**: Emit events for post creation, success, and failure

## Installation

```bash
bun add @elizaos/plugin-linkedin
```

## Configuration

### Environment Variables

Add these environment variables to your `.env` file:

```bash
# Required: LinkedIn API Access Token
LINKEDIN_ACCESS_TOKEN=your_access_token_here

# Required: Either person or organization URN (or both)
LINKEDIN_PERSON_URN=urn:li:person:your_person_id
LINKEDIN_ORGANIZATION_URN=urn:li:organization:your_org_id

# Optional: Configuration settings
LINKEDIN_API_VERSION=202406
LINKEDIN_POST_INTERVAL_MIN=120
LINKEDIN_POST_INTERVAL_MAX=360
LINKEDIN_ENABLE_MENTIONS=true
LINKEDIN_ENABLE_HASHTAGS=true
LINKEDIN_ENABLE_ORGANIZATION_POSTING=false
LINKEDIN_TARGET_AUDIENCE=PUBLIC
```

### LinkedIn API Setup

1. **Create a LinkedIn App**:
   - Go to [LinkedIn Developer Portal](https://developer.linkedin.com/)
   - Create a new app
   - Request the following permissions:
     - `w_member_social` (for personal posting)
     - `w_organization_social` (for organization posting)
     - `r_organization_social` (to read organization details)

2. **Get Access Token**:
   - Use OAuth 2.0 flow to get an access token
   - For development, you can use LinkedIn's token generator
   - Store the token in `LINKEDIN_ACCESS_TOKEN`

3. **Get URNs**:
   - **Person URN**: `urn:li:person:{your_linkedin_id}`
   - **Organization URN**: `urn:li:organization:{organization_id}`
   - You can find these using LinkedIn's API or developer tools

## Usage

### Basic Setup

```typescript
import { LinkedInService } from '@elizaos/plugin-linkedin';

// The plugin will automatically start when the runtime initializes
// Make sure your environment variables are configured
```

### Plugin Configuration

Add the LinkedIn plugin to your ElizaOS character configuration:

```json
{
  "name": "MyAgent",
  "plugins": ["@elizaos/plugin-linkedin"],
  "settings": {
    "LINKEDIN_ACCESS_TOKEN": "your_token_here",
    "LINKEDIN_PERSON_URN": "urn:li:person:12345",
    "POST_BEHAVIOR": "auto"
  }
}
```

### Posting Behavior

The plugin supports different posting behaviors controlled by the `POST_BEHAVIOR` setting:

- `auto`: Posts are automatically published to LinkedIn
- `approval`: Posts are saved for manual approval
- `disabled`: No posts are generated

### Content Features

#### Mentions
Use LinkedIn mention format in your posts:
```
Hello @[John Doe](urn:li:person:12345)! Great to connect with you.
```

#### Hashtags
Add hashtags to increase discoverability:
```
Excited to share our latest #AI #innovation #technology
```

#### Media
The plugin supports uploading:
- Images (JPG, PNG, GIF)
- Videos (MP4, MOV)
- Documents (PDF, DOC, DOCX, PPT, PPTX)

## API Reference

### LinkedInClientBase

Main client for LinkedIn API operations.

```typescript
class LinkedInClientBase {
  async init(): Promise<void>
  async getProfile(): Promise<LinkedInProfile | null>
  async getOrganization(urn: string): Promise<LinkedInOrganization | null>
  async createPost(postData: LinkedInPostRequest): Promise<LinkedInPostResponse>
  async uploadMedia(buffer: Buffer, filename: string): Promise<string>
  validatePost(text: string): { valid: boolean; errors: string[] }
}
```

### LinkedInPostClient

Handles automatic post generation and publishing.

```typescript
class LinkedInPostClient {
  async start(): Promise<void>
  async stop(): Promise<void>
  async generateNewPost(): Promise<void>
}
```

### Utility Functions

```typescript
// Format post content
formatLinkedInPost(text: string, options?: FormatOptions): string

// Extract mentions and hashtags
extractLinkedInMentions(text: string): Array<{ name: string; urn: string }>
extractLinkedInHashtags(text: string): string[]

// Validate URNs
validateLinkedInUrn(urn: string, type?: 'person' | 'organization'): boolean

// Content validation
validateLinkedInPostContent(content: string): ValidationResult
```

## Events

The plugin emits the following events:

- `linkedin:post:generated` - When a new post is generated
- `linkedin:post:created` - When a post is successfully created
- `linkedin:post:failed` - When post creation fails
- `linkedin:media:uploaded` - When media is uploaded
- `linkedin:world:joined` - When client connects to LinkedIn

## Rate Limits

The plugin respects LinkedIn's rate limits:

- **Posts**: 100 per day, 25 per hour, 5 per minute
- **Media Uploads**: 500 per day, 100 per hour

Built-in rate limiting prevents exceeding these limits.

## Error Handling

The plugin includes comprehensive error handling:

- **Retry Logic**: Automatic retry for transient errors
- **Rate Limit Handling**: Automatic backoff when rate limited
- **Validation**: Pre-validate content before posting
- **Graceful Degradation**: Continue operation even if some features fail

## Content Guidelines

LinkedIn has specific content policies. The plugin helps enforce:

- **Character Limits**: Maximum 3,000 characters per post
- **Hashtag Limits**: Maximum 5 hashtags per post
- **Mention Limits**: Maximum 5 mentions per post
- **Media Limits**: Maximum 9 media files per post

## Troubleshooting

### Common Issues

1. **Authentication Failed**
   - Check your `LINKEDIN_ACCESS_TOKEN`
   - Ensure token has required permissions
   - Verify token hasn't expired

2. **Invalid URN**
   - Check format: `urn:li:person:12345` or `urn:li:organization:67890`
   - Ensure URN matches your LinkedIn account

3. **Rate Limited**
   - Plugin will automatically retry after rate limit window
   - Consider reducing posting frequency

4. **Content Validation Failed**
   - Check post length (max 3,000 characters)
   - Verify hashtag and mention limits
   - Ensure mentions use correct URN format

### Debug Mode

Enable debug logging to troubleshoot issues:

```bash
LOG_LEVEL=debug bun start
```

## Contributing

Contributions are welcome! Please see the main ElizaOS repository for contribution guidelines.

## License

MIT License - see the main ElizaOS repository for details.