x-tweet-speedread-skill
X Tweet Speedread (Premium) — instant English brief for any X post. Charge-first direct mode via SkillPay (0.001 USDT/call).
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-x-tweet-speedread-skill
Repository
Skill path: skills/huangkefeng-ai/x-tweet-speedread-skill
X Tweet Speedread (Premium) — instant English brief for any X post. Charge-first direct mode via SkillPay (0.001 USDT/call).
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install x-tweet-speedread-skill into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding x-tweet-speedread-skill to shared team environments
- Use x-tweet-speedread-skill for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: x-tweet-speedread-skill
description: X Tweet Speedread (Premium) — instant English brief for any X post. Charge-first direct mode via SkillPay (0.001 USDT/call).
---
# X Tweet Speedread (Premium)
Paste an X URL, get an instant English speedread.
## Pricing
- **0.001 USDT per call** (1 token)
- Charge-first model
- Low balance => return `PAYMENT_URL`
## What it returns
- 3–5 key bullets
- 1 core takeaway
- up to 3 risks
- up to 3 actions
## Run
```bash
node scripts/run.js --url "https://x.com/.../status/..." --user "<user-id>"
```
## Billing behavior
- Calls SkillPay billing directly before extraction.
- If balance is low, returns `PAYMENT_URL` and `PAYMENT_INFO`.
- If charge succeeds, continues to fetch and summarize the X post.
## Optional overrides
- `SKILLPAY_BILLING_URL`
- `SKILL_BILLING_API_KEY`
- `SKILL_ID`
- `SKILLPAY_PRICE_TOKEN`
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/run.js
```javascript
#!/usr/bin/env node
/**
* X Tweet Speedread Skill (Direct mode, no custom backend)
* 1) Charge via SkillPay
* 2) Fetch X post text with fallback
* 3) Output English speedread summary
*/
const args = process.argv.slice(2);
const getArg = (name) => {
const i = args.indexOf(`--${name}`);
return i >= 0 ? args[i + 1] : undefined;
};
const url = getArg('url');
const userId = getArg('user') || 'anonymous';
if (!url) {
console.error('Usage: node scripts/run.js --url <x-status-url> --user <user-id>');
process.exit(1);
}
const BILLING_URL = process.env.SKILLPAY_BILLING_URL || 'https://skillpay.me/api/v1/billing';
const SKILL_BILLING_API_KEY = process.env.SKILL_BILLING_API_KEY || 'sk_74e1969ebc92fcf58257470c50f8bb76e36c9da0d201aa69861e28c62f5bd48e';
const SKILL_ID = process.env.SKILL_ID || '607813fc-caa5-4bd6-86fb-651f4cc6deb9';
const SKILLPAY_PRICE_TOKEN = Number(process.env.SKILLPAY_PRICE_TOKEN || '1');
async function getPaymentLink(userId, amount = 7) {
const endpoint = `${BILLING_URL}/payment-link`;
const res = await fetch(endpoint, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': SKILL_BILLING_API_KEY,
},
body: JSON.stringify({ user_id: userId, amount }),
}).catch(() => null);
if (!res) return null;
try {
const data = await res.json();
return data?.payment_url || null;
} catch {
return null;
}
}
async function charge() {
if (!SKILL_BILLING_API_KEY || !SKILL_ID) {
return { ok: false, reason: 'missing_billing_config' };
}
const endpoint = `${BILLING_URL}/charge`;
const res = await fetch(endpoint, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': SKILL_BILLING_API_KEY,
},
body: JSON.stringify({
user_id: userId,
skill_id: SKILL_ID,
amount: SKILLPAY_PRICE_TOKEN,
meta: { source: 'x-tweet-speedread-skill' },
}),
}).catch(() => null);
if (!res) return { ok: false, reason: 'network_error' };
let data = null;
try { data = await res.json(); } catch {}
if (!res.ok || !data) return { ok: false, reason: 'charge_failed', data };
if (data.success) return { ok: true, data };
const paymentUrl = await getPaymentLink(userId, 7);
if (paymentUrl) data.payment_url = paymentUrl;
return { ok: false, reason: 'insufficient_balance', data };
}
function toJina(u) {
return `https://r.jina.ai/http://${u.replace(/^https?:\/\//, '')}`;
}
function extractStatusId(u) {
const m = u.match(/status\/(\d+)/);
return m ? m[1] : null;
}
async function fetchText() {
const attempts = [];
const looksBad = (t) => {
if (!t || t.length < 40) return true;
const badMarkers = [
'JavaScript is not available',
'stylesheet-group',
'Please enable JavaScript',
'.css-175oi2r',
];
return badMarkers.some((m) => t.includes(m));
};
const tryFetch = async (label, target) => {
const r = await fetch(target).catch(() => null);
if (!r || !r.ok) {
attempts.push({ label, ok: false });
return null;
}
const t = await r.text();
if (looksBad(t)) {
attempts.push({ label, ok: false, reason: 'bad_content' });
return null;
}
attempts.push({ label, ok: true });
return t;
};
let text = await tryFetch('jina', toJina(url));
const sid = extractStatusId(url);
if (!text && sid) {
text = await tryFetch('fxtwitter-i', `https://api.fxtwitter.com/i/status/${sid}`);
if (!text) text = await tryFetch('fxtwitter', `https://api.fxtwitter.com/status/${sid}`);
}
if (!text) text = await tryFetch('direct', url);
return { text: text || '', attempts };
}
function clean(raw) {
return raw
.replace(/<[^>]+>/g, ' ')
.replace(/\s+/g, ' ')
.replace(/Title:\s*/gi, '')
.trim();
}
function splitSentences(text) {
return text
.split(/(?<=[。!?!?\.])\s+/)
.map((s) => s.trim())
.filter(Boolean);
}
function summarizeEn(text) {
const s = splitSentences(text);
const picks = s.slice(0, 5);
const core = picks[0] || 'No clear core point found.';
return {
bullets: picks,
core,
risks: [
'The post may contain subjective bias and should be verified.',
'Income/performance claims may be non-reproducible.',
'Use small-scale validation before any paid or trading action.',
],
actions: [
'Run a low-cost reproducibility test first.',
'Split workflow into input → processing → output → billing.',
'Track 7-day data before scaling effort or spend.',
],
};
}
(async () => {
const chargeResult = await charge();
if (chargeResult.ok !== true) {
const paymentUrl = chargeResult?.data?.payment_url || null;
if (paymentUrl) {
console.error(`PAYMENT_URL:${paymentUrl}`);
console.error('PAYMENT_INFO:Insufficient balance. Top up and retry this same command.');
}
console.error(JSON.stringify({
ok: false,
stage: 'billing',
code: chargeResult?.reason || 'billing_failed',
message: 'Billing required: charge failed, config missing, or insufficient balance',
payment_url: paymentUrl,
topup_min_usdt: 7,
chargeResult,
}, null, 2));
process.exit(2);
}
const { text, attempts } = await fetchText();
if (!text) {
console.error(JSON.stringify({ ok: false, stage: 'fetch', attempts }, null, 2));
process.exit(3);
}
const cleaned = clean(text);
const summary = summarizeEn(cleaned);
console.log(JSON.stringify({
ok: true,
charged: true,
billing: chargeResult,
attempts,
input: url,
summary,
}, null, 2));
})();
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "huangkefeng-ai",
"slug": "x-tweet-speedread-skill",
"displayName": "X Tweet Speedread",
"latest": {
"version": "1.2.2",
"publishedAt": 1772723142712,
"commit": "https://github.com/openclaw/skills/commit/b64feea9c6b5586007d107bb1aed229c70e27ae5"
},
"history": []
}
```