Twitter/X Integration
Reward your community for engaging with your brand on Twitter/X. Track mentions, and reward users with LTZ tokens automatically.
Overviewβ
The Twitter Loyalty Bot is a Cloudflare Worker that polls the Twitter API for brand mentions and triggers rewards through the Loyalteez platform.
| Feature | Description |
|---|---|
| Serverless | Runs on Cloudflare Workers (free tier usually sufficient) |
| Automatic | Polls every 15 minutes via cron trigger |
| Smart Deduplication | High water mark + KV storage prevents duplicate rewards |
| Partner Portal Integration | Twitter handle configured in Partner Portal (single source of truth) |
| Configurable | Set reward amounts and limits in Partner Portal |
Supported Event Typesβ
| Event Type | Description | API Tier Required |
|---|---|---|
tweet_mention | User mentions @YourBrand | Basic (Free) |
tweet_reply | User replies to your tweet | Basic (Free) |
tweet_like | User likes your tweet | Pro ($100/mo) |
tweet_retweet | User retweets your content | Pro ($100/mo) |
Likes and retweets require Twitter API Pro tier due to endpoint restrictions. Mentions work with the free Basic tier.
Quick Startβ
Prerequisitesβ
- Cloudflare Account
- Twitter Developer Account
- Loyalteez Brand ID (from Partner Portal)
1. Clone the Repositoryβ
git clone https://github.com/Alpha4-Labs/x-loyalty-bot.git
cd x-loyalty-bot
npm install
2. Get Twitter API Credentialsβ
- Go to Twitter Developer Portal
- Create a new Project and App
- Navigate to Keys and Tokens
- Generate a Bearer Token
Store your Bearer Token securely. Never commit it to git!
3. Create KV Namespaceβ
npx wrangler kv:namespace create TWITTER_BOT_KV
Copy the id from the output.
4. Configureβ
cp wrangler.example.toml wrangler.toml
Edit wrangler.toml:
[[kv_namespaces]]
binding = "TWITTER_BOT_KV"
id = "your_kv_id_here"
[vars]
BRAND_ID = "0xYourWalletAddress"
LOYALTEEZ_API_URL = "https://api.loyalteez.app"
SUPABASE_URL = "https://xcyhefjogmgttegqhhyi.supabase.co"
The Twitter handle is NOT configured here. It's configured in Partner Portal and read from Supabase at runtime.
5. Set Secretsβ
# Twitter Bearer Token from step 2
npx wrangler secret put TWITTER_BEARER_TOKEN
# Supabase key (get from Loyalteez team)
npx wrangler secret put SUPABASE_PUBLISH_KEY
6. Configure Twitter Handle in Partner Portalβ
- Go to Partner Portal β Settings β Profile
- Expand Authentication Methods β X (Twitter)
- Enter your brand's Twitter handle (without @)
- Click Save Profile
This is the single source of truth for your Twitter handle. The worker reads this value from Supabase on each poll.
7. Deployβ
npm run deploy
8. Configure Events in Partner Portalβ
- Go to Partner Portal β Settings β Points Distribution
- Click Add Event
- Select Tweet Mention (or other Twitter events)
- Configure:
- Reward Amount: e.g., 50 LTZ
- Cooldown: e.g., 1 hour (prevents spam)
- Max Claims: e.g., 10 per user
- Save Configuration
How It Worksβ
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Twitter API ββββββΆβ Cloudflare ββββββΆβ Loyalteez β
β Search API β β Worker (Cron) β β Event Handler β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β β β
β βΌ β
β ββββββββββββββββββββ β
β β KV Store β β
β β (Deduplication) β β
β ββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββ β
ββββββββββββββββΆβ Supabase βββββββββββββββ
β (Config) β
ββββββββββββββββββββ
- Cron Trigger: Worker runs every 15 minutes
- Load Config: Fetches Twitter handle from Supabase (Partner Portal)
- High Water Mark: Only fetches tweets newer than last processed
- Search Mentions: Queries Twitter for
@YourBrandmentions - Check KV: Skip already-processed tweets (belt-and-suspenders)
- Send Event: Calls Loyalteez Event Handler
- Store: Updates high water mark and records tweet ID
First Run Behaviorβ
On first deployment (no high water mark), the bot will:
- Process only the 3 most recent mentions (to avoid mass-processing old tweets)
- Set a high water mark for future polls
- Subsequent polls only fetch tweets newer than the high water mark
API Endpointsβ
The worker exposes several HTTP endpoints for management and testing:
| Endpoint | Method | Description |
|---|---|---|
/ | GET | Service info and available endpoints |
/health | GET | Health check with config status |
/config | GET | Debug endpoint showing configuration |
/trigger | POST | Manually trigger a poll (for testing) |
/reset | POST | Reset high water mark (start fresh) |
Example: Manual Triggerβ
curl -X POST https://your-worker.workers.dev/trigger
Example: Reset High Water Markβ
curl -X POST https://your-worker.workers.dev/reset
This resets the "last processed tweet" marker, causing the next poll to be treated as a first run (processes 3 most recent tweets).
Example: Health Checkβ
curl https://your-worker.workers.dev/health
Response:
{
"status": "ok",
"service": "twitter-loyalty-bot",
"brand_id": "0x...",
"twitter_handle": "YourBrand",
"timestamp": "2024-11-24T..."
}
User Identificationβ
Twitter users are mapped to Loyalteez wallets using a synthetic email format:
Example: [email protected]
- Deterministic: Same Twitter user always gets the same wallet
- Cross-Platform: Can be linked with other social identities
- Claiming: Users visit the Perk Marketplace and connect their Twitter to claim rewards
Partner Portal Configurationβ
Adding Your Twitter Handleβ
- Go to Partner Portal β Settings β Profile
- Expand Authentication Methods β X (Twitter)
- Enter your brand's Twitter handle (without @)
- Click Save Profile
The worker reads this value from Supabase on each poll, so changes take effect immediately.
Creating Twitter Eventsβ
- Go to Settings β Points Distribution β Events tab
- Click Add Event
- Select a Twitter event type:
- Tweet Mention - When someone mentions your handle
- Tweet Like - When someone likes your tweet
- Tweet Retweet - When someone retweets you
- Tweet Reply - When someone replies to you
- Configure reward parameters
- Save
Advanced Configurationβ
Change Poll Frequencyβ
Edit wrangler.toml:
[triggers]
crons = ["*/5 * * * *"] # Every 5 minutes (uses more API quota)
More frequent polling consumes Twitter API quota faster. Basic tier allows only 10 requests per 15-minute window.
Custom Domainβ
[[routes]]
pattern = "x-bot.yourdomain.com/*"
zone_name = "yourdomain.com"
Service Bindings (Internal)β
For direct worker-to-worker communication (bypasses public HTTP):
[[services]]
binding = "EVENT_HANDLER"
service = "loyalteez-event-handler"
API Rate Limitsβ
Twitter API Tiersβ
| Tier | Requests/15min | Monthly Tweets | Cost | Recommended Polling |
|---|---|---|---|---|
| Free | 1 | 100 | $0 | Daily |
| Basic | 10 | 10,000 | $100/mo | Every 15 min |
| Pro | 450 | 1,000,000 | $5,000/mo | Every 5 min |
The free tier is extremely restrictive:
- Only 1 request per 15 minutes
- Only 100 tweets per month
- Use daily polling (
0 12 * * *) to conserve quota - Suitable for demos only - upgrade to Basic for production
Calculationβ
Each poll uses 1-2 API requests:
- 1 request for user ID lookup (cached for 24 hours in KV)
- 1 request for mention search
Free tier with daily polling:
- 1 poll/day Γ 1 request = 1 request/day β
- 100 tweets/month Γ· ~10 tweets/poll = ~10 polls before cap
- Daily polling sustainable for demos with light engagement
Basic tier with 15-min polling:
- 96 polls/day Γ 1 request = 96 requests/day β
- 10,000 tweets/month = comfortable headroom
User IDs are cached in KV for 24 hours, so repeated polls for the same handle only use 1 search request after the first poll.
Troubleshootingβ
"Twitter API secrets not configured"β
npx wrangler secret put TWITTER_BEARER_TOKEN
"Twitter handle not configured in Partner Portal"β
- Go to Partner Portal β Settings β Profile
- Find Authentication Methods β X (Twitter)
- Enter your handle (without @)
- Save
"No config found for brand"β
- Verify
BRAND_IDin wrangler.toml matches your Partner Portal wallet - Ensure
SUPABASE_PUBLISH_KEYsecret is set correctly
"Rate limit exceeded" (429 error)β
Twitter Basic tier has 10 requests per 15-minute window. If you hit this:
- Wait 15 minutes for the rate limit to reset
- Reduce poll frequency in
wrangler.toml - Consider upgrading to Pro tier for high-engagement brands
No rewards appearingβ
- Verify
BRAND_IDmatches your Partner Portal wallet - Confirm
tweet_mentionevent exists in Partner Portal - Check worker logs:
npx wrangler tail - Verify Twitter handle is set in Partner Portal
High water mark issuesβ
If old tweets are being processed or new tweets are being skipped:
# Reset the high water mark
curl -X POST https://your-worker.workers.dev/reset
Next poll will be treated as first run (processes 3 most recent tweets).
View Real-Time Logsβ
npx wrangler tail
Security Best Practicesβ
- Never commit secrets - Use
npx wrangler secret put - Use
.gitignore- Excludeswrangler.toml,.env,node_modules - Use example files -
wrangler.example.tomlfor templates - Rotate tokens - Regenerate Bearer Token if compromised
- Don't commit wrangler.toml - Contains your KV ID and brand-specific config
Example Use Casesβ
1. Brand Awareness Campaignβ
Reward users 100 LTZ for mentioning your brand:
Event: tweet_mention
Reward: 100 LTZ
Cooldown: 24 hours
Max Claims: 5 per user
2. Product Launch Buzzβ
Higher rewards for launch week engagement:
Event: tweet_mention
Reward: 250 LTZ
Cooldown: 1 hour
Max Total Claims: 1000 (first 1000 users)
3. Community Buildingβ
Daily engagement rewards:
Event: tweet_mention
Reward: 25 LTZ
Cooldown: 24 hours
Max Claims: Unlimited
Environment Variables Referenceβ
| Variable | Description | Where to Set |
|---|---|---|
BRAND_ID | Your Loyalteez wallet address | wrangler.toml |
LOYALTEEZ_API_URL | API endpoint | wrangler.toml |
SUPABASE_URL | Supabase instance URL | wrangler.toml |
TWITTER_BEARER_TOKEN | Twitter API Bearer Token | Secret |
SUPABASE_PUBLISH_KEY | Supabase public key | Secret |
Twitter handle is NOT an environment variable. It's configured in Partner Portal and read from Supabase at runtime.
Resourcesβ
- GitHub Repository: Alpha4-Labs/x-loyalty-bot
- Twitter API Docs: developer.twitter.com
- Event Handler API: Event Handler Reference
- Cloudflare Workers: developers.cloudflare.com/workers
Supportβ
- GitHub Issues: Report bugs or request features
- Discord: Join our developer community
- Email: [email protected]