Skill: teltel-call-center/teltel-send-sms-text-message (version 1.0.1)

--- name: teltel-send-sms-text-message description: Send SMS text messages via TelTel (teltel.io) using the REST API (api.teltel.io). Includes bulk send, delivery report, and bulk sms. metadata: {"openclaw":{"emoji":"💬","homepage":"https://www.teltel.io/","primaryEnv":"TELTEL_API_KEY"}} --- Use the bundled Node scripts to send SMS via the TelTel API. ## Before you use the skill (TelTel prerequisites) 1) Register at **https://www.teltel.io/** 2) Add funds / credit to your TelTel account 3) From the TelTel **SMS** section, send a **test SMS** first to confirm your sender name/phone is accepted/verified 4) In TelTel **Settings**, find your **API key** 5) Enjoy ## Configure from the OpenClaw Skills panel ### API key field (shown in the Skills UI) This skill declares `TELTEL_API_KEY` as its **primary env var**, so the OpenClaw Skills UI can show an **API key** input for it. Under the hood it maps to: - `skills.entries.teltel-send-sms-text-message.apiKey` → `TELTEL_API_KEY` ### Default sender Set a default sender name/number (used when you do **not** pass `--from`): - `skills.entries.teltel-send-sms-text-message.env.TELTEL_SMS_FROM` ## Configure via environment variables (alternative) - `TELTEL_API_KEY` (required) - `TELTEL_SMS_FROM` (optional) — default sender name/number - `TELTEL_BASE_URL` (optional) — defaults to `https://api.teltel.io/v2` ## Send a single SMS ```bash node {baseDir}/scripts/send_sms.js \ --to "+3712xxxxxxx" \ --message "Hello from TelTel" \ --from "37167881855" ``` If you omit `--from`, the script uses `TELTEL_SMS_FROM`. Dry-run (prints URL + payload, does not send): ```bash node {baseDir}/scripts/send_sms.js \ --dry-run \ --to "+37111111111" \ --message "test" \ --from "37167881855" ``` ## Send bulk SMS ```bash node {baseDir}/scripts/send_sms_bulk.js \ --from "37167881855" \ --to "+3712...,+1..." \ --message "Hello everyone" ``` The `--to` list can be comma/newline/semicolon separated. ## API details (for reference) - Base URL: `https://api.teltel.io/v2` - Single SMS: `POST /sms/text` - JSON body: `{ "data": { "from": "...", "to": "+...", "message": "...", "callback": "https://..."? } }` - Bulk SMS: `POST /sms/bulk/text` - JSON body: `{ "data": { "from": "...", "to": ["+...", "+..."], "message": "...", "callback": "https://..."? } }` Notes: - `to` must be in international format.

path: scripts/send_sms.js
content: #!/usr/bin/env node
/**
 * TelTel SMS sender
 *
 * Usage:
 *   node send_sms.js --to "+3712xxxxxxx" --message "Hi" --from "37163030348" [--callback "https://..."] [--apikey "..."] [--dry-run]
 *
 * Env:
 *   TELTEL_API_KEY (preferred)
 *   TELTEL_SMS_FROM (optional default)
 */

const BASE_URL = process.env.TELTEL_BASE_URL || 'https://api.teltel.io/v2';

function parseArgs(argv) {
  const out = {};
  for (let i = 2; i < argv.length; i++) {
    const a = argv[i];
    if (!a.startsWith('--')) continue;
    const key = a.slice(2);
    if (key === 'dry-run') { out.dryRun = true; continue; }
    const val = argv[i + 1];
    i++;
    out[key] = val;
  }
  return out;
}

function requireField(obj, name) {
  if (!obj[name] || String(obj[name]).trim() === '') {
    console.error(`Missing required --${name}`);
    process.exit(2);
  }
}

