smsbower
v0.5.1
Published
Node.js TypeScript SDK for the SMSBower client API.
Downloads
34
Maintainers
Readme
smsbower
TypeScript SDK for the SMSBower handler API, scoped to Node.js 18+.
Runtime scope
This package is for Node.js only. Browser runtimes are not supported.
Install
npm install smsbowerConfiguration
createSmsBowerClient accepts:
apiKey(required)baseUrl(optional, defaults to the SMSBower handler endpoint)timeoutMs(optional)userAgent(optional)
Initialize client
import { createSmsBowerClient } from "smsbower";
const client = createSmsBowerClient({
apiKey: process.env.SMSBOWER_API_KEY!,
timeoutMs: 15_000,
});Core endpoint usage
import { createSmsBowerClient } from "smsbower";
const client = createSmsBowerClient({ apiKey: process.env.SMSBOWER_API_KEY! });
const balance = await client.getBalance();
const services = await client.getServicesList();
const countries = await client.getCountries();
const prices = await client.getPrices({ service: "ot", country: 6 });
const pricesV2 = await client.getPricesV2({ service: "ot", country: 6 });
const pricesV3 = await client.getPricesV3({ country: 6, service: "ot", providerIds: [2295, 3027] });
console.log(balance.token, Object.keys(services.value).length);
console.log(Object.keys(countries.value).length, prices.value, pricesV2.value, pricesV3.value);Activation endpoint usage
import { createSmsBowerActivationEndpoints, createSmsBowerClient } from "smsbower";
const client = createSmsBowerClient({ apiKey: process.env.SMSBOWER_API_KEY! });
const activation = createSmsBowerActivationEndpoints(client);
const number = await activation.getNumber({ service: "ot", country: 6, providerIds: [2295, 3027] });
const status = await activation.getStatus({ activationId: number.activationId });
const lifecycle = await activation.setStatus({ activationId: number.activationId, status: 1 });
console.log(number.phoneNumber, status.token, lifecycle.token);Error handling
import {
SmsBowerApiError,
SmsBowerParseError,
SmsBowerTransportError,
createSmsBowerClient,
} from "smsbower";
const client = createSmsBowerClient({ apiKey: process.env.SMSBOWER_API_KEY! });
try {
await client.getBalance();
} catch (error) {
if (error instanceof SmsBowerApiError) {
console.error("API rejected the request", { code: error.code, token: error.token });
} else if (error instanceof SmsBowerParseError) {
console.error("Response could not be parsed", { code: error.code, token: error.token });
} else if (error instanceof SmsBowerTransportError) {
console.error("Transport failed", { code: error.code, status: error.status });
} else {
throw error;
}
}Migration notes (0.2.0)
getServicesListnow accepts both response input shapes:- legacy map:
{ [code]: name } - wrapped payload:
{ status, services: [{ code, name }] }
- legacy map:
- The SDK always normalizes
getServicesListoutput to the canonical map shape (Record<string, string>) inservices.value. - For wrapped payload duplicates, the last item for a given
codewins. - Wrapped
servicesitems with invalidcode/nameare ignored when valid entries exist; if no valid entries remain, the SDK throwsSmsBowerParseErrorwith codeMALFORMED_JSON. - The unsupported wallet endpoint was removed because the upstream action is invalid (
BAD_ACTION); migrate by removing wallet endpoint usage from consumer code.
Compatibility notes (0.3.0)
getCountriesskips malformed upstream entries when valid country rows still exist.getPricessupports country-first quote payloads from live API and normalizes to canonical SDK output.getPricesV2supports live bucket-map payloads (price -> count).getPricesV3accepts provider quote objects usingpriceas well ascost.
Local quality gates
npm run lint
npm run typecheck
npm run typecheck:contracts
npm test
npm run build
npm run pack:checkIntegration tests are opt-in and env-gated:
npm run test:integrationSet these vars when you want live integration checks:
SMSBOWER_API_KEYSMSBOWER_SERVICESMSBOWER_COUNTRYSMSBOWER_PROVIDER_IDS
License
MIT
