simple_node_characterai
v1.1.2
Published
Simple Node.js library for interacting with Character.AI via HTTP and WebSocket with typescript
Maintainers
Readme
THIS PACKAGE HEAVILY INSPIRED BY node_characterai PACKAGE.
Character AI (Node) Package
Simple Node.js library for interacting with Character.AI via HTTP and WebSocket with typescript. It provides simple primitives to authenticate, create chats, send messages, and fetch chat turns. Perfect usage for route handlers in Node.js applications that need interactions with Character.AI in custom interface.
Features
- Authenticate with a session token and initialize a WebSocket
- Create one-on-one chats with characters
- Send messages and await final replies
- Fetch chat turns (messages) with pagination
- Minimal, typed API with clear data models
Installation
npm install simple_node_characteraiQuick Start
import { authenticate, createNewConversation, sendMessage, getMessages, getProfile } from 'simple_node_characterai';
(async () => {
// 1) Authenticate with your session token (string without "Token " prefix is fine)
await authenticate('YOUR_SESSION_TOKEN');
// 2) Access the authenticated user profile
const profile = getProfile();
console.log('Logged in as:', profile.user.username);
// 3) Create a new chat with a character
const characterId = 'CHARACTER_ID';
const addTurn = await createNewConversation(characterId);
const chatId = addTurn.turn.turn_key.chat_id;
// 4) Send a message and wait for the final candidate
const response = await sendMessage('Hello!', characterId, chatId);
console.log(response.turn.candidates[0].raw_content);
// 5) Fetch latest turns (up to 50)
const turns = await getMessages(chatId);
console.log('Turns count:', turns.length);
})();Example with Hono Route Handler
import { Hono } from 'hono'
import { authenticate, createNewConversation, sendMessage, getMessages, getProfile } from 'simple_node_characterai';
const app = new Hono();
(async () => {
await authenticate(process.env.CHARACTERAI_TOKEN!);
})();
// Creates a new one-on-one conversation
// Body: { characterId: string } -> Response: { chatId: string }
app.post('/conversations', async (c) => {
try {
const body = await c.req.json();
const characterId = body?.characterId;
if (!characterId) return c.json({ error: 'characterId is required' }, 400);
const addTurn = await createNewConversation(characterId);
const chatId = addTurn.turn.turn_key.chat_id;
return c.json({ chatId });
} catch (e) {
return c.json({ error: 'failed to create conversation' }, 500);
}
});
// Sends a message to a conversation and returns the final content
// Body: { message: string, characterId: string, chatId: string }
// Make sure to store the characterId and chatId somewhere, like Database
// The messages field can be get in response.turn.candidates[0].raw_content
app.post('/messages', async (c) => {
try {
const body = await c.req.json();
const message = body?.message;
const characterId = body?.characterId;
const chatId = body?.chatId;
if (!message || !characterId || !chatId) {
return c.json({ error: 'message, characterId, and chatId are required' }, 400);
}
const response = await sendMessage(message, characterId, chatId);
const final = response.turn.candidates?.[0];
return c.json({
turn: response.turn,
content: final?.raw_content ?? null
});
} catch (e) {
return c.json({ error: 'failed to send message' }, 500);
}
});
// Fetches up to 50 turns for the given chatId
// Optional query: ?token=NEXT_TOKEN for pagination
// Token will be available in meta field of response if there's more turns to fetch.
app.get('/messages/:chatId', async (c) => {
try {
const chatId = c.req.param('chatId');
const token = c.req.query('token') ?? undefined;
const messages = await getMessages(chatId, token);
return c.json({ turns: messages.turns, token: messages.meta.next_token });
} catch (e) {
return c.json({ error: 'failed to fetch messages' }, 500);
}
});
export default appFind Authorization Token
- Logged in to character.ai
- Make sure to select any character first
- Open the developer tools F12, FN + F12, CTRL + SHIFT + I
- Go to
Applicationtab - Navigate to Cookies section, and select https://character.ai cookies
- Look up for
HTTP_AUTHORIZATIONtoken with string that starts withToken - If token doesn't present, refresh the page and see the token again
- Copy the value
Sometimes the token will show up for a minutes and dissapear.
Find Character ID and Chat ID
Logged in to character.ai, and select a character you want to chat, then look up at URL, the URL contains the Character and Chat ID with following detail:
https://character.ai/chat/{characterId}?hist={chatId}API Reference
Auth
authenticate(sessionToken: string): Promise
- Authenticates the user, validates the token, loads the profile, and opens the WebSocket.
- Accepts either raw token or
"Token XXX"format.
getProfile(): Profile
- Returns the in-memory authenticated user profile.
Chat
createNewConversation(characterId: string): Promise
- Creates a new one-on-one chat with the specified character and resolves when the greeting turn arrives.
- Returns metadata and the initial turn.
sendMessage(message: string, characterId: string, chatId: string): Promise
- Sends a user message to an existing chat.
- Resolves when the model returns a final candidate for the turn.
getMessages(chatId: string, token?: string): Promise<Turn[]>
- Retrieves up to 50 turns for the given chat.
- If a
tokenis provided, fetches the next page of results usingnext_token.
Notes
- This package is intended for personal use.
- Avoid logging tokens, cookies, or PII; keep sensitive information in memory.
- When building client-side applications, follow CORS restrictions; this package is designed for server-side Node usage.
Development
Still in development but ready to use for basic chatting usage, more feature will be added in the future.
