CAINode
CAINode copied to clipboard
The Lightweight Unofficial Character.AI API for Node.js / Deno / Bun.
CAINode
A lighweight Unofficial Character.AI API in Node/Deno/Bun JS, It does not require a puppeteer to interact with c.ai because the interaction is conducted with websocket and HTTPS Request (fetch).
CAINode is now using ESM. Please read at Getting Started first before using CAINode.
Features
- Lightweight library (WebSocket and Fetch)
- Easy to use
- Almost all Character.AI Support
- Voice Call
- Single/Group chat
- Image Generate
- User
- Persona
- Explore list
Table of contents
- Getting Started
- Install
- Example Usage
- Main Function List
- login
- generate_token
- logout
- User Function List
- user.info
- user.change_info
- user.settings
- user.public_following_list
- user.public_followers_list
- user.following_list_name
- user.followers_list_name
- user.follow
- user.unfollow
- Image Function List
- image.generate_avatar
- image.generate_image
- Persona Function List
- persona.create
- persona.set_default
- persona.list
- persona.info
- persona.update
- persona.delete
- persona.set_character
- Explore Function List
- explore.featured
- explore.for_you
- explore.simillar_char
- explore.character_categories
- Character Function list
- character.votes
- character.votes_array
- character.vote
- character.search
- character.search_suggest
- character.info
- character.recent_list
- character.connect
- character.disconnect
- character.send_message
- character.generate_turn
- character.generate_turn_candidate
- character.create_new_conversation
- character.delete_message
- character.edit_message
- character.replay_tts
- character.current_voice
- Group Chat Function List
- group_chat.list
- group_chat.connect
- group_chat.disconnect
- group_chat.create
- group_chat.delete
- group_chat.rename
- group_chat.join_group_invite
- group_chat.char_add
- group_chat.char_remove
- group_chat.send_message
- group_chat.generate_turn
- group_chat.generate_turn_candidate
- group_chat.reset_conversation
- group_chat.delete_message
- group_chat.edit_message
- group_chat.select_turn
- Chat Function List
- chat.history_chat_turns
- chat.conversation_info
- chat.history_conversation_list
- chat.set_conversation_chat
- chat.pin_message
- chat.list_pinned_message
- chat.archive_conversation
- chat.duplicate_conversation
- chat.rename_conversation
- Voice Function List
- voice.user_created_list
- voice.info
- voice.search
- voice.connect
- voice.disconnect
- Issues
Getting Started
Install
To install CAINode, you can simply do
- using NPM (Node Package Manager)
npm install -g cainode - Using Deno
import CAINode from "npm:cainode@latest"; - Using Bun.JS
bun install cainode
Back to the Table of contents
Example usage
- CommonJS
(async function() { const client = new (await import("cainode")).CAINode(); await client.login("Your token"); console.log("Logged in!"); await client.logout(); })() - TypeScript/ESM
import {CAINode} from "cainode" // import {CAINode} from "npm:cainode@latest"; for Deno const client = new CAINode(); await client.login("Your token"); console.log("Logged in!"); await client.logout();
Back to the Table of contents
Main Function List
-
login()
Start client initialization with login, make sure your token is valid so that the login session can run properly.
To get Character.AI Session Token, You can use generate_token() function.
await client.login("YOUR_CHARACTER_AI_TOKEN");Param Require Type Description Token truestringYour Character.AI token used for client login. Back to the Table of contents
-
generate_token()
Generate your Character.AI Token by email.
-
Without timeout
await client.generate_token("[email protected]", 0); -
With timeout (per 2 seconds)
await client.generate_token("[email protected]", 30); // and it will end in 60 seconds. -
With callback
await client.generate_token("[email protected]", 30, function() { console.log("Please check your email.") }, function() { console.log("Time is up! Please try again later.") });
Param Require Type Description email truestringYour email to send a verification link. timeout_per_2s falsenumberMax waiting for verification. (default = 30) mail_sent_cb falseFunctionCallback when the mail was sent to the target. timeout_cb falseFunctionCallback when the timeout was reached. Back to the Table of contents
-
-
logout()
Logout from the client.
await client.logout();Param Require Type Description none falsenullUsed for client logout from character ai. Back to the Table of contents
User Function List
-
user.info()
Get current information account.
console.log(client.user.info);Param Require Type Description none falsenullGet user information account. Back to the Table of contents
-
user.public_info()
Get user public information account.
await client.user.public_info();Param Require Type Description username falsestringTarget Character.AI username account. (default = null, and it will target to your own account.) Back to the Table of contents
-
user.change_info()
Change current information account.
await client.user.change_info();Param Require Type Description username falsestringChange your old username to new username. name falsestringChange your old name to new name. avatar_rel_path falsestringChange your old avatar_rel_path link to new avatar_rel_path link.
Warning: avatar_rel_path image link must be generated/uploaded to Character.AI server.bio falsestringChange your old bio to new bio. Back to the Table of contents
-
user.settings()
Get account settings information data.
await client.user.settings();Param Require Type Description none falsenullGet user settings information. Back to the Table of contents
-
user.public_following_list()
Get public user following list.
await client.user.public_following_list();Param Require Type Description username truestringTarget Character.AI username account. page_param falsenumberPage parameter. Back to the Table of contents
-
user.public_followers_list()
Get public user followers list.
await client.user.public_followers_list();Param Require Type Description username truestringTarget Character.AI username account. page_param falsenumberPage parameter. Back to the Table of contents
-
user.following_list_name()
Get account following name list.
await client.user.following_list_name();Param Require Type Description none falsenullGet account following name list. Back to the Table of contents
-
user.followers_list_name()
Get account followers name list.
await client.user.followers_list_name();Param Require Type Description none falsenullGet account followers name list. Back to the Table of contents
-
user.follow()
Follow user account.
await client.user.follow();Param Require Type Description username truestringTarget Character.AI username account. Back to the Table of contents
-
user.unfollow()
Unfollow user account.
await client.user.unfollow();Param Require Type Description username truestringTarget Character.AI username account. Back to the Table of contents
Image Function List
-
image.generate_avatar()
Generate avatar image using prompt.
await client.image.generate_avatar(prompt_name);Param Require Type Description prompt_name trueStringPrompt used for generating avatar image. Back to the Table of contents
-
image.generate_image()
Generate image using prompt.
await client.image.generate_image(prompt_name);Param Require Type Description prompt_name trueStringPrompt used for generating AI image. Back to the Table of contents
Persona Function List
-
persona.create()
Create your personality for your character.
await client.persona.create(name, description);Param Require Type Description name trueStringYour persona name description trueStringDescription of your personality, this section is used to describe yourself so that your AI character knows who you are. Back to the Table of contents
-
persona.set_default()
Set your default personality specifically.
await client.persona.set_default(external_persona_id);Param Require Type Description external_persona_id trueStringExternal personality id that you have. Back to the Table of contents
-
persona.list()
Get all your personality data.
await client.persona.list();Param Require Type Description none falsenullGet all your personality data. Back to the Table of contents
-
persona.info()
Get your personality information.
await client.persona.info(external_persona_id);Param Require Type Description external_persona_id trueStringExternal personality id that you have. Back to the Table of contents
-
persona.update()
Update your personality specifically.
await client.persona.update(external_persona_id, name, description);Param Require Type Description external_persona_id trueStringExternal personality id that you have. name trueStringYour new personality name. description trueStringYour new personality detail. Back to the Table of contents
-
persona.delete()
Used for deleting your personality spesifically.
await client.persona.delete(external_persona_id);Param Require Type Description external_persona_id trueStringExternal personality id that you have. Back to the Table of contents
-
persona.set_character()
Set a custom personality for your character specifically.
await client.persona.set_character(character_id, external_persona_id);Param Require Type Description character_id trueStringA character id that you want to set a custom personality. external_persona_id trueStringYour personality id that you use to let AI characters know who you are. Back to the Table of contents
Explore Function List
-
explore.featured()
Get the list of characters displayed by the character.ai server.
await client.explore.featured();Param Require Type Description none falsenullGet all featured data. Back to the Table of contents
-
explore.for_you()
Get a list of characters recommended by the character.ai server.
await client.explore.for_you();Param Require Type Description none falsenullGet all for you data. Back to the Table of contents
-
explore.simillar_char()
Get the list simillar character from ID character.
await client.explore.simillar_char(char_id);Param Require Type Description char_id truestringCharacter ID. Back to the Table of contents
-
explore.character_categories()
Get the list of characters from the character category exploration.
await client.explore.character_categories();Param Require Type Description none falsenullGet all character categories data. Back to the Table of contents
Character Function List
-
character.votes()
Get character vote information.
await client.character.votes(character_id);Param Require Type Description character_id trueStringThe character id you are aiming for. Back to the Table of contents
-
character.votes_array()
Get character vote information in array.
await client.character.votes_array(character_id);Param Require Type Description character_id trueStringThe character id you are aiming for. Back to the Table of contents
-
character.vote()
Used for vote the character.
await client.character.vote(character_id, vote);Param Require Type Description character_id trueStringThe character id you are aiming for. vote trueBooleanCharacter vote options, true = like,false = dislike, andnull = cancelBack to the Table of contents
-
character.search()
Search for a character by name or query.
await client.character.search(name);Param Require Type Description name trueStringSearch queries to find characters. Back to the Table of contents
-
character.search_suggest()
Search character by name and suggested by Character.AI Server
await client.character.search_suggest(name);Param Require Type Description name trueStringCharacter name query. Back to the Table of contents
-
character.info()
Get detailed information about characters.
await client.character.info(character_id);Param Require Type Description character_id trueStringYour character id. Back to the Table of contents
-
character.recent_list()
Get a list of recent chat activity
await client.character.recent_list();Param Require Type Description none falsenullGet recent character chats. Back to the Table of contents
-
character.connect()
Connect client to character chat
await client.character.connect(character_id);Param Require Type Description character_id trueStringYour character id. Back to the Table of contents
-
character.disconnect()
Disconnecting client from character chat
await client.character.disconnect();Param Require Type Description none falsenullDisconnecting client from character chat. Back to the Table of contents
-
character.send_message()
Send message to character.
await client.character.send_message(message, manual_turn, image_url);Param Require Type Description message trueStringMessage content. manual_turn falseBooleanIf the value of manual_turnis set totruethen the message that the client receives must be generated withcharacter.generate_turn()so that the message is obtained by the client.image_url falseStringThe image content that the character will see, must be a url and not a file type or a file with a type other than image. Back to the Table of contents
-
character.generate_turn()
Generating message response from character.
await client.character.generate_turn();Param Require Type Description none falsenullGenerate message response Back to the Table of contents
-
character.generate_turn_candidate()
Regenerate character message.
await client.character.generate_turn_candidate(turn_id);Param Require Type Description turn_id trueStringturn_idormessage_idfrom the character.Back to the Table of contents
-
character.create_new_conversation()
it will create a new conversation and your current conversation will save on the history.
- With greeting
await client.character.create_new_conversation(); - Without greeting
await client.character.create_new_conversation(false);
Param Require Type Description with_greeting falseBooleanThe character will send you a greeting when you create a new conversation. (Default = true) Back to the Table of contents
- With greeting
-
character.delete_message()
Delete character message.
await client.character.delete_message(turn_id);Param Require Type Description turn_id trueStringturn_idormessage_idfrom the character.Back to the Table of contents
-
character.edit_message()
Edit the character message.
await client.character.edit_message(candidate_id, turn_id, new_message);Param Require Type Description candidate_id trueStringturn_id trueStringturn_idormessage_idfrom the character.new_message trueStringNew character message Back to the Table of contents
-
character.replay_tts()
Generate text messages from character to voice audio.
- if you have Voice ID
await client.character.replay_tts("Turn ID", "Candidate ID", "fill the Voice Character ID here") - if you don't have Voice ID and want to use Voice Query instead
await client.character.replay_tts("Turn ID", "Candidate ID", "Sonic the Hedgehog", true)
Param Require Type Description turn_id trueStringturn_idfrom the character.candidate_id trueStringcandidate_idfrom the character.voice_id_or_query trueStringInput Voice character ID or you can use Voice Query. using_query falseBooleanUsing Query (if You're using Voice Query, then set this parameter to true.)Back to the Table of contents
- if you have Voice ID
-
character.current_voice()
Get character current voice info.
- Auto (you must already connected with character)
await client.character.current_voice() - Manual
await client.character.current_voice("Character ID")
Param Require Type Description character_id trueStringTarget of Character ID. Back to the Table of contents
- Auto (you must already connected with character)
Group Chat Function List
-
group_chat.list()
Get all list available group chat in account.
await client.group_chat.list();Param Require Type Description none falsenullnone Back to the Table of contents
-
group_chat.connect()
Connecting to group chat by the
room_id, btw you can't connect the group chat before you create it.await client.group_chat.connect(room_id);Param Require Type Description room_id trueStringYour group chat id. Back to the Table of contents
-
group_chat.disconnect()
Disconnecting from group chat by the
room_id.await client.group_chat.disconnect(room_id);Param Require Type Description room_id trueStringYour group chat id. Back to the Table of contents
-
group_chat.create()
Create a custom room chat.
await client.group_chat.create(title_room, character_id);Param Require Type Description title_room trueStringYour custom title room name. character_id trueStringYour character id will be added to the group chat. Back to the Table of contents
-
group_chat.delete()
Delete group chat.
await client.group_chat.delete(room_id);Param Require Type Description room_id trueStringYour group chat id. Back to the Table of contents
-
group_chat.rename()
Rename group chat.
await client.group_chat.rename(new_name, room_id);Param Require Type Description new_name trueStringNew name for your group chat. room_id trueStringYour group chat id. Back to the Table of contents
-
group_chat.join_group_invite()
Joining group chat using invite code.
await client.group_chat.join_group_invite(invite_code);Param Require Type Description invite_code trueStringThe group chat miinvite code. Back to the Table of contents
-
group_chat.char_add()
Add a character with
character_idto the group chat.await client.group_chat.char_add(character_id);Param Require Type Description character_id trueStringCharacter id to be added to the group chat. Back to the Table of contents
-
group_chat.char_remove()
Remove a character with
character_idfrom the group chat.await client.group_chat.char_remove(character_id);Param Require Type Description character_id trueStringCharacter id to be removed from the group chat. Back to the Table of contents
-
group_chat.send_message()
Send message to character in group chat.
await client.group_chat.send_message(message, image_url);Param Require Type Description message trueStringMessage content. image_url falseStringThe image content that the character will see, must be a url and not a file type or a file with a type other than image. Back to the Table of contents
-
group_chat.generate_turn()
Generating message response character from group chat.
await client.group_chat.generate_turn();Param Require Type Description none falsenullGenerate message response Back to the Table of contents
-
group_chat.generate_turn_candidate()
Regenerate character message.
await client.group_chat.generate_turn_candidate(turn_id);Param Require Type Description turn_id trueStringturn_idormessage_idfrom the character.Back to the Table of contents
-
group_chat.reset_conversation()
Reset conversation in group chat.
await client.group_chat.reset_conversation();Param Require Type Description none falsenullReset conversation. Back to the Table of contents
-
group_chat.delete_message()
Delete character message.
await client.group_chat.delete_message(turn_id);Param Require Type Description turn_id trueStringturn_idormessage_idfrom the character.Back to the Table of contents
-
group_chat.edit_message()
Edit character message in group chat.
await client.group_chat.edit_message(candidate_id, turn_id, new_message);Param Require Type Description candidate_id trueStringturn_id trueStringturn_idormessage_idfrom the character.new_message trueStringNew character message Back to the Table of contents
-
group_chat.select_turn()
Select the turn of character chat by yourself.
await client.group_chat.select_turn(turn_id);Param Require Type Description turn_id trueStringturn_idormessage_idfrom the character.Back to the Table of contents
Chat Function List
-
chat.history_chat_turns()
Get a history chat from group or single chat.
await client.chat.history_chat_turns(chat_id);Param Require Type Description chat_id trueStringGroup chat or single chat ID. Back to the Table of contents
-
chat.conversation_info()
Get converastion information.
await client.chat.conversation_info(chat_id);Param Require Type Description chat_id trueStringGroup chat ID or single chat ID. Back to the Table of contents
-
chat.history_conversation_list()
Get list of your history conversation from character. This function is for Single character only.
- Auto (Already connected to the Single character chat)
await client.chat.history_conversation_list() - Manual
await client.chat.history_conversation_list("Character ID")
Param Require Type Description character_id falseStringTarget of Character ID. Back to the Table of contents
- Auto (Already connected to the Single character chat)
-
chat.set_conversation_chat()
Set conversation chat, and bring the history chat into current chat. This function is for Single character only.
await client.chat.set_conversation_chat(chat_id)Param Require Type Description chat_id trueStringsingle chat ID. Back to the Table of contents
-
chat.pin_message()
Pin message. This function is for Single character only.
- Auto (if your're already connected to the single character)
await client.chat.pin_message("Turn ID") - Manual
await client.chat.pin_message("Turn ID", true, "Chat ID")
Param Require Type Description turn_id trueStringTurn ID Message. pinned falseBooleanSet the message pinned or not. (set trueif you want to pin the message, setfalseif you want to unpin the message.)chat_id falseStringChat ID Message. (Set the Chat ID if you not connected to the Single character.) Back to the Table of contents
- Auto (if your're already connected to the single character)
-
chat.list_pinned_message()
Get list pinned message from chat. This function works only for single character chat.
await client.chat.list_pinned_message("Chat ID")Param Require Type Description chat_id trueStringChat ID Message. Back to the Table of contents
-
chat.archive_conversation()
Archive your conversation. This function works only for single character chat.
- If you want archive the conversation
await client.chat.archive_conversation("Chat ID", true) - If you want unarchive the conversation
await client.chat.archive_conversation("Chat ID", false)
Param Require Type Description chat_id trueStringChat ID message that you want to archive. set_archive falseBooleanSet Archive (to archive the Conversation, you can set it to true. If you want to unarchive the Converastion, you can set it tofalse.)Back to the Table of contents
- If you want archive the conversation
-
chat.duplicate_conversation()
Duplicate your conversation. This function works only for single character chat.
await client.chat.duplicate_conversation("Chat ID", "Turn ID")Param Require Type Description chat_id trueStringChat ID message that you want to duplicate. turn_id trueStringTurn ID message that you want to duplicate. Back to the Table of contents
-
chat.rename_conversation()
Rename your conversation title. This function works only for single character chat.
await client.chat.rename_conversation("Chat ID", "Custom Name")Param Require Type Description chat_id trueStringChat ID message that you want to rename. name trueStringName that you want to rename. Back to the Table of contents
Voice Function List
-
voice.user_created_list()
Get list of user created voice information.
- Get your own created voice list
await client.voice.user_list() - Get user created voice list
await client.voice.user_list("username")
Param Require Type Description username falseStringA username that wants you to check the created voice list. Back to the Table of contents
- Get your own created voice list
-
voice.info()
Get a voice information.
await client.voice.info("Voice ID")Param Require Type Description voice_id trueStringA Voice ID that wants you to check the voice information. Back to the Table of contents
-
voice.connect()
WARNING: This feature only supports Single character chat, not Group chat.
Connect to voice character chat, and this function works only for single character chat.
- Using Query
await client.voice.connect("Query", true) - Using Voice ID
await client.voice.connec("Voice ID")
Example to use
-
Without microphone
const Speaker = require("speaker"); // import Speaker from "speaker" const speaker = new Speaker({ channels: 1, // 1 channel bitDepth: 16, // 16-bit samples sampleRate: 48000 // 48,000 Hz sample rate }); await client.character.connect("Character ID"); let test = await client.voice.connect("Sonic The Hedgehog", true); console.log("Character voice ready!"); test.output.on("frameReceived", ev => { speaker.write(Buffer.from(ev.frame.data.buffer)); // PCM buffer write into speaker and you'll hear the sound. }); await client.character.generate_turn(); // Test is voice character is working or not. -
With microphone (Voice call)
const Speaker = require("speaker"); // import Speaker from "speaker" const { spawn } = require('child_process'); // import { spawn } from "child_process". //for microphone, I'll using sox. so Ineed child_process const speaker = new Speaker({ channels: 1, // 1 channel bitDepth: 16, // 16-bit samples sampleRate: 48000 // 48,000 Hz sample rate }); const recordMic = spawn('sox', [ '-q', '-t', 'waveaudio', '-d', // Input windows audio (add '-d' if you want set default) '-r', '48000', // Sample rate: 48 kHz '-e', 'signed-integer', // Encoding: signed PCM '-b', '16', // Bit depth: 16-bit '-c', '1', // Channel: 1 (mono) '-t', 'raw', // Output format: raw PCM '-' // stdout ]); let test = await client.voice.connect("Sonic The Hedgehog", true, true); console.log("Voice call ready!"); test.output.on("frameReceived", ev => { speaker.write(Buffer.from(ev.frame.data.buffer)); // PCM buffer write into speaker and you'll hear the sound. }); recordMic.stdout.on("data", data => { if (test.is_speech(data)) test.input_write(data); // Mic PCM Buffer output send it to Livekit server. });
Param Require Type Description voice_query_or_id trueStringTarget Voice query or Voice ID. using_voice_query falseBooleanUsing Voice Query (set it to true if voice_query_or_idusing Voice Query)using_mic falseBooleanUsing Microphone (You can talk to the Character using Microphone. Livekit needed.) mic_opt false{framerate: number, channel: number}Mic options. Default = {framerate: 48000, channel: 1}Back to the Table of contents
- Using Query
-
voice.disconnect()
WARNING: This feature only supports Single character chat, not Group chat.
Disconnect from voice character chat.
await client.voice.disconnect()Param Require Type Description none falsenullDisconnect from voice character chat. Back to the Table of contents
Issues
Feel free to open the issue, I hope this documentation can help you maximally and make it easier for you to use this package.
Thanks to ZTRdiamond for helping me making a documentation.