@strafe-js/rest
v1.3.0
Published
REST client for the Strafe Chat API
Readme
Overview
@strafe-js/rest is the standalone HTTP REST client for the Strafe Chat API. It uses Node.js native fetch and FormData, handles Bot and Bearer authorization headers, automatically retries HTTP 429 Too Many Requests responses using retry_after / Retry-After, and provides strongly-typed methods for all core Strafe endpoints.
Installation
Node.js 18 or newer is required.
npm install @strafe-js/rest @strafe-js/utilQuick Start
import { REST } from '@strafe-js/rest';
const rest = new REST({
baseUrl: 'https://app.strafe.chat/api',
token: process.env.BOT_TOKEN,
authScheme: 'Bot',
retries: 3,
});
// Fetch current bot user
const me = await rest.getMe();
console.log(`Authenticated as ${me.username} (${me.id})`);
// Send a message to a room
await rest.createMessage('112233445566778899', {
plaintext: 'Hello from @strafe-js/rest!',
});Constructor Options (RESTOptions)
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| baseUrl | string | Required | Base URL of the Strafe REST API (https://app.strafe.chat/api) |
| token | string | undefined | Authentication token (can also be set via rest.setToken(token)) |
| authScheme | 'Bot' \| 'Bearer' | 'Bot' | Prefix for the Authorization header |
| retries | number | 3 | Maximum automatic retries on HTTP 429 rate-limit responses |
| userAgent | string | 'strafebot-js/1.2' | Custom User-Agent header |
API Reference
Low-Level HTTP Methods
rest.setToken(token: string): this: Updates the authentication token at runtime.rest.request<T>(opts: RequestOptions): Promise<T>: Executes an HTTP request with query serialization, JSON orFormDatabody encoding, and429retry handling.rest.get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>rest.post<T>(path: string, body?: unknown): Promise<T>rest.patch<T>(path: string, body?: unknown): Promise<T>rest.put<T>(path: string, body?: unknown): Promise<T>rest.delete<T>(path: string, body?: unknown): Promise<T>
Users & Spaces
rest.getMe(): Promise<User>:GET /users/@merest.getMySpaces(): Promise<Space[]>(alias:rest.getSpaces()):GET /users/@me/spacesrest.getSpace(spaceId: Snowflake): Promise<Space>:GET /spaces/:spaceIdrest.getSpaceRooms(spaceId: Snowflake): Promise<Room[]>:GET /spaces/:spaceId/roomsrest.getSpaceMembers(spaceId: Snowflake): Promise<SpaceMember[]>:GET /spaces/:spaceId/membersrest.getSpaceMember(spaceId: Snowflake, userId: Snowflake): Promise<SpaceMember>:GET /spaces/:spaceId/members/:userId
Messages & Reactions
rest.createMessage(roomId: Snowflake, body: CreateMessageBody | string): Promise<Message>:POST /rooms/:roomId/messagesrest.editMessage(roomId: Snowflake, messageId: Snowflake, body: EditMessageBody | string): Promise<Message>:PATCH /rooms/:roomId/messages/:messageIdrest.deleteMessage(roomId: Snowflake, messageId: Snowflake): Promise<void>:DELETE /rooms/:roomId/messages/:messageIdrest.listMessages(roomId: Snowflake, params?: { limit?: number; before?: Snowflake; after?: Snowflake }): Promise<Message[]>:GET /rooms/:roomId/messagesrest.getMessage(roomId: Snowflake, messageId: Snowflake): Promise<Message>:GET /rooms/:roomId/messages/:messageIdrest.triggerTyping(roomId: Snowflake): Promise<void>:POST /rooms/:roomId/typingrest.addReaction(roomId: Snowflake, messageId: Snowflake, emoji: string): Promise<void>:PUT /rooms/:roomId/messages/:messageId/reactions/:emojirest.removeReaction(roomId: Snowflake, messageId: Snowflake, emoji: string, userId?: Snowflake): Promise<void>:DELETE /rooms/:roomId/messages/:messageId/reactions/:emoji/:userId
Invites, Moderation & Attachments
rest.createInvite(spaceId: Snowflake, opts?: { max_uses?: number; max_age?: number; room_id?: Snowflake }): Promise<{ code: string }>:POST /spaces/:spaceId/invitesrest.kickMember(spaceId: Snowflake, userId: Snowflake): Promise<void>:DELETE /spaces/:spaceId/members/:userIdrest.banMember(spaceId: Snowflake, userId: Snowflake, reason?: string): Promise<void>:PUT /spaces/:spaceId/bans/:userIdrest.uploadAttachment(file: Blob | Buffer, filename: string, uploadUrl?: string): Promise<Attachment>: Uploads a binary file viamultipart/form-data.
Error Handling
Non-2xx responses throw StrafeError or RateLimitError (from @strafe-js/util):
import { StrafeError, RateLimitError } from '@strafe-js/util';
try {
await rest.createMessage(roomId, 'Hello!');
} catch (err) {
if (err instanceof RateLimitError) {
console.error(`Rate limited! Retry after ${err.retryAfter}s`);
} else if (err instanceof StrafeError) {
console.error(`HTTP ${err.status} (${err.code}): ${err.message}`);
}
}License
Apache-2.0