async function main() {
  const args = parseArgs(process.argv);

  const [REDACTED_SECRET] || process.env.TELTEL_API_KEY;
  if (!apiKey && !args.dryRun) {
    console.error('Missing TELTEL_API_KEY (env) or --apikey');
    process.exit(2);
  }

  const from = (args.from || process.env.TELTEL_SMS_FROM || '').replace(/^\+/, '');
  const to = (args.to || '').trim();
  const message = args.message;
  const callback = args.callback;

  requireField({ to }, 'to');
  requireField({ message }, 'message');
  if (!from) {
    console.error('Missing --from (or TELTEL_SMS_FROM env).');
    process.exit(2);
  }

  const payload = {
    data: {
      from,
      to,
      message,
      ...(callback ? { callback } : {})
    }
  };

  const url = `${BASE_URL}/sms/text`;

  if (args.dryRun) {
    console.log(JSON.stringify({ url, payload }, null, 2));
    return;
  }

  const res = await fetch(url, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'x-api-key': apiKey,
    },
    body: JSON.stringify(payload),
  });

  const text = await res.text();
  let json;
  try { json = JSON.parse(text); } catch { json = null; }

  if (!res.ok) {
    console.error(`TelTel API error: HTTP ${res.status}`);
    console.error(text);
    process.exit(1);
  }

  console.log(JSON.stringify(json ?? { raw: text }, null, 2));
}

main().catch((err) => {
  console.error(err?.stack || String(err));
  process.exit(1);
});


path: scripts/send_sms_bulk.js
content: #!/usr/bin/env node
/**
 * TelTel bulk SMS sender
 *
 * Usage:
 *   node send_sms_bulk.js --to "+3712..., +3712..." --message "Hi" --from "37163030348" [--callback "https://..."] [--apikey "..."] [--dry-run]
 */

const BASE_URL = process.env.TELTEL_BASE_URL || 'https://api.teltel.io/v2';

function parseArgs(argv) {
  const out = {};
  for (let i = 2; i < argv.length; i++) {
    const a = argv[i];
    if (!a.startsWith('--')) continue;
    const key = a.slice(2);
    if (key === 'dry-run') { out.dryRun = true; continue; }
    const val = argv[i + 1];
    i++;
    out[key] = val;
  }
  return out;
}

function splitToList(s) {
  return String(s || '')
    .split(/[\n,;]+/)
    .map(x => x.trim())
    .filter(Boolean);
}

async function main() {
  const args = parseArgs(process.argv);
  const [REDACTED_SECRET] || process.env.TELTEL_API_KEY;
  if (!apiKey && !args.dryRun) {
    console.error('Missing TELTEL_API_KEY (env) or --apikey');
    process.exit(2);
  }

  const from = (args.from || process.env.TELTEL_SMS_FROM || '').replace(/^\+/, '');
  const toList = splitToList(args.to);
  const message = args.message;
  const callback = args.callback;

  if (!from) {
    console.error('Missing --from (or TELTEL_SMS_FROM env).');
    process.exit(2);
  }
  if (!toList.length) {
    console.error('Missing --to (comma/newline separated list).');
    process.exit(2);
  }
  if (!message) {
    console.error('Missing --message');
    process.exit(2);
  }

  const payload = {
    data: {
      from,
      to: toList,
      message,
      ...(callback ? { callback } : {})
    }
  };

  const url = `${BASE_URL}/sms/bulk/text`;

  if (args.dryRun) {
    console.log(JSON.stringify({ url, payload }, null, 2));
    return;
  }

  const res = await fetch(url, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'x-api-key': apiKey,
    },
    body: JSON.stringify(payload),
  });

  const text = await res.text();
  let json;
  try { json = JSON.parse(text); } catch { json = null; }

  if (!res.ok) {
    console.error(`TelTel API error: HTTP ${res.status}`);
    console.error(text);
    process.exit(1);
  }

  console.log(JSON.stringify(json ?? { raw: text }, null, 2));
}

main().catch((err) => {
  console.error(err?.stack || String(err));
  process.exit(1);
});


Security scan verdicts — ClawScan: clean | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)