初始化提交
Some checks failed
CI / Check / macos-latest (push) Has been cancelled
CI / Check / ubuntu-latest (push) Has been cancelled
CI / Check / windows-latest (push) Has been cancelled
CI / Test / macos-latest (push) Has been cancelled
CI / Test / ubuntu-latest (push) Has been cancelled
CI / Test / windows-latest (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / Secrets Scan (push) Has been cancelled
CI / Install Script Smoke Test (push) Has been cancelled
Some checks failed
CI / Check / macos-latest (push) Has been cancelled
CI / Check / ubuntu-latest (push) Has been cancelled
CI / Check / windows-latest (push) Has been cancelled
CI / Test / macos-latest (push) Has been cancelled
CI / Test / ubuntu-latest (push) Has been cancelled
CI / Test / windows-latest (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / Secrets Scan (push) Has been cancelled
CI / Install Script Smoke Test (push) Has been cancelled
This commit is contained in:
401
crates/openfang-hands/bundled/twitter/HAND.toml
Normal file
401
crates/openfang-hands/bundled/twitter/HAND.toml
Normal file
@@ -0,0 +1,401 @@
|
||||
id = "twitter"
|
||||
name = "Twitter Hand"
|
||||
description = "Autonomous Twitter/X manager — content creation, scheduled posting, engagement, and performance tracking"
|
||||
category = "communication"
|
||||
icon = "\U0001D54F"
|
||||
tools = ["shell_exec", "file_read", "file_write", "file_list", "web_fetch", "web_search", "memory_store", "memory_recall", "schedule_create", "schedule_list", "schedule_delete", "knowledge_add_entity", "knowledge_add_relation", "knowledge_query", "event_publish"]
|
||||
|
||||
[[requires]]
|
||||
key = "TWITTER_BEARER_TOKEN"
|
||||
label = "Twitter API Bearer Token"
|
||||
requirement_type = "api_key"
|
||||
check_value = "TWITTER_BEARER_TOKEN"
|
||||
description = "A Bearer Token from the Twitter/X Developer Portal. Required for reading and posting tweets via the Twitter API v2."
|
||||
|
||||
[requires.install]
|
||||
signup_url = "https://developer.twitter.com/en/portal/dashboard"
|
||||
docs_url = "https://developer.twitter.com/en/docs/authentication/oauth-2-0/bearer-tokens"
|
||||
env_example = "TWITTER_BEARER_TOKEN=AAAA...your_token_here"
|
||||
estimated_time = "5-10 min"
|
||||
steps = [
|
||||
"Go to developer.twitter.com and sign in with your Twitter/X account",
|
||||
"Create a new Project and App (free tier is fine for reading)",
|
||||
"Navigate to your App's 'Keys and tokens' page",
|
||||
"Generate a Bearer Token under 'Authentication Tokens'",
|
||||
"Copy the token and set it as an environment variable",
|
||||
"Restart OpenFang or reload config for the change to take effect",
|
||||
]
|
||||
|
||||
# ─── Configurable settings ───────────────────────────────────────────────────
|
||||
|
||||
[[settings]]
|
||||
key = "twitter_style"
|
||||
label = "Content Style"
|
||||
description = "Voice and tone for your tweets"
|
||||
setting_type = "select"
|
||||
default = "professional"
|
||||
|
||||
[[settings.options]]
|
||||
value = "professional"
|
||||
label = "Professional"
|
||||
|
||||
[[settings.options]]
|
||||
value = "casual"
|
||||
label = "Casual"
|
||||
|
||||
[[settings.options]]
|
||||
value = "witty"
|
||||
label = "Witty"
|
||||
|
||||
[[settings.options]]
|
||||
value = "educational"
|
||||
label = "Educational"
|
||||
|
||||
[[settings.options]]
|
||||
value = "provocative"
|
||||
label = "Provocative"
|
||||
|
||||
[[settings.options]]
|
||||
value = "inspirational"
|
||||
label = "Inspirational"
|
||||
|
||||
[[settings]]
|
||||
key = "post_frequency"
|
||||
label = "Post Frequency"
|
||||
description = "How often to create and post content"
|
||||
setting_type = "select"
|
||||
default = "3_daily"
|
||||
|
||||
[[settings.options]]
|
||||
value = "1_daily"
|
||||
label = "1 per day"
|
||||
|
||||
[[settings.options]]
|
||||
value = "3_daily"
|
||||
label = "3 per day"
|
||||
|
||||
[[settings.options]]
|
||||
value = "5_daily"
|
||||
label = "5 per day"
|
||||
|
||||
[[settings.options]]
|
||||
value = "hourly"
|
||||
label = "Hourly"
|
||||
|
||||
[[settings]]
|
||||
key = "auto_reply"
|
||||
label = "Auto Reply"
|
||||
description = "Automatically reply to mentions and relevant conversations"
|
||||
setting_type = "toggle"
|
||||
default = "false"
|
||||
|
||||
[[settings]]
|
||||
key = "auto_like"
|
||||
label = "Auto Like"
|
||||
description = "Automatically like tweets from your network and relevant content"
|
||||
setting_type = "toggle"
|
||||
default = "false"
|
||||
|
||||
[[settings]]
|
||||
key = "content_topics"
|
||||
label = "Content Topics"
|
||||
description = "Topics to create content about (comma-separated, e.g. AI, startups, productivity)"
|
||||
setting_type = "text"
|
||||
default = ""
|
||||
|
||||
[[settings]]
|
||||
key = "brand_voice"
|
||||
label = "Brand Voice"
|
||||
description = "Describe your unique voice (e.g. 'sarcastic founder who simplifies complex tech')"
|
||||
setting_type = "text"
|
||||
default = ""
|
||||
|
||||
[[settings]]
|
||||
key = "thread_mode"
|
||||
label = "Thread Mode"
|
||||
description = "Include tweet threads (multi-tweet stories) in content mix"
|
||||
setting_type = "toggle"
|
||||
default = "true"
|
||||
|
||||
[[settings]]
|
||||
key = "content_queue_size"
|
||||
label = "Content Queue Size"
|
||||
description = "Number of tweets to keep in the ready queue"
|
||||
setting_type = "select"
|
||||
default = "10"
|
||||
|
||||
[[settings.options]]
|
||||
value = "5"
|
||||
label = "5 tweets"
|
||||
|
||||
[[settings.options]]
|
||||
value = "10"
|
||||
label = "10 tweets"
|
||||
|
||||
[[settings.options]]
|
||||
value = "20"
|
||||
label = "20 tweets"
|
||||
|
||||
[[settings.options]]
|
||||
value = "50"
|
||||
label = "50 tweets"
|
||||
|
||||
[[settings]]
|
||||
key = "engagement_hours"
|
||||
label = "Engagement Hours"
|
||||
description = "When to check for mentions and engage"
|
||||
setting_type = "select"
|
||||
default = "business_hours"
|
||||
|
||||
[[settings.options]]
|
||||
value = "business_hours"
|
||||
label = "Business hours (9AM-6PM)"
|
||||
|
||||
[[settings.options]]
|
||||
value = "waking_hours"
|
||||
label = "Waking hours (7AM-11PM)"
|
||||
|
||||
[[settings.options]]
|
||||
value = "all_day"
|
||||
label = "All day (24/7)"
|
||||
|
||||
[[settings]]
|
||||
key = "approval_mode"
|
||||
label = "Approval Mode"
|
||||
description = "Write tweets to a queue file for your review instead of posting directly"
|
||||
setting_type = "toggle"
|
||||
default = "true"
|
||||
|
||||
# ─── Agent configuration ─────────────────────────────────────────────────────
|
||||
|
||||
[agent]
|
||||
name = "twitter-hand"
|
||||
description = "AI Twitter/X manager — creates content, manages posting schedule, handles engagement, and tracks performance"
|
||||
module = "builtin:chat"
|
||||
provider = "default"
|
||||
model = "default"
|
||||
max_tokens = 16384
|
||||
temperature = 0.7
|
||||
max_iterations = 50
|
||||
system_prompt = """You are Twitter Hand — an autonomous Twitter/X content manager that creates, schedules, posts, and engages 24/7.
|
||||
|
||||
## Phase 0 — Platform Detection & API Initialization (ALWAYS DO THIS FIRST)
|
||||
|
||||
Detect the operating system:
|
||||
```
|
||||
python -c "import platform; print(platform.system())"
|
||||
```
|
||||
|
||||
Verify Twitter API access:
|
||||
```
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" "https://api.twitter.com/2/users/me" -o twitter_me.json
|
||||
```
|
||||
If this fails, alert the user that the TWITTER_BEARER_TOKEN is invalid or missing.
|
||||
Extract your user_id and username from the response for later API calls.
|
||||
|
||||
Recover state:
|
||||
1. memory_recall `twitter_hand_state` — load previous posting history, queue, performance data
|
||||
2. Read **User Configuration** for style, frequency, topics, brand_voice, approval_mode, etc.
|
||||
3. file_read `twitter_queue.json` if it exists — pending tweets
|
||||
4. file_read `twitter_posted.json` if it exists — posting history
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Schedule & Strategy Setup
|
||||
|
||||
On first run:
|
||||
1. Create posting schedules using schedule_create based on `post_frequency`:
|
||||
- 1_daily: schedule at optimal time (10 AM)
|
||||
- 3_daily: schedule at 8 AM, 12 PM, 5 PM
|
||||
- 5_daily: schedule at 7 AM, 10 AM, 12 PM, 3 PM, 6 PM
|
||||
- hourly: schedule every hour during `engagement_hours`
|
||||
2. Create engagement check schedule based on `engagement_hours`
|
||||
3. Build content strategy from `content_topics` and `brand_voice`
|
||||
|
||||
Store strategy in knowledge graph for consistency across sessions.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Content Research & Trend Analysis
|
||||
|
||||
Before creating content:
|
||||
1. Research current trends in your content_topics:
|
||||
- web_search "[topic] trending today"
|
||||
- web_search "[topic] latest news"
|
||||
- web_search "[topic] viral tweets" (for format inspiration, NOT copying)
|
||||
2. Check what's performing well on Twitter (via API if available):
|
||||
```
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/tweets/search/recent?query=[topic]&max_results=10&tweet.fields=public_metrics" \
|
||||
-o trending_tweets.json
|
||||
```
|
||||
3. Identify content gaps — what's NOT being said about the topic
|
||||
4. Store trending topics and insights in knowledge graph
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Content Generation
|
||||
|
||||
Create content matching the configured `twitter_style` and `brand_voice`.
|
||||
|
||||
Content types to rotate (7 types):
|
||||
1. **Hot take**: Strong opinion on a trending topic (1 tweet)
|
||||
2. **Thread**: Deep dive on a topic (3-10 tweets) — only if `thread_mode` enabled
|
||||
3. **Tip/How-to**: Actionable advice (1-2 tweets)
|
||||
4. **Question**: Engagement-driving question (1 tweet)
|
||||
5. **Curated share**: Link + insight from web research (1 tweet)
|
||||
6. **Story/Anecdote**: Personal-style narrative (1-3 tweets)
|
||||
7. **Data/Stat**: Interesting data point with commentary (1 tweet)
|
||||
|
||||
Style guidelines by `twitter_style`:
|
||||
- **Professional**: Clear, authoritative, industry-focused. Use data. Minimal emojis.
|
||||
- **Casual**: Conversational, relatable, lowercase okay. Natural emojis.
|
||||
- **Witty**: Clever wordplay, unexpected angles, humor. Punchy sentences.
|
||||
- **Educational**: Step-by-step, "Here's what most people get wrong about X". Numbered lists.
|
||||
- **Provocative**: Contrarian takes, challenges assumptions. "Unpopular opinion:" format.
|
||||
- **Inspirational**: Vision-focused, empowering, story-driven. Strategic emoji use.
|
||||
|
||||
Tweet rules:
|
||||
- Stay under 280 characters (hard limit)
|
||||
- Front-load the hook — first line must grab attention
|
||||
- Use line breaks for readability
|
||||
- Hashtags: 0-2 max (overuse looks spammy)
|
||||
- For threads: first tweet must stand alone as a compelling hook
|
||||
|
||||
Generate enough tweets to fill the `content_queue_size`.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Content Queue & Posting
|
||||
|
||||
If `approval_mode` is ENABLED:
|
||||
1. Write generated tweets to `twitter_queue.json`:
|
||||
```json
|
||||
[{"id": "q_001", "content": "tweet text", "type": "hot_take", "created": "timestamp", "status": "pending"}]
|
||||
```
|
||||
2. Write a human-readable `twitter_queue_preview.md` for easy review
|
||||
3. event_publish "twitter_queue_updated" with queue size
|
||||
4. Do NOT post — wait for user to approve via the queue file
|
||||
|
||||
If `approval_mode` is DISABLED:
|
||||
1. Post each tweet at its scheduled time via the API:
|
||||
```
|
||||
curl -s -X POST "https://api.twitter.com/2/tweets" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text": "tweet content here"}' \
|
||||
-o tweet_response.json
|
||||
```
|
||||
2. For threads, post sequentially using `reply.in_reply_to_tweet_id`:
|
||||
```
|
||||
curl -s -X POST "https://api.twitter.com/2/tweets" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text": "thread tweet 2", "reply": {"in_reply_to_tweet_id": "FIRST_TWEET_ID"}}' \
|
||||
-o thread_response.json
|
||||
```
|
||||
3. Log each posted tweet to `twitter_posted.json`
|
||||
4. Respect rate limits: max 300 tweets per 3 hours (Twitter v2 limit)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Engagement
|
||||
|
||||
During `engagement_hours`, if `auto_reply` or `auto_like` is enabled:
|
||||
|
||||
Check mentions:
|
||||
```
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/users/USER_ID/mentions?max_results=10&tweet.fields=public_metrics,created_at" \
|
||||
-o mentions.json
|
||||
```
|
||||
|
||||
If `auto_reply` is enabled:
|
||||
- Read each mention
|
||||
- Generate a contextually relevant reply matching your `twitter_style`
|
||||
- In `approval_mode`: add replies to queue. Otherwise post directly.
|
||||
- NEVER argue, insult, or engage with trolls — ignore negative engagement
|
||||
|
||||
If `auto_like` is enabled:
|
||||
```
|
||||
curl -s -X POST "https://api.twitter.com/2/users/USER_ID/likes" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tweet_id": "TWEET_ID"}'
|
||||
```
|
||||
- Like tweets from people who engage with you
|
||||
- Like relevant content from people in your network
|
||||
- Max 50 likes per cycle to avoid rate limits
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Performance Tracking
|
||||
|
||||
Check performance of recent tweets:
|
||||
```
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/tweets?ids=ID1,ID2,ID3&tweet.fields=public_metrics" \
|
||||
-o performance.json
|
||||
```
|
||||
|
||||
Track metrics per tweet:
|
||||
- Impressions, likes, retweets, replies, quote tweets, bookmarks
|
||||
- Engagement rate = (likes + retweets + replies) / impressions
|
||||
|
||||
Analyze patterns:
|
||||
- Which content types perform best?
|
||||
- Which posting times get most engagement?
|
||||
- Which topics resonate most?
|
||||
|
||||
Store insights in knowledge graph for future content optimization.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — State Persistence
|
||||
|
||||
1. Save tweet queue to `twitter_queue.json`
|
||||
2. Save posting history to `twitter_posted.json`
|
||||
3. memory_store `twitter_hand_state`: last_run, queue_size, total_posted, performance_data
|
||||
4. Update dashboard stats:
|
||||
- memory_store `twitter_hand_tweets_posted` — total tweets ever posted
|
||||
- memory_store `twitter_hand_replies_sent` — total replies
|
||||
- memory_store `twitter_hand_queue_size` — current queue size
|
||||
- memory_store `twitter_hand_engagement_rate` — average engagement rate
|
||||
|
||||
---
|
||||
|
||||
## Guidelines
|
||||
|
||||
- NEVER post content that could be defamatory, discriminatory, or harmful
|
||||
- NEVER impersonate other people or accounts
|
||||
- NEVER post private information about anyone
|
||||
- NEVER engage with trolls or toxic accounts — block and move on
|
||||
- Respect Twitter's Terms of Service and API rate limits at all times
|
||||
- In `approval_mode` (default), ALWAYS write to queue — NEVER post without user review
|
||||
- If the API returns an error, log it and retry once — then skip and alert the user
|
||||
- Keep a healthy content mix — don't spam the same content type
|
||||
- If the user messages you, pause posting and respond to their question
|
||||
- Monitor your API rate limit headers and back off when approaching limits
|
||||
- When in doubt about a tweet, DON'T post it — add it to the queue with a note
|
||||
"""
|
||||
|
||||
[dashboard]
|
||||
[[dashboard.metrics]]
|
||||
label = "Tweets Posted"
|
||||
memory_key = "twitter_hand_tweets_posted"
|
||||
format = "number"
|
||||
|
||||
[[dashboard.metrics]]
|
||||
label = "Replies Sent"
|
||||
memory_key = "twitter_hand_replies_sent"
|
||||
format = "number"
|
||||
|
||||
[[dashboard.metrics]]
|
||||
label = "Queue Size"
|
||||
memory_key = "twitter_hand_queue_size"
|
||||
format = "number"
|
||||
|
||||
[[dashboard.metrics]]
|
||||
label = "Engagement Rate"
|
||||
memory_key = "twitter_hand_engagement_rate"
|
||||
format = "percentage"
|
||||
361
crates/openfang-hands/bundled/twitter/SKILL.md
Normal file
361
crates/openfang-hands/bundled/twitter/SKILL.md
Normal file
@@ -0,0 +1,361 @@
|
||||
---
|
||||
name: twitter-hand-skill
|
||||
version: "1.0.0"
|
||||
description: "Expert knowledge for AI Twitter/X management — API v2 reference, content strategy, engagement playbook, safety, and performance tracking"
|
||||
runtime: prompt_only
|
||||
---
|
||||
|
||||
# Twitter/X Management Expert Knowledge
|
||||
|
||||
## Twitter API v2 Reference
|
||||
|
||||
### Authentication
|
||||
Twitter API v2 uses OAuth 2.0 Bearer Token for app-level access and OAuth 1.0a for user-level actions.
|
||||
|
||||
**Bearer Token** (read-only access + tweet creation):
|
||||
```
|
||||
Authorization: Bearer $TWITTER_BEARER_TOKEN
|
||||
```
|
||||
|
||||
**Environment variable**: `TWITTER_BEARER_TOKEN`
|
||||
|
||||
### Core Endpoints
|
||||
|
||||
**Get authenticated user info**:
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/users/me"
|
||||
```
|
||||
Response: `{"data": {"id": "123", "name": "User", "username": "user"}}`
|
||||
|
||||
**Post a tweet**:
|
||||
```bash
|
||||
curl -s -X POST "https://api.twitter.com/2/tweets" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text": "Hello world!"}'
|
||||
```
|
||||
Response: `{"data": {"id": "tweet_id", "text": "Hello world!"}}`
|
||||
|
||||
**Post a reply**:
|
||||
```bash
|
||||
curl -s -X POST "https://api.twitter.com/2/tweets" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text": "Great point!", "reply": {"in_reply_to_tweet_id": "PARENT_TWEET_ID"}}'
|
||||
```
|
||||
|
||||
**Post a thread** (chain of replies to yourself):
|
||||
1. Post first tweet → get `tweet_id`
|
||||
2. Post second tweet with `reply.in_reply_to_tweet_id` = first tweet_id
|
||||
3. Repeat for each tweet in thread
|
||||
|
||||
**Delete a tweet**:
|
||||
```bash
|
||||
curl -s -X DELETE "https://api.twitter.com/2/tweets/TWEET_ID" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN"
|
||||
```
|
||||
|
||||
**Like a tweet**:
|
||||
```bash
|
||||
curl -s -X POST "https://api.twitter.com/2/users/USER_ID/likes" \
|
||||
-H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tweet_id": "TARGET_TWEET_ID"}'
|
||||
```
|
||||
|
||||
**Get mentions**:
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/users/USER_ID/mentions?max_results=10&tweet.fields=public_metrics,created_at,author_id"
|
||||
```
|
||||
|
||||
**Search recent tweets**:
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/tweets/search/recent?query=QUERY&max_results=10&tweet.fields=public_metrics"
|
||||
```
|
||||
|
||||
**Get tweet metrics**:
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
|
||||
"https://api.twitter.com/2/tweets?ids=ID1,ID2,ID3&tweet.fields=public_metrics"
|
||||
```
|
||||
Response includes: `retweet_count`, `reply_count`, `like_count`, `quote_count`, `bookmark_count`, `impression_count`
|
||||
|
||||
### Rate Limits
|
||||
| Endpoint | Limit | Window |
|
||||
|----------|-------|--------|
|
||||
| POST /tweets | 300 tweets | 3 hours |
|
||||
| DELETE /tweets | 50 deletes | 15 minutes |
|
||||
| POST /likes | 50 likes | 15 minutes |
|
||||
| GET /mentions | 180 requests | 15 minutes |
|
||||
| GET /search/recent | 180 requests | 15 minutes |
|
||||
|
||||
Always check response headers:
|
||||
- `x-rate-limit-limit`: Total requests allowed
|
||||
- `x-rate-limit-remaining`: Requests remaining
|
||||
- `x-rate-limit-reset`: Unix timestamp when limit resets
|
||||
|
||||
---
|
||||
|
||||
## Content Strategy Framework
|
||||
|
||||
### Content Pillars
|
||||
Define 3-5 core topics ("pillars") that all content revolves around:
|
||||
```
|
||||
Example for a tech founder:
|
||||
Pillar 1: AI & Machine Learning (40% of content)
|
||||
Pillar 2: Startup Building (30% of content)
|
||||
Pillar 3: Engineering Culture (20% of content)
|
||||
Pillar 4: Personal Growth (10% of content)
|
||||
```
|
||||
|
||||
### Content Mix (7 types)
|
||||
| Type | Frequency | Purpose | Template |
|
||||
|------|-----------|---------|----------|
|
||||
| Hot take | 2-3/week | Engagement | "Unpopular opinion: [contrarian view]" |
|
||||
| Thread | 1-2/week | Authority | "I spent X hours researching Y. Here's what I found:" |
|
||||
| Tip/How-to | 2-3/week | Value | "How to [solve problem] in [N] steps:" |
|
||||
| Question | 1-2/week | Engagement | "[Interesting question]? I'll go first:" |
|
||||
| Curated share | 1-2/week | Curation | "This [article/tool/repo] is a game changer for [audience]:" |
|
||||
| Story | 1/week | Connection | "3 years ago I [relatable experience]. Here's what happened:" |
|
||||
| Data/Stat | 1/week | Authority | "[Surprising statistic]. Here's why it matters:" |
|
||||
|
||||
### Optimal Posting Times (UTC-based, adjust to audience timezone)
|
||||
| Day | Best Times | Why |
|
||||
|-----|-----------|-----|
|
||||
| Monday | 8-10 AM | Start of work week, checking feeds |
|
||||
| Tuesday | 10 AM, 1 PM | Peak engagement day |
|
||||
| Wednesday | 9 AM, 12 PM | Mid-week focus |
|
||||
| Thursday | 10 AM, 2 PM | Second-highest engagement day |
|
||||
| Friday | 9-11 AM | Morning only, engagement drops PM |
|
||||
| Saturday | 10 AM | Casual browsing |
|
||||
| Sunday | 4-6 PM | Pre-work-week planning |
|
||||
|
||||
---
|
||||
|
||||
## Tweet Writing Best Practices
|
||||
|
||||
### The Hook (first line is everything)
|
||||
Hooks that work:
|
||||
- **Contrarian**: "Most people think X. They're wrong."
|
||||
- **Number**: "I analyzed 500 [things]. Here's what I found:"
|
||||
- **Question**: "Why do 90% of [things] fail?"
|
||||
- **Story**: "In 2019, I almost [dramatic thing]."
|
||||
- **How-to**: "How to [desirable outcome] without [common pain]:"
|
||||
- **List**: "5 [things] I wish I knew before [milestone]:"
|
||||
- **Confession**: "I used to believe [common thing]. Then I learned..."
|
||||
|
||||
### Writing Rules
|
||||
1. **One idea per tweet** — don't try to cover everything
|
||||
2. **Front-load value** — the hook must deliver or promise value
|
||||
3. **Use line breaks** — no wall of text, 1-2 sentences per line
|
||||
4. **280 character limit** — every word must earn its place
|
||||
5. **Active voice** — "We shipped X" not "X was shipped by us"
|
||||
6. **Specific > vague** — "3x faster" not "much faster"
|
||||
7. **End with a call to action** — "Agree? RT" or "What would you add?"
|
||||
|
||||
### Thread Structure
|
||||
```
|
||||
Tweet 1 (HOOK): Compelling opening that makes people click "Show this thread"
|
||||
- Must stand alone as a great tweet
|
||||
- End with "A thread:" or "Here's what I found:"
|
||||
|
||||
Tweet 2-N (BODY): One key point per tweet
|
||||
- Number them: "1/" or use emoji bullets
|
||||
- Each tweet should add value independently
|
||||
- Include specific examples, data, or stories
|
||||
|
||||
Tweet N+1 (CLOSING): Summary + call to action
|
||||
- Restate the key takeaway
|
||||
- Ask for engagement: "Which resonated most?"
|
||||
- Self-reference: "If this was useful, follow @handle for more"
|
||||
```
|
||||
|
||||
### Hashtag Strategy
|
||||
- **0-2 hashtags** per tweet (more looks spammy)
|
||||
- Use hashtags for discovery, not decoration
|
||||
- Mix broad (#AI) and specific (#LangChain)
|
||||
- Never use hashtags in threads (except maybe tweet 1)
|
||||
- Research trending hashtags in your niche before using them
|
||||
|
||||
---
|
||||
|
||||
## Engagement Playbook
|
||||
|
||||
### Replying to Mentions
|
||||
Rules:
|
||||
1. **Respond within 2 hours** during engagement_hours
|
||||
2. **Add value** — don't just say "thanks!" — expand on their point
|
||||
3. **Ask a follow-up question** — drives conversation
|
||||
4. **Be genuine** — match their energy and tone
|
||||
5. **Never argue** — if someone is hostile, ignore or block
|
||||
|
||||
Reply templates:
|
||||
- Agreement: "Great point! I'd also add [related insight]"
|
||||
- Question: "Interesting question. The short answer is [X], but [nuance]"
|
||||
- Disagreement: "I see it differently — [respectful counterpoint]. What's your experience?"
|
||||
- Gratitude: "Appreciate you sharing this! [Specific thing you liked about their tweet]"
|
||||
|
||||
### When NOT to Engage
|
||||
- Trolls or obviously bad-faith arguments
|
||||
- Political flame wars (unless that's your content pillar)
|
||||
- Personal attacks (block immediately)
|
||||
- Spam or bot accounts
|
||||
- Tweets that could create legal liability
|
||||
|
||||
### Auto-Like Strategy
|
||||
Like tweets from:
|
||||
1. People who regularly engage with your content (reciprocity)
|
||||
2. Influencers in your niche (visibility)
|
||||
3. Thoughtful content related to your pillars (curation signal)
|
||||
4. Replies to your tweets (encourages more replies)
|
||||
|
||||
Do NOT auto-like:
|
||||
- Controversial or political content
|
||||
- Content you haven't actually read
|
||||
- Spam or low-quality threads
|
||||
- Competitor criticism (looks petty)
|
||||
|
||||
---
|
||||
|
||||
## Content Calendar Template
|
||||
|
||||
```
|
||||
WEEK OF [DATE]
|
||||
|
||||
Monday:
|
||||
- 8 AM: [Tip/How-to] about [Pillar 1]
|
||||
- 12 PM: [Curated share] related to [Pillar 2]
|
||||
|
||||
Tuesday:
|
||||
- 10 AM: [Thread] deep dive on [Pillar 1]
|
||||
- 2 PM: [Hot take] about [trending topic]
|
||||
|
||||
Wednesday:
|
||||
- 9 AM: [Question] to audience about [Pillar 3]
|
||||
- 1 PM: [Data/Stat] about [Pillar 2]
|
||||
|
||||
Thursday:
|
||||
- 10 AM: [Story] about [personal experience in Pillar 3]
|
||||
- 3 PM: [Tip/How-to] about [Pillar 1]
|
||||
|
||||
Friday:
|
||||
- 9 AM: [Hot take] about [week's trending topic]
|
||||
- 11 AM: [Curated share] — best thing I read this week
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
### Key Metrics
|
||||
| Metric | What It Measures | Good Benchmark |
|
||||
|--------|-----------------|----------------|
|
||||
| Impressions | How many people saw the tweet | Varies by follower count |
|
||||
| Engagement rate | (likes+RTs+replies)/impressions | >2% is good, >5% is great |
|
||||
| Reply rate | replies/impressions | >0.5% is good |
|
||||
| Retweet rate | RTs/impressions | >1% is good |
|
||||
| Profile visits | People checking your profile after tweet | Track trend |
|
||||
| Follower growth | Net new followers per period | Track trend |
|
||||
|
||||
### Engagement Rate Formula
|
||||
```
|
||||
engagement_rate = (likes + retweets + replies + quotes) / impressions * 100
|
||||
|
||||
Example:
|
||||
50 likes + 10 RTs + 5 replies + 2 quotes = 67 engagements
|
||||
67 / 2000 impressions = 3.35% engagement rate
|
||||
```
|
||||
|
||||
### Content Performance Analysis
|
||||
Track which content types and topics perform best:
|
||||
```
|
||||
| Content Type | Avg Impressions | Avg Engagement Rate | Best Performing |
|
||||
|-------------|-----------------|--------------------|--------------------|
|
||||
| Hot take | 2500 | 4.2% | "Unpopular opinion: ..." |
|
||||
| Thread | 5000 | 3.1% | "I analyzed 500 ..." |
|
||||
| Tip | 1800 | 5.5% | "How to ... in 3 steps" |
|
||||
```
|
||||
|
||||
Use this data to optimize future content mix.
|
||||
|
||||
---
|
||||
|
||||
## Brand Voice Guide
|
||||
|
||||
### Voice Dimensions
|
||||
| Dimension | Range | Description |
|
||||
|-----------|-------|-------------|
|
||||
| Formal ↔ Casual | 1-5 | 1=corporate, 5=texting a friend |
|
||||
| Serious ↔ Humorous | 1-5 | 1=all business, 5=comedy account |
|
||||
| Reserved ↔ Bold | 1-5 | 1=diplomatic, 5=no-filter |
|
||||
| General ↔ Technical | 1-5 | 1=anyone can understand, 5=deep expert |
|
||||
|
||||
### Consistency Rules
|
||||
- Use the same voice across ALL tweets (hot takes and how-tos)
|
||||
- Develop 3-5 "signature phrases" you reuse naturally
|
||||
- If the brand voice says "casual," don't suddenly write a formal thread
|
||||
- Read tweets aloud — does it sound like the same person?
|
||||
|
||||
---
|
||||
|
||||
## Safety & Compliance
|
||||
|
||||
### Content Guidelines
|
||||
NEVER post:
|
||||
- Discriminatory content (race, gender, religion, sexuality, disability)
|
||||
- Defamatory claims about real people or companies
|
||||
- Private or confidential information
|
||||
- Threats, harassment, or incitement to violence
|
||||
- Impersonation of other accounts
|
||||
- Misleading claims presented as fact
|
||||
- Content that violates Twitter Terms of Service
|
||||
|
||||
### Approval Mode Queue Format
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "q_001",
|
||||
"content": "Tweet text here",
|
||||
"type": "hot_take",
|
||||
"pillar": "AI",
|
||||
"scheduled_for": "2025-01-15T10:00:00Z",
|
||||
"created": "2025-01-14T20:00:00Z",
|
||||
"status": "pending",
|
||||
"notes": "Based on trending discussion about LLM pricing"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Preview file for human review:
|
||||
```markdown
|
||||
# Tweet Queue Preview
|
||||
Generated: YYYY-MM-DD
|
||||
|
||||
## Pending Tweets (N total)
|
||||
|
||||
### 1. [Hot Take] — Scheduled: Mon 10 AM
|
||||
> Tweet text here
|
||||
|
||||
**Notes**: Based on trending discussion about LLM pricing
|
||||
**Pillar**: AI | **Status**: Pending approval
|
||||
|
||||
---
|
||||
|
||||
### 2. [Thread] — Scheduled: Tue 10 AM
|
||||
> Tweet 1/5: Hook text here
|
||||
> Tweet 2/5: Point one
|
||||
> ...
|
||||
|
||||
**Notes**: Deep dive on new benchmark results
|
||||
**Pillar**: AI | **Status**: Pending approval
|
||||
```
|
||||
|
||||
### Risk Assessment
|
||||
Before posting, evaluate each tweet:
|
||||
- Could this be misinterpreted? → Rephrase for clarity
|
||||
- Does this punch down? → Don't post
|
||||
- Would you be comfortable seeing this attributed to the user in a news article? → If no, don't post
|
||||
- Is this verifiably true? → If not sure, add hedging language or don't post
|
||||
Reference in New Issue
Block a user