@xquik/tweetclaw 1.0.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/openclaw.plugin.json +1 -0
- package/package.json +3 -2
- package/skills/tweetclaw/SKILL.md +208 -0
- package/src/index.ts +31 -31
- package/src/tools/explore.ts +1 -1
- package/src/tools/tweetclaw.ts +136 -7
package/README.md
CHANGED
|
@@ -43,21 +43,21 @@ AI uses explore → filters spec by category "composition"
|
|
|
43
43
|
|
|
44
44
|
### `tweetclaw` (execute API calls)
|
|
45
45
|
|
|
46
|
-
Execute authenticated API calls. Auth is injected automatically
|
|
46
|
+
Execute authenticated API calls. Auth is injected automatically - the LLM never sees your API key.
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
You: "
|
|
49
|
+
You: "Post a tweet saying 'Hello from TweetClaw!'"
|
|
50
50
|
|
|
51
|
-
AI uses
|
|
52
|
-
|
|
53
|
-
→ Returns tweet results
|
|
51
|
+
AI uses tweetclaw → finds connected account, posts tweet
|
|
52
|
+
→ Returns { tweetId, success: true }
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
```
|
|
57
|
-
You: "
|
|
56
|
+
You: "Search tweets about AI agents"
|
|
58
57
|
|
|
59
|
-
AI uses
|
|
60
|
-
→
|
|
58
|
+
AI uses explore → finds /api/v1/x/tweets/search
|
|
59
|
+
AI uses tweetclaw → calls the endpoint with auth
|
|
60
|
+
→ Returns tweet results
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
## Commands
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xquik/tweetclaw",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Post tweets, reply, like, retweet, follow, DM & more from OpenClaw - full X/Twitter automation via Xquik",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"src/",
|
|
25
|
+
"skills/",
|
|
25
26
|
"openclaw.plugin.json"
|
|
26
27
|
],
|
|
27
28
|
"keywords": [
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@eslint/js": "^10.0.1",
|
|
51
|
-
"@sinclair/typebox": "^0.34.
|
|
52
|
+
"@sinclair/typebox": "^0.34.48",
|
|
52
53
|
"@types/node": "^25.5.0",
|
|
53
54
|
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
|
54
55
|
"@typescript-eslint/parser": "^8.57.0",
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tweetclaw
|
|
3
|
+
description: "OpenClaw plugin for X/Twitter automation. Post tweets, reply, like, retweet, follow, DM, search, extract data, run giveaways, monitor accounts via Xquik. 40+ endpoints, 2 tools (explore + tweetclaw), 2 commands (/xstatus, /xtrends), background event poller."
|
|
4
|
+
homepage: https://xquik.com
|
|
5
|
+
read_when:
|
|
6
|
+
- Posting, replying, liking, retweeting, or following on X/Twitter
|
|
7
|
+
- Searching tweets or looking up X/Twitter users
|
|
8
|
+
- Running giveaway draws from tweet replies
|
|
9
|
+
- Monitoring X/Twitter accounts for new activity
|
|
10
|
+
- Composing algorithm-optimized tweets
|
|
11
|
+
- Extracting bulk data from X/Twitter (followers, replies, communities)
|
|
12
|
+
- Downloading tweet media or uploading images
|
|
13
|
+
- Sending DMs or updating X/Twitter profile
|
|
14
|
+
metadata: {"openclaw":{"emoji":"🐦","primaryEnv":"XQUIK_API_KEY","requires":{"env":["XQUIK_API_KEY"]}}}
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# TweetClaw
|
|
18
|
+
|
|
19
|
+
OpenClaw plugin for X/Twitter automation powered by Xquik. Install via:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
openclaw plugins install @xquik/tweetclaw
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
Set your Xquik API key (get one at [xquik.com/account-manager](https://xquik.com/account-manager)):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
openclaw config set plugins.entries.tweetclaw.config.apiKey 'xq_YOUR_KEY'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Tools
|
|
34
|
+
|
|
35
|
+
TweetClaw registers 2 tools that cover the entire Xquik API (40+ endpoints):
|
|
36
|
+
|
|
37
|
+
### `explore` (free, no network)
|
|
38
|
+
|
|
39
|
+
Search the API spec to find endpoints. No API calls are made.
|
|
40
|
+
|
|
41
|
+
Example: "What endpoints are available for tweet composition?"
|
|
42
|
+
|
|
43
|
+
The agent writes an async arrow function that filters the in-memory endpoint catalog:
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
async () => spec.endpoints.filter(e => e.category === 'composition')
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `tweetclaw` (execute API calls)
|
|
50
|
+
|
|
51
|
+
Execute authenticated API calls. Auth is injected automatically.
|
|
52
|
+
|
|
53
|
+
Example: "Post a tweet saying 'Hello from TweetClaw!'"
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
async () => {
|
|
57
|
+
const { accounts } = await xquik.request('/api/v1/x/accounts');
|
|
58
|
+
return xquik.request('/api/v1/x/tweets', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: { account: accounts[0].xUsername, text: 'Hello from TweetClaw!' }
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `/xstatus` | Account info, subscription status, usage |
|
|
70
|
+
| `/xtrends` | Trending topics from curated sources |
|
|
71
|
+
| `/xtrends tech` | Trending topics filtered by category |
|
|
72
|
+
|
|
73
|
+
## Event Notifications
|
|
74
|
+
|
|
75
|
+
When polling is enabled (default), TweetClaw checks for new events every 60 seconds:
|
|
76
|
+
|
|
77
|
+
- Monitor alerts: new tweets, replies, quotes, retweets from monitored accounts
|
|
78
|
+
- Follower changes: gained or lost followers on monitored accounts
|
|
79
|
+
|
|
80
|
+
## Common Workflows
|
|
81
|
+
|
|
82
|
+
### Post a tweet
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
You: "Post a tweet saying 'Hello from TweetClaw!'"
|
|
86
|
+
Agent uses tweetclaw -> finds connected account, posts tweet
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Reply to a tweet
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
You: "Reply 'Great thread!' to this tweet: https://x.com/user/status/123"
|
|
93
|
+
Agent uses tweetclaw -> posts reply with reply_to_tweet_id
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Like, retweet, follow
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
You: "Like and retweet this tweet, then follow the author"
|
|
100
|
+
Agent uses tweetclaw -> likes tweet, retweets, looks up user ID, follows
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Send a DM
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
You: "DM @username saying 'Hey, let's collaborate!'"
|
|
107
|
+
Agent uses tweetclaw -> looks up user ID, sends DM
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Update profile
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
You: "Change my bio to 'Building cool stuff' and update my avatar"
|
|
114
|
+
Agent uses tweetclaw -> PATCH /api/v1/x/profile, PATCH /api/v1/x/profile/avatar
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Upload media and tweet with image
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
You: "Tweet 'Check this out!' with this image: https://example.com/photo.jpg"
|
|
121
|
+
Agent uses tweetclaw -> uploads media, posts tweet with media_ids
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Search tweets
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
You: "Search tweets about AI agents"
|
|
128
|
+
Agent uses tweetclaw -> calls search endpoint with query
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Run a giveaway draw
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
You: "Pick 3 random winners from replies to this tweet: https://x.com/..."
|
|
135
|
+
Agent uses tweetclaw -> creates draw with filters
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Extract bulk data
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
You: "Extract the last 1000 followers of @elonmusk"
|
|
142
|
+
Agent uses tweetclaw -> estimates cost, creates extraction job
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Monitor an account
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
You: "Monitor @elonmusk for new tweets and follower changes"
|
|
149
|
+
Agent uses tweetclaw -> creates monitor with event types
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Download tweet media
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
You: "Download all media from this tweet"
|
|
156
|
+
Agent uses tweetclaw -> returns gallery URL with all media
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Compose an optimized tweet (free)
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
You: "Help me write a tweet about our product launch"
|
|
163
|
+
Agent uses tweetclaw -> 3-step compose/refine/score workflow
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Analyze writing style (free)
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
You: "Analyze @username's tweet style"
|
|
170
|
+
Agent uses tweetclaw -> returns style analysis with tone, patterns, metrics
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Browse trending topics (free)
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
You: "What's trending on X right now?"
|
|
177
|
+
Agent uses tweetclaw -> returns curated trending topics from 7 sources
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API Categories
|
|
181
|
+
|
|
182
|
+
| Category | Examples | Free |
|
|
183
|
+
|----------|---------|------|
|
|
184
|
+
| Write Actions | Post tweets, reply, like, retweet, follow, DM, update profile | No |
|
|
185
|
+
| Media | Upload media, download tweet media | No |
|
|
186
|
+
| Twitter | Search tweets, look up users, check follows | No |
|
|
187
|
+
| Composition | Compose, refine, score tweets; manage drafts | Yes |
|
|
188
|
+
| Styles | Analyze tweet styles, compare, performance | Mixed |
|
|
189
|
+
| Extraction | Reply/follower/community extraction (20 tools) | No |
|
|
190
|
+
| Draws | Giveaway draws, export results | No |
|
|
191
|
+
| Monitoring | Create monitors, view events, webhooks | No |
|
|
192
|
+
| Account | API keys, subscription, connected X accounts | Yes |
|
|
193
|
+
| Trends | X trending topics, curated radar from 7 sources | Mixed |
|
|
194
|
+
|
|
195
|
+
## Pricing
|
|
196
|
+
|
|
197
|
+
Free tier (no subscription): tweet composition, style analysis, drafts, curated radar, account management, integrations.
|
|
198
|
+
|
|
199
|
+
Subscription ($20/month): write actions, search, media, extractions, draws, monitors, X trending.
|
|
200
|
+
|
|
201
|
+
When a paid endpoint returns 402, TweetClaw provides a checkout URL.
|
|
202
|
+
|
|
203
|
+
## When NOT to Use
|
|
204
|
+
|
|
205
|
+
- Reading tweets in a browser or basic browsing (use a browser skill instead)
|
|
206
|
+
- X/Twitter analytics dashboards (TweetClaw returns raw data, not visualizations)
|
|
207
|
+
- Scheduling tweets for future posting (Xquik posts immediately)
|
|
208
|
+
- Managing X/Twitter ads or promoted content (not supported)
|
package/src/index.ts
CHANGED
|
@@ -15,66 +15,64 @@ function isPollerEvent(value: unknown): value is PollerEvent {
|
|
|
15
15
|
return typeof value === 'object' && value !== null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function isPluginConfig(value: unknown): value is PluginConfig {
|
|
19
|
+
return typeof value === 'object' && value !== null && 'apiKey' in value;
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
const DEFAULT_POLLING_INTERVAL_SECONDS = 60;
|
|
19
23
|
|
|
24
|
+
interface ToolResult {
|
|
25
|
+
readonly content: ReadonlyArray<{ readonly text: string; readonly type: string }>;
|
|
26
|
+
readonly isError?: true;
|
|
27
|
+
}
|
|
28
|
+
|
|
20
29
|
interface CommandContext {
|
|
21
30
|
readonly args?: string;
|
|
31
|
+
readonly commandBody?: string;
|
|
32
|
+
readonly senderId?: string;
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
interface OpenClawApi {
|
|
25
|
-
readonly config: {
|
|
26
|
-
readonly plugins?: {
|
|
27
|
-
readonly entries?: {
|
|
28
|
-
readonly tweetclaw?: {
|
|
29
|
-
readonly config?: PluginConfig;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
36
|
readonly logger: {
|
|
37
|
+
readonly debug?: (message: string) => void;
|
|
38
|
+
readonly error: (message: string) => void;
|
|
35
39
|
readonly info: (message: string) => void;
|
|
36
40
|
readonly warn: (message: string) => void;
|
|
37
41
|
};
|
|
42
|
+
readonly pluginConfig?: Readonly<Record<string, unknown>>;
|
|
38
43
|
readonly registerCommand: (options: {
|
|
39
|
-
readonly
|
|
44
|
+
readonly acceptsArgs?: boolean;
|
|
40
45
|
readonly description: string;
|
|
41
46
|
readonly handler: (context: CommandContext) => Promise<{ readonly text: string }>;
|
|
42
47
|
readonly name: string;
|
|
43
48
|
}) => void;
|
|
44
49
|
readonly registerService: (options: {
|
|
45
50
|
readonly id: string;
|
|
46
|
-
readonly start: () => void;
|
|
47
|
-
readonly stop
|
|
51
|
+
readonly start: (context?: unknown) => void;
|
|
52
|
+
readonly stop?: (context?: unknown) => void;
|
|
48
53
|
}) => void;
|
|
49
54
|
readonly registerTool: (
|
|
50
|
-
|
|
55
|
+
tool: {
|
|
51
56
|
readonly description: string;
|
|
57
|
+
readonly execute: (toolCallId: string, params: { readonly code: string }) => Promise<ToolResult>;
|
|
52
58
|
readonly name: string;
|
|
53
|
-
readonly parameters:
|
|
54
|
-
readonly properties: Readonly<Record<string, { readonly description: string; readonly type: string }>>;
|
|
55
|
-
readonly required: readonly string[];
|
|
56
|
-
readonly type: string;
|
|
57
|
-
};
|
|
59
|
+
readonly parameters: unknown;
|
|
58
60
|
},
|
|
59
|
-
|
|
60
|
-
readonly content: ReadonlyArray<{ readonly text: string; readonly type: string }>;
|
|
61
|
-
readonly isError?: true;
|
|
62
|
-
}>,
|
|
61
|
+
options?: { readonly name?: string; readonly optional?: boolean },
|
|
63
62
|
) => void;
|
|
64
|
-
readonly sendMessage: (text: string) => void;
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
const CODE_PARAMETER = {
|
|
68
66
|
properties: {
|
|
69
67
|
code: { description: 'Async arrow function to execute', type: 'string' },
|
|
70
68
|
},
|
|
71
|
-
required: ['code']
|
|
69
|
+
required: ['code'],
|
|
72
70
|
type: 'object',
|
|
73
71
|
};
|
|
74
72
|
|
|
75
73
|
export default function register(api: OpenClawApi, fetchFunction?: FetchFunction): void {
|
|
76
|
-
const config = api.
|
|
77
|
-
if (config
|
|
74
|
+
const config: unknown = api.pluginConfig;
|
|
75
|
+
if (!isPluginConfig(config)) {
|
|
78
76
|
api.logger.warn(
|
|
79
77
|
"TweetClaw: No API key configured. Run: openclaw config set plugins.entries.tweetclaw.config.apiKey 'xq_YOUR_KEY'",
|
|
80
78
|
);
|
|
@@ -84,23 +82,25 @@ export default function register(api: OpenClawApi, fetchFunction?: FetchFunction
|
|
|
84
82
|
const { apiKey, baseUrl = 'https://xquik.com' } = config;
|
|
85
83
|
const request = createProxiedRequest(baseUrl, apiKey, fetchFunction);
|
|
86
84
|
|
|
87
|
-
// --- Tools (2-tool approach) ---
|
|
85
|
+
// --- Tools (2-tool approach, execute inside tool object) ---
|
|
88
86
|
api.registerTool(
|
|
89
87
|
{
|
|
90
88
|
description: SEARCH_DESCRIPTION,
|
|
89
|
+
execute: async (_toolCallId, { code }) => handleExplore(code),
|
|
91
90
|
name: 'explore',
|
|
92
91
|
parameters: CODE_PARAMETER,
|
|
93
92
|
},
|
|
94
|
-
|
|
93
|
+
{ name: 'explore' },
|
|
95
94
|
);
|
|
96
95
|
|
|
97
96
|
api.registerTool(
|
|
98
97
|
{
|
|
99
98
|
description: EXECUTE_DESCRIPTION,
|
|
99
|
+
execute: async (_toolCallId, { code }) => handleTweetclaw({ apiKey, baseUrl, code, fetchFunction }),
|
|
100
100
|
name: 'tweetclaw',
|
|
101
101
|
parameters: CODE_PARAMETER,
|
|
102
102
|
},
|
|
103
|
-
|
|
103
|
+
{ name: 'tweetclaw', optional: true },
|
|
104
104
|
);
|
|
105
105
|
|
|
106
106
|
// --- Commands (instant, no LLM) ---
|
|
@@ -114,7 +114,7 @@ export default function register(api: OpenClawApi, fetchFunction?: FetchFunction
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
api.registerCommand({
|
|
117
|
-
|
|
117
|
+
acceptsArgs: true,
|
|
118
118
|
description: 'Show trending topics on X',
|
|
119
119
|
handler: async ({ args }) => {
|
|
120
120
|
const text = await handleXTrends(request, args);
|
|
@@ -136,7 +136,7 @@ export default function register(api: OpenClawApi, fetchFunction?: FetchFunction
|
|
|
136
136
|
const username: string = isPollerEvent(event) && typeof event.xUsername === 'string'
|
|
137
137
|
? event.xUsername
|
|
138
138
|
: '';
|
|
139
|
-
api.
|
|
139
|
+
api.logger.info(`[TweetClaw] ${eventType} from @${username}`);
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
142
|
request,
|
package/src/tools/explore.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { EndpointInfo, ToolResult } from '../types.js';
|
|
|
4
4
|
|
|
5
5
|
const categories = [...new Set(API_SPEC.map((endpoint) => endpoint.category))].toSorted((a, b) => a.localeCompare(b)).join(', ');
|
|
6
6
|
|
|
7
|
-
const SEARCH_DESCRIPTION = `Search the X (Twitter) API spec for endpoints:
|
|
7
|
+
const SEARCH_DESCRIPTION = `Search the X (Twitter) API spec for endpoints: post tweets, reply, like, retweet, follow, DM, update profile, upload media, search tweets, look up users, extract data, monitor accounts, run giveaways, compose tweets, and more. No network calls - runs against an in-memory endpoint catalog.
|
|
8
8
|
|
|
9
9
|
Write an async arrow function. The sandbox provides:
|
|
10
10
|
|
package/src/tools/tweetclaw.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { createProxiedRequest } from '../request.js';
|
|
|
2
2
|
import { AsyncFunction, errorResult, specEndpoints, successResult } from './sandbox.js';
|
|
3
3
|
import type { FetchFunction, RequestFunction, ToolResult } from '../types.js';
|
|
4
4
|
|
|
5
|
-
const EXECUTE_DESCRIPTION = `Execute X (Twitter) API calls:
|
|
5
|
+
const EXECUTE_DESCRIPTION = `Execute X (Twitter) API calls: post tweets, reply, like, retweet, follow, DM, update profile, upload media, search tweets, look up users, extract data, run giveaways, monitor accounts, compose tweets, and more. Write an async arrow function.
|
|
6
6
|
|
|
7
7
|
The sandbox provides:
|
|
8
8
|
\`\`\`typescript
|
|
@@ -20,6 +20,13 @@ declare const spec: { endpoints: EndpointInfo[] };
|
|
|
20
20
|
Auth is injected automatically - never pass API keys.
|
|
21
21
|
First use "explore" to find endpoints, then write code here to call them.
|
|
22
22
|
|
|
23
|
+
## Important rules
|
|
24
|
+
- TWEET ACTIONS: SENDING a tweet ("tweet this", "post this") uses POST /api/v1/x/tweets. DRAFTING a tweet ("help me write", "compose") uses the 3-step compose flow. Never use compose when the user has text and wants to send it.
|
|
25
|
+
- CALL ORDERING: NEVER combine free and paid endpoints in Promise.all. Call free endpoints first (radar, styles, compose), then paid ones separately. If a paid call fails with 402, still use free data already fetched.
|
|
26
|
+
- WRITE ACTIONS: All require the "account" parameter (X username, e.g. "@myaccount"). Follow/unfollow/DM use numeric user ID in path - look up the user first via GET /api/v1/x/users/:username.
|
|
27
|
+
- CURRENT EVENTS: Use /api/v1/radar (free) for trending topics. Never use web search for trends.
|
|
28
|
+
- SUBSCRIPTION ERRORS: On 402, call POST /api/v1/subscribe (free) to get checkout URL.
|
|
29
|
+
|
|
23
30
|
## Workflows
|
|
24
31
|
|
|
25
32
|
### 1. Send a tweet (Subscription required)
|
|
@@ -103,7 +110,28 @@ async () => {
|
|
|
103
110
|
}
|
|
104
111
|
\`\`\`
|
|
105
112
|
|
|
106
|
-
### 7.
|
|
113
|
+
### 7. Update profile, avatar, or banner
|
|
114
|
+
\`\`\`javascript
|
|
115
|
+
async () => {
|
|
116
|
+
// Update bio, name, location, URL
|
|
117
|
+
await xquik.request('/api/v1/x/profile', {
|
|
118
|
+
method: 'PATCH',
|
|
119
|
+
body: { account: '@myaccount', name: 'New Name', bio: 'Building cool stuff' }
|
|
120
|
+
});
|
|
121
|
+
// Update avatar (url must be HTTPS, max 700 KB)
|
|
122
|
+
await xquik.request('/api/v1/x/profile/avatar', {
|
|
123
|
+
method: 'PATCH',
|
|
124
|
+
body: { account: '@myaccount', url: 'https://example.com/avatar.jpg' }
|
|
125
|
+
});
|
|
126
|
+
// Update banner (max 2 MB)
|
|
127
|
+
return xquik.request('/api/v1/x/profile/banner', {
|
|
128
|
+
method: 'PATCH',
|
|
129
|
+
body: { account: '@myaccount', url: 'https://example.com/banner.jpg' }
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
\`\`\`
|
|
133
|
+
|
|
134
|
+
### 8. Search tweets with pagination (Subscription required)
|
|
107
135
|
\`\`\`javascript
|
|
108
136
|
async () => {
|
|
109
137
|
// Use limit param for more than 20 results (max 200)
|
|
@@ -113,14 +141,87 @@ async () => {
|
|
|
113
141
|
}
|
|
114
142
|
\`\`\`
|
|
115
143
|
|
|
116
|
-
###
|
|
144
|
+
### 9. Look up a user or tweet
|
|
145
|
+
\`\`\`javascript
|
|
146
|
+
async () => {
|
|
147
|
+
// User profile (name, bio, followers, following, verified, location)
|
|
148
|
+
const user = await xquik.request('/api/v1/x/users/elonmusk');
|
|
149
|
+
// Single tweet with full metrics
|
|
150
|
+
const tweet = await xquik.request('/api/v1/x/tweets/1234567890');
|
|
151
|
+
// Check if A follows B
|
|
152
|
+
const follows = await xquik.request('/api/v1/x/followers/check', {
|
|
153
|
+
query: { source: 'userA', target: 'userB' }
|
|
154
|
+
});
|
|
155
|
+
return { user, tweet, follows };
|
|
156
|
+
}
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
### 10. Monitor an account + set up webhook
|
|
160
|
+
\`\`\`javascript
|
|
161
|
+
async () => {
|
|
162
|
+
// Create monitor for new tweets, replies, follower changes
|
|
163
|
+
const monitor = await xquik.request('/api/v1/monitors', {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
body: { username: 'elonmusk', eventTypes: ['tweet.new', 'tweet.reply', 'follower.gained'] }
|
|
166
|
+
});
|
|
167
|
+
// Set up webhook to receive events (save the secret!)
|
|
168
|
+
const webhook = await xquik.request('/api/v1/webhooks', {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
body: { url: 'https://your-server.com/webhook', eventTypes: ['tweet.new', 'tweet.reply'] }
|
|
171
|
+
});
|
|
172
|
+
return { monitor, webhook };
|
|
173
|
+
}
|
|
174
|
+
\`\`\`
|
|
175
|
+
|
|
176
|
+
### 11. Run a giveaway draw from tweet replies
|
|
177
|
+
\`\`\`javascript
|
|
178
|
+
async () => {
|
|
179
|
+
return xquik.request('/api/v1/draws', {
|
|
180
|
+
method: 'POST',
|
|
181
|
+
body: {
|
|
182
|
+
tweetUrl: 'https://x.com/user/status/1234567890',
|
|
183
|
+
winnerCount: 3,
|
|
184
|
+
backupCount: 2,
|
|
185
|
+
uniqueAuthorsOnly: true,
|
|
186
|
+
mustRetweet: true,
|
|
187
|
+
mustFollowUsername: 'myaccount',
|
|
188
|
+
filterMinFollowers: 50
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
### 12. Extract bulk data (followers, replies, communities)
|
|
195
|
+
\`\`\`javascript
|
|
196
|
+
async () => {
|
|
197
|
+
// Always estimate cost first
|
|
198
|
+
const estimate = await xquik.request('/api/v1/extractions/estimate', {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
body: { toolType: 'follower_explorer', targetUsername: 'elonmusk', resultsLimit: 1000 }
|
|
201
|
+
});
|
|
202
|
+
if (!estimate.allowed) return { error: 'Would exceed quota', estimate };
|
|
203
|
+
// Create extraction job
|
|
204
|
+
const job = await xquik.request('/api/v1/extractions', {
|
|
205
|
+
method: 'POST',
|
|
206
|
+
body: { toolType: 'follower_explorer', targetUsername: 'elonmusk', resultsLimit: 1000 }
|
|
207
|
+
});
|
|
208
|
+
return job;
|
|
209
|
+
// 20 tool types: reply_extractor, repost_extractor, quote_extractor, thread_extractor,
|
|
210
|
+
// article_extractor, follower_explorer, following_explorer, verified_follower_explorer,
|
|
211
|
+
// mention_extractor, post_extractor, community_extractor, community_moderator_explorer,
|
|
212
|
+
// community_post_extractor, community_search, list_member_extractor, list_post_extractor,
|
|
213
|
+
// list_follower_explorer, space_explorer, people_search, tweet_search_extractor
|
|
214
|
+
}
|
|
215
|
+
\`\`\`
|
|
216
|
+
|
|
217
|
+
### 13. Browse trending topics (FREE)
|
|
117
218
|
\`\`\`javascript
|
|
118
219
|
async () => {
|
|
119
220
|
return xquik.request('/api/v1/radar');
|
|
120
221
|
}
|
|
121
222
|
\`\`\`
|
|
122
223
|
|
|
123
|
-
###
|
|
224
|
+
### 14. Analyze a user's writing style
|
|
124
225
|
\`\`\`javascript
|
|
125
226
|
async () => {
|
|
126
227
|
// Returns cached style if available (free for all users)
|
|
@@ -132,7 +233,7 @@ async () => {
|
|
|
132
233
|
}
|
|
133
234
|
\`\`\`
|
|
134
235
|
|
|
135
|
-
###
|
|
236
|
+
### 15. Download media and get gallery link (Subscription required)
|
|
136
237
|
\`\`\`javascript
|
|
137
238
|
async () => {
|
|
138
239
|
// Returns galleryUrl only (shareable gallery page with all media)
|
|
@@ -143,14 +244,42 @@ async () => {
|
|
|
143
244
|
}
|
|
144
245
|
\`\`\`
|
|
145
246
|
|
|
146
|
-
###
|
|
247
|
+
### 16. Set up Telegram alerts for monitor events (FREE)
|
|
248
|
+
\`\`\`javascript
|
|
249
|
+
async () => {
|
|
250
|
+
return xquik.request('/api/v1/integrations', {
|
|
251
|
+
method: 'POST',
|
|
252
|
+
body: {
|
|
253
|
+
type: 'telegram',
|
|
254
|
+
chatId: '123456789',
|
|
255
|
+
eventTypes: ['tweet.new', 'tweet.reply', 'draw.completed', 'extraction.completed']
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
\`\`\`
|
|
260
|
+
|
|
261
|
+
### 17. Community actions (create, join, leave)
|
|
262
|
+
\`\`\`javascript
|
|
263
|
+
async () => {
|
|
264
|
+
// Join a community
|
|
265
|
+
await xquik.request('/api/v1/x/communities/99999/join', {
|
|
266
|
+
method: 'POST', body: { account: '@myaccount' }
|
|
267
|
+
});
|
|
268
|
+
// Leave a community
|
|
269
|
+
await xquik.request('/api/v1/x/communities/99999/join', {
|
|
270
|
+
method: 'DELETE', body: { account: '@myaccount' }
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
\`\`\`
|
|
274
|
+
|
|
275
|
+
### 18. Subscribe (FREE - returns Stripe checkout URL)
|
|
147
276
|
\`\`\`javascript
|
|
148
277
|
async () => {
|
|
149
278
|
return xquik.request('/api/v1/subscribe', { method: 'POST' });
|
|
150
279
|
}
|
|
151
280
|
\`\`\`
|
|
152
281
|
|
|
153
|
-
###
|
|
282
|
+
### 19. Draft & optimize tweet text (3-step compose flow, FREE)
|
|
154
283
|
\`\`\`javascript
|
|
155
284
|
async () => {
|
|
156
285
|
// Use this ONLY when the user wants help WRITING tweet text.
|