The Twitter / X integration lets your Cognest assistant post tweets, reply to conversations, retweet content, manage direct messages, and react to real-time events such as mentions and new followers. It wraps the X API v2 and handles rate limiting, pagination, and OAuth token management automatically.
.env file:TWITTER_API_KEY=your_api_key
TWITTER_API_SECRET=your_api_secret
TWITTER_ACCESS_TOKEN=your_access_token
TWITTER_ACCESS_SECRET=your_access_secret
TWITTER_BEARER_TOKEN=your_bearer_tokenAdd the Twitter integration to your cognest.config.yaml:
integrations:
twitter:
enabled: true
credentials:
api_key: ${TWITTER_API_KEY}
api_secret: ${TWITTER_API_SECRET}
access_token: ${TWITTER_ACCESS_TOKEN}
access_secret: ${TWITTER_ACCESS_SECRET}
bearer_token: ${TWITTER_BEARER_TOKEN}
settings:
# Poll interval for timeline and mention checks (seconds)
poll_interval: 30
# Maximum tweet length (default 280)
max_tweet_length: 280
# Enable filtered stream for real-time events
use_filtered_stream: true
# Rate limit strategy: "queue" buffers requests, "drop" discards excess
rate_limit_strategy: queueYou can use the integration through the config file (shown above) or register it programmatically:
import { Cognest } from '@cognest/sdk'
const cognest = new Cognest()
const twitter = cognest.integration('twitter')
await twitter.tweet('Hello from Cognest!')
await cognest.start()| Method | Parameters | Description |
|---|---|---|
| tweet(text, options?) | text: string, options?: { mediaIds?, replySettings? } | Post a new tweet. Supports media attachments and reply restrictions. |
| reply(tweetId, text, options?) | tweetId: string, text: string | Reply to an existing tweet by its ID. |
| retweet(tweetId) | tweetId: string | Retweet (repost) an existing tweet. |
| like(tweetId) | tweetId: string | Like a tweet. |
| getTimeline(userId?, options?) | userId?: string, options?: { maxResults?, paginationToken? } | Retrieve the home or user timeline. Defaults to the authenticated user. |
| searchTweets(query, options?) | query: string, options?: { maxResults?, startTime?, endTime? } | Search recent tweets matching a query using the X API v2 search endpoint. |
| getUser(username) | username: string | Fetch a user profile by handle. |
| sendDM(userId, text) | userId: string, text: string | Send a direct message to a user. |
Subscribe to real-time events emitted by the Twitter integration. Events are delivered through the filtered stream or polling, depending on your configuration.
| Event | Payload | Description |
|---|---|---|
| mention | { tweetId, userId, username, text, createdAt } | Fired when the authenticated account is mentioned in a tweet. |
| dm:received | { senderId, senderUsername, text, conversationId, createdAt } | Fired when a new direct message is received. |
| tweet:liked | { tweetId, userId, username } | Fired when one of your tweets is liked. |
| tweet:retweeted | { tweetId, userId, username } | Fired when one of your tweets is retweeted. |
| follower:new | { userId, username, followedAt } | Fired when a new user follows the authenticated account. |
twitter.on('mention', async (event) => {
console.log(`@${event.username} mentioned you: ${event.text}`)
// Auto-reply to mentions
await twitter.reply(event.tweetId, `Thanks for the mention, @${event.username}!`)
})
twitter.on('dm:received', async (event) => {
console.log(`DM from @${event.senderUsername}: ${event.text}`)
})
twitter.on('follower:new', async (event) => {
console.log(`New follower: @${event.username}`)
})A complete example that monitors brand mentions, performs sentiment analysis with the AI engine, and auto-replies to positive tweets:
import { Cognest } from '@cognest/sdk'
const cognest = new Cognest()
const twitter = cognest.integration('twitter')
// Monitor brand mentions and respond intelligently
twitter.on('mention', async (event) => {
// Use the AI engine to analyze sentiment
const analysis = await cognest.engine.run({
prompt: `Analyze the sentiment of this tweet and decide if we should reply.
Tweet: "${event.text}"
If positive or neutral, draft a friendly reply under 280 characters.
If negative, draft a professional support-oriented reply.
Return JSON: { "sentiment": "positive"|"negative"|"neutral", "reply": "..." }`,
responseFormat: 'json',
})
const { sentiment, reply } = JSON.parse(analysis.text)
// Reply to the tweet
await twitter.reply(event.tweetId, reply)
// Log for analytics
console.log(`[${sentiment}] @${event.username}: ${event.text}`)
console.log(` Replied: ${reply}`)
})
// Auto-retweet tweets from a curated list of accounts
const CURATED_ACCOUNTS = ['cognestai', 'techleaders', 'airesearchers']
cognest.skill('scheduled-retweet', {
schedule: '0 */4 * * *', // Every 4 hours
handler: async () => {
for (const account of CURATED_ACCOUNTS) {
const user = await twitter.getUser(account)
const timeline = await twitter.getTimeline(user.id, { maxResults: 5 })
for (const tweet of timeline.data) {
// Only retweet if it matches our topic filter
const isRelevant = await cognest.engine.run({
prompt: `Is this tweet relevant to AI automation? Answer yes or no.\nTweet: "${tweet.text}"`,
})
if (isRelevant.text.toLowerCase().includes('yes')) {
await twitter.retweet(tweet.id)
}
}
}
},
})
// Search for industry discussions and engage
cognest.skill('social-listening', {
schedule: '*/15 * * * *', // Every 15 minutes
handler: async () => {
const results = await twitter.searchTweets(
'"AI automation" OR "workflow automation" -is:retweet lang:en',
{ maxResults: 10 }
)
for (const tweet of results.data) {
await twitter.like(tweet.id)
}
},
})
await cognest.start()
console.log('Twitter bot is running...')Common Issues
403 Forbidden: Your Twitter app may not have the required permissions. Go to the Twitter Developer Portal and ensure your app has Read and Write permissions, plus Direct Message access if using DMs. 429 Too Many Requests: You've hit a rate limit. Cognest queues requests by default when rate_limit_strategy is set to "queue". If you see this error, check your poll_interval and reduce request frequency. Filtered Stream connection drops: The X API v2 filtered stream has a maximum of one concurrent connection per app. Ensure only one Cognest instance is using the stream. Set use_filtered_stream: false to fall back to polling. Bearer token errors: The bearer token is used for app-only authentication (read-only). Posting tweets, liking, and DMs require OAuth 1.0a user tokens (access_token and access_secret).
Rate Limit Reference
The X API v2 free tier allows 1,500 tweets per month and 50 requests per 15-minute window for most endpoints. The Basic tier ($100/month) increases this to 3,000 tweets and 10,000 search results. Check your usage tier in the Developer Portal and configure poll_interval accordingly.