Giter Club home page Giter Club logo

node_characterai's Introduction

Character AI Unofficial Node API

Node.js client for the unofficial Character AI API, an awesome website which brings characters to life with AI!

Intro

This repository is inspired by RichardDorian's unofficial node API. Though, I found it hard to use and it was not really stable and archived. So I remade it in javascript.

This project is not affiliated with Character AI in any way! It is a community project. The purpose of this project is to bring and build projects powered by Character AI.

If you like this project, please check their website.

Features

  • ๐Ÿ‘ Fully written in Javascript and CommonJS (for max compatibility and ease of use)
  • โŒš Asynchronous requests
  • ๐Ÿ—ฃ๏ธ Use conversations or use the API to fetch information
  • ๐Ÿงธ Easy to use
  • ๐Ÿ” Active development
  • ๐Ÿ‘ค Guest & token login support

Installation

npm install node_characterai

Usage

Basic guest authentication and message:

const CharacterAI = require("node_characterai");
const characterAI = new CharacterAI();

(async () => {
  // Authenticating as a guest (use `.authenticateWithToken()` to use an account)
  await characterAI.authenticateAsGuest();

  // Place your character's id here
  const characterId = "8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw";

  // Create a chat object to interact with the conversation
  const chat = await characterAI.createOrContinueChat(characterId);

  // Send a message
  const response = await chat.sendAndAwaitResponse("Hello discord mod!", true);

  console.log(response);
  // Use `response.text` to use it as a string
})();

Using an Access Token

Some parts of the API (like managing a conversation) require you to be logged in using a sessionToken.

To get it, you can open your browser, go to the Character.AI website in localStorage.

Important

If you are using old versions of the package and are getting a Authentication token is invalid, you now again need a sessionToken to authenticate (as of update 1.2.5 and higher). See below.

If you are using something that is using the package and has not updated to the latest version in a while, make sure to update the package by doing npm update node_characterai or manually copying the files or open a respective issue to their package (if they have one).


โš ๏ธ WARNING: DO NOT share your session token to anyone you do not trust or if you do not know what you're doing.

Anyone with your session token could have access to your account without your consent. Do this at your own risk.


On PC:

  1. Open the Character.AI website in your browser (https://beta.character.ai)
  2. Open the developer tools (F12, Ctrl+Shift+I, or Cmd+J)
  3. Go to the Application tab
  4. Go to the Storage section and click on Local Storage
  5. Look for the char_token key
  6. Open the object, right click on value and copy your session token.

Session_Token

On Mobile:

  1. Open the Character.AI website in your browser on the OLD interface (https://old.character.ai/)
  2. Open the URL bar, write javascript: (case sensitive) and paste the following:
(function(){let e=window.localStorage["char_token"];if(!e){alert("You need to log in first!");return;}let t=JSON.parse(e).value;document.documentElement.innerHTML=`<div><i><p>provided by node_characterai - <a href="https://github.com/realcoloride/node_characterai?tab=readme-ov-file#using-an-access-token">click here for more information</a></p></i><p>Here is your session token:</p><input value="${t}" readonly><p><strong>Do not share this with anyone unless you know what you are doing! This is your personal session token. If stolen or requested by someone you don't trust, they could access your account without your consent; if so, please close the page immediately.</strong></p><button id="copy" onclick="navigator.clipboard.writeText('${t}'); alert('Copied to clipboard!')">Copy session token to clipboard</button><button onclick="window.location.reload();">Refresh the page</button></div>`;localStorageKey=null;storageInformation=null;t=null;})();
  1. The following page should appear: Access_Token_Mobile

  2. Click the respective buttons to copy your access token or id token to your clipboard.


When using the package, you can:

  • Login as guest using authenticateAsGuest() - for mass usage or testing purposes
  • Login with your account or a token using authenticateWithToken() - for full features and unlimited messaging

Finding your character's ID

You can find your character ID in the URL of a Character's chat page.

For example, if you go to the chat page of the character Discord Moderator you will see the URL https://beta.character.ai/chat?char=8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw.

The last part of the URL is the character ID: Character_ID

Image Interactions

WARNING: This part is currently experimental, if you encounter any problem, open an Issue.

๐Ÿ–ผ๏ธ Character AI has the ability to generate and interpret images in a conversation. Some characters base this concept into special characters, or maybe use it for recognizing images, or to interact with a character and give it more details on something: the possibilities are endless.

๐Ÿ’ Most of the Character AI image features can be used like so:

// Most of these functions will return you an URL to the image
await chat.generateImage("dolphins swimming in green water");
await chat.uploadImage("https://www.example.com/image.jpg");
await chat.uploadImage("./photos/image.jpg");

// Other supported types are Buffers, Readable Streams, File Paths, and URLs
await chat.uploadImage(imageBuffer);

// Including the image relative path is necessary to upload an image
await chat.sendAndAwaitResponse({
  text: "What is in this image?",
  image_rel_path: "https://www.example.com/coffee.jpg",
  image_description: "This is coffee.",
  image_description_type: "HUMAN" // Set this if you are manually saying what the AI is looking at
}, true);

Props to @creepycats for implementing most of this stuff out

Troubleshooting

Problem Answer
โŒ Token was invalid Make sure your token is actually valid and you copied your entire token (its pretty long) or, you have not updated the package.
โš ๏ธ The specified Chromium path for puppeteer could not be located On most systems, puppeteer will automatically locate Chromium. But on certain distributions, the path has to be specified manually. This warning occurs if node_characterai could not locate Chromium on linux (/usr/bin/chromium-browser), and will error if puppeteer cannot locate it automatically. See this for a fix.
๐Ÿ˜ฎ Why are chromium processes opening? This is because as of currently, the simple fetching is broken and I use puppeteer (a chromium browser control library) to go around cloudflare's restrictions.
๐Ÿ‘ฅ authenticateAsGuest() doesn't work See issue #14.
๐Ÿฆ’ Hit the max amount of messages? Sadly, guest accounts only have a limited amount of messages before they get limited and forced to login. See below for more info ๐Ÿ‘‡
๐Ÿช How to use an account to mass use the library? You can use conversations, a feature introduced in 1.0.0, to assign to users and channels. To reproduce a conversation, use OOC (out of character) to make the AI think you're with multiple people. See an example here: chrome_RDbmXXtFNlchrome_BgF8crPvqC (Disclaimer: on some characters, their personality will make them ignore any OOC request).
๐Ÿƒ How do I avoid concurrency and crashes when using more than one request at a time? Check the solution found by @SeoulSKY here using async-mutex.
๐Ÿ“ฃ Is this official? No, this project is made by a fan of the website and is unofficial. To support the developers, please check out their website.
๐Ÿ˜ฒ Did something awesome with node_characterai? Please let me know!
โœ‰๏ธ Want to contact me? See my profile
โ˜• Want to support me? You can send me a coffee on ko.fi: https://ko-fi.com/coloride. Many thanks!
๐Ÿ’ก Have an idea? Open an issue in the Issues tab
โž• Other issue? Open an issue in the Issues tab

In-depth troubleshooting

๐Ÿคš Before you scroll, please know that:

  • In the Client class, you can access the Requester class and define puppeteer or other variables related to how CharacterAI will work using characterAI.requester.(property). Also, anything here is subject to change, so make sure to update the package frequently.

๐Ÿ’ณ About CharacterAI+

"I am a member of cai+, how do I use it?"

Change the property .usePlus from the requester and if needed, change .forceWaitingRoom.

For example:

// Default is `false`
characterAI.requester.usePlus = true;

๐Ÿงญ About Puppeteer

Around a few months ago, the package only required the node-fetch module to run. The package was made using simple API requests.

However, over time, Cloudflare started fighting against scraping and bots, which also made it almost impossible for anyone to use this package.

This is where in versions 1.1 and higher, puppeteer is used (which uses a chromium browser) to make requests with the API.

โš™๏ธ How to change Puppeteer settings

๐Ÿ‘‰ IMPORTANT: do the changes before you initialize your client!

In the CharacterAI class, you can access the requester and define the .puppeteerPath variable or other arguments, and the properties include (and are subject to change in future versions):

// Chromium executable path (in some linux distributions, /usr/bin/chromium-browser)
puppeteerPath;
// Default arguments for when the browser launches
puppeteerLaunchArgs;
// Boolean representing the default timeout (default is 30000ms)
puppeteerNoDefaultTimeout;
// Number representing the default protocol timeout
puppeteerProtocolTimeout;
Specifying Chromium's path

๐Ÿง For linux users, if your puppeteer doesn't automatically detect the path to Chromium, you will need to specify it manually.

To do this, you just need to set puppeteerPath to your Chromium path:

characterAI.puppeteerPath = "/path/to/chromium-browser";

On Linux, you can use the which command to find where Chromium is installed:

$ which chromium-browser # or whatever command you use to launch chrome

๐Ÿ’ก I recommend that you frequently update this package for bug fixes and new additions.

Disclaimer

โค๏ธ This project is updated frequently, always check for the latest version for new features or bug fixes.

๐Ÿš€ If you have an issue or idea, let me know in the Issues section.

๐Ÿ“œ If you use this API, you also bound to the terms of usage of their website.

(real)coloride - 2023-2024, Licensed MIT.

node_characterai's People

Contributors

creepycats avatar onnowhere avatar parking-master avatar realcoloride avatar rense0 avatar reymaicer avatar sivertheisholt avatar then77 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node_characterai's Issues

Hanging on characterAI.authenticateAsGuest

When I try calling await characterAI.authenticateAsGuest it hangs sometimes. Is this due to the cloudflare protection on the website? When I add logs inbetween that await call it doesn't get past that line.

I get the console logs
[node_characterai] Puppeteer - This is an experimental feature. Please report any issues on github.
[node_characterai] Puppeteer - Done with setup
but nothing afterwards.

[News] Massive update incoming, your code may break!

Hello!
I have worked on a new update today that brings tons of changes to the API wrapper!

Many classes were added.
Thanks to all the people who gave some tips and feedback.

Major changes:

Classes Added:

Reply

Returned by chat.sendAndAwaitResponse()
Contains the information of a reply.

To manage or interact with the message, use the await reply.getMessage() function.
When printed using console.log, it will return the text property (for testing purposes), this is an experimental feature, but will be disabled by feedback if needed.

โš ๏ธ So make sure that you use reply.text in your code!
This will allow you to interact and get more information about a reply.

If you dont use singleReply, you will get an array of Reply (replies).

Message

Primary message class that allows you to interact with the message and get proper information about it.

Notable methods:
message.delete(deletePreviousToo = false) - Reference to issue #6, allows you to delete the message sent, and delete the previous one (can be the AI message that preceeds yours)
message.getPreviousMessage() - Gets you the message that preceeds this one, returns null if it doesn't exist.

OutgoingMessage

Class message to send a message with more information than a text message.
Used in chat.sendAndAwaitResponse(options, singleReply)
๐Ÿ‘Œ You will still be able to use text instead of this class.

MessageHistory

Class that contains an array of messages when fetched with chat.fetchHistory().
Contains also extra details, but use .messages to access those messages.

Changes to the Chat class

deleteMessagesBulk(amount = 50) - #6 Deletes messages in mass by amount
deleteMessage(messageId) - #6 Deletes a message by its id
getMessageById - Gets a message (class) by its id to interact with

TL:DR - Added support for message deletion, conversation management, more parameters for messages, checks...
This update may break some stuff of code out there, so please check!

This update will be pushed soon, I am just making extra tests.

403 on createOrContinueChat

Ever since last night the API has stopped working, speficially on createOrContinueChat where you get TypeError: Cannot read properties of undefined (reading 'characterId') on the returned chat.
I checked the request that is made and turns out it's getting a 403 error, indicating that it's probably not authenticated properly.

I think C.AI has pushed an update that caused it to break.

Often crashes while using as a Discord bot...

I tried making a Discord Bot using this package and I have discovered that it often crashes and I can't find a reason why. Can't navigate to the chat.js file.

The error is the the following-

node:events:491
      throw er; // Unhandled 'error' event

TypeError: Cannot read properties of undefined (reading 'length')
    at Chat.sendAndAwaitResponse (D:\node_modules\node_characterai\chat.js:71:41) 
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Client.<anonymous> (D:\index.js:39:26)
Emitted 'error' event on Client instance at:
    at emitUnhandledRejectionOrErr (node:events:394:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:84:21)

Node.js v18.14.0

My code is the following-

const { Client, GatewayIntentBits} = require('discord.js');
let client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
		GatewayIntentBits.MessageContent,
        GatewayIntentBits.GuildMembers,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.GuildVoiceStates,
        GatewayIntentBits.GuildEmojisAndStickers,
        GatewayIntentBits.GuildIntegrations,
        GatewayIntentBits.GuildInvites,
        GatewayIntentBits.GuildMessageReactions,
        GatewayIntentBits.GuildMessageTyping,
        GatewayIntentBits.GuildWebhooks,
    ],
    disableMentions: 'everyone',
});

client.on('ready', () => {
    console.log(`Logged in as ${client.user.tag}!`);
  });

const CharacterAI = require('node_characterai');
const characterAI = new CharacterAI();

(async() => {
    await characterAI.authenticateAsGuest();

    const characterId = "CHARACTERID"

    const chat = await characterAI.createOrContinueChat(characterId);

    client.on('messageCreate', async message => {
        if (message.author.bot || !message.content) return;
        message.channel.sendTyping();

        const prompt = message.content
      
        const response = await chat.sendAndAwaitResponse(prompt, true);
        message.channel.send(response.text);
      });

})();

client.login('TOKEN');

I hope for a solution :) . And thanks for making this package.

Expiration Dates

Hey ! Do you happen to know if there's something that could be done to automatically create a token instead of recreating one at expiration dates ?

Puppeteer headless Deprecation error

``[node_characterai] Puppeteer - This is an experimental feature. Please report any issues on github.
๏ฟฝ[1m๏ฟฝ[43m๏ฟฝ[30m
Puppeteer old Headless deprecation warning:๏ฟฝ[0m๏ฟฝ[33m
In the near feature headless: true will default to the new Headless mode
for Chrome instead of the old Headless implementation. For more
information, please see https://developer.chrome.com/articles/new-headless/.
Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.๏ฟฝ[0m

c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ProductLauncher.js:289
throw new Error(Could not find Chromium (rev. ${this.puppeteer.browserRevision}). This can occur if either\n +
^

Error: Could not find Chromium (rev. 1108766). This can occur if either

  1. you did not perform an installation before running the script (e.g. npm install) or
  2. your cache path is incorrectly configured (which is: C:\Users\lolt0.cache\puppeteer).
    For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.
    at ChromeLauncher.resolveExecutablePath (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ProductLauncher.js:289:27)
    at ChromeLauncher.executablePath (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ChromeLauncher.js:182:25)
    at ChromeLauncher.computeLaunchArguments (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ChromeLauncher.js:99:37)
    at ChromeLauncher.launch (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ProductLauncher.js:83:39)
    at ChromeLauncher.launch (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\ChromeLauncher.js:53:22)
    at PuppeteerNode.launch (c:\Users\lolt0\node_modules\puppeteer\node_modules\puppeteer-core\lib\cjs\puppeteer\node\PuppeteerNode.js:150:105)
    at PuppeteerExtra.launch (c:\Users\lolt0\node_modules\puppeteer-extra\dist\index.cjs.js:128:41)
    at async Requester.initialize (c:\Users\lolt0\node_modules\node_characterai\requester.js:25:25)
    at async Client.authenticateAsGuest (c:\Users\lolt0\node_modules\node_characterai\client.js:197:9)``

Failed to fetch a lazy token

When you try to login with a guest (or even with a real token) the API returns an error, which makes it impossible to use the chats, I don't know why exactly but I've been testing it for several days in different environments and it always gives me the same error, while before it did work normally.

Testing code:

const CharacterAI = require('node_characterai');
const characterAI = new CharacterAI();
 
(async() => {
    await characterAI.authenticateAsGuest();
 
    const characterId = "8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw" // Discord moderator
 
    const chat = await characterAI.createOrContinueChat(characterId);
    const response = await chat.sendAndAwaitResponse('Hello discord mod!', true)
 
    console.log(response);
})();

Error:

imagen

Necessity fetching of all chunks from /streaming endpoint

I found an issue related to audio content on my personal project. So I think you may need to be aware of this.

Upon POSTing to the /streaming endpoint, the API will provide several JSON data chunks in response. It is essential to obtain the previous data chunks along with the latest ones. In cases where a user has enabled their character voice options, the API will deliver character audio data in raw format by chunk. As a result, failing to retrieve earlier portions of the audio would lead to the loss of critical audio content. (The final chunk of JSON data only includes a partial portion of the audio.)

Does this in any way violate Character.ai ToS?

I wish to use this package for a public discord bot project, so i would really like to know if using this package is permitted since i wish to keep the bot project legally safe in the long run.

Cannot find module โ€œfs/promisesโ€

I am new to this package. Everytime I run the program it fails with this message.

I have installed โ€œfsโ€ and imported, but it is still throwing this error.

pi@raspberrypi:~ $ node ai1.js

Error: Cannot find module 'fs/promises'
Require stack:
- /home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserFetcher.js
- /home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/node.js
- /home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/puppeteer-core.js
- /home/pi/node_modules/puppeteer/lib/cjs/puppeteer/puppeteer.js
- /home/pi/ai1.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
    at Function.Module._load (internal/modules/cjs/loader.js:667:27)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserFetcher.js:36:20)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserFetcher.js',
    '/home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/node.js',
    '/home/pi/node_modules/puppeteer-core/lib/cjs/puppeteer/puppeteer-core.js',
    '/home/pi/node_modules/puppeteer/lib/cjs/puppeteer/puppeteer.js',
    '/home/pi/ai1.js'
  ]
}

This is the only file I am using:

ai1.js
const CharacterAI = require('node_characterai');
const characterAI = new CharacterAI();
const puppeteer = require("puppeteer");

(async() => {
    await characterAI.authenticateWithToken("xxx");

    const characterId = "xxx" // Discord moderator

    const chat = await characterAI.createOrContinueChat(characterId);
    const response = await chat.sendAndAwaitResponse('Hello discord mod!', true)

    console.log(response);
    // use response.text to use it in a string.
})();

Error: Failed to fetch a lazy token - blocked by Cloudflare?

When I was running the example code, it raised following exception:

Error: Failed to fetch a lazy token
      at Client.authenticateAsGuest (/home/lss233/project/node_modules/node_characterai/client.js:207:22)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at <anonymous> (/home/lss233/project/plugins/character-ai/src/index.ts:35:7)

I tired to print out the request, It shows follwing:

  [Symbol(Response internals)]: {
    type: 'default',
    url: 'https://beta.character.ai/chat/auth/lazy/',
    status: 403,
    statusText: 'Forbidden',
    headers: {
      'cache-control': 'private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
      'cf-ray': '795d56563f192ae9-LAX',
      connection: 'close',
      'content-encoding': 'gzip',
      'content-type': 'text/html; charset=UTF-8',
      date: 'Tue, 07 Feb 2023 16:00:13 GMT',
      expires: 'Thu, 01 Jan 1970 00:00:01 GMT',
      'referrer-policy': 'same-origin',
      server: 'cloudflare',
      'server-timing': 'cf-q-config;dur=6.9999996412662e-06',
      'set-cookie': '__cf_bm=fGFX6BoxOEm01ZuoCPM9886gf89xMl7oKfPfezzJig7Wo-1675785613-0-AS5g4Pb+ReO3jBcKFPLGLsbM3cFUPyzDJZg5FvHd70IARJJ7lPfUpUxWLtsJDJL7vesH5zQF78SzahQvqcSrk=; path=/; expires=Tue, 07-Feb-23 16:30:13 GMT; domain=.character.ai; HttpOnly; Secure; SameSite=None',
      'transfer-encoding': 'chunked',
      vary: 'Accept-Encoding',
      'x-frame-options': 'SAMEORIGIN'
    },
    counter: 0,
    highWaterMark: 16384
  }
}

It seems that they have Cloudflare AntiBot enabled.

Chat.deleteMessage() doesn't seem to work

I tried deleting a message with const response = await chat.sendAndAwaitResponse(message, true); ... await chat.deleteMessage(response.lastUserMessageId.toString());

Received no error, but the message was not deleted on the site.

How to interact with html?

Thank you very much for your project, which made me come into contact with nodejs.

The code works fine, but I don't quite understand how to allow users to have a conversation on my webpage.

webserver.js
const http = require('http');
const fs = require('fs');
const express = require('express');
const path = require('path');

const app = express();


app.use(express.static(path.join(__dirname, 'page')));


app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'page', 'main.html'));
});


const server = http.createServer(app);

server.listen(3000, 'localhost', () => {
  console.log('server in 3000 port');
});

And another problem that i don't really know what happened.

test.js
const CharacterAI = require('node_characterai');
const readline = require('readline');

const characterAI = new CharacterAI();

(async () => {
  await characterAI.authenticateAsGuest();

  const characterId = "8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw"; // Discord moderator

  const chat = await characterAI.createOrContinueChat(characterId);

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  rl.setPrompt('You: ');
  rl.prompt();

  rl.on('line', async (input) => {
    const response = await chat.sendAndAwaitResponse(input.trim(), true);
    console.log('Bot:', response.text);

    rl.prompt();
  });

  rl.on('close', () => {
    console.log('Chat ended.');
  });
})();

then appear

C:\Users\USER\Downloads\node_characterai-main\node_modules\node_characterai\chat.js:71
            for (let i = 0; i < replies.length; i++) {
                                        ^

TypeError: Cannot read properties of undefined (reading 'length')
    at Chat.sendAndAwaitResponse (C:\Users\USER\Downloads\node_characterai-main\node_modules\node_characterai\chat.js:71:41)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Interface.<anonymous> (C:\Users\USER\Downloads\node_characterai-main\test.js:22:22)

[Feature suggestion] Memory wipe

just a suggestion that can be very helpful. If the user uses non guest authorization
Have a function that wipes all the conversation and creates a new conversation with no memory of the previous one

There is such option in character AI website "Save and Start New Chat"
image

chat is undefined

It's as straightforward as the title says.
Here's the code I used to test:

const CharacterAI = require('node_characterai');
const characterAI = new CharacterAI();
(async () => {
                    await characterAI.authenticateAsGuest();
                    const chat = await characterAI.createOrContinueChat("qvYZ0WMhydAFcefkmZDknc_7u4gKx6V0iBgP-aBmC6w");
})()

The issue persists no matter what CharacterID I use.

authenticateWithToken blocked?

I have this code

async function main() {
    /// character.ai 
    await characterAI.authenticateWithToken("[token from local storage]");
    const characterId = "g60H0IyiUL2l4IvjRzDb7P5PyzY-H1auahH_kyfnWCk" 
    const chat = await characterAI.createOrContinueChat(characterId);
}

And it causes

Unhandled error occured but ignored. SyntaxError: Unexpected token < in JSON at position 0
    at JSON.parse (<anonymous>)
    at parseJSONFromBytes (node:internal/deps/undici/undici:6498:19)
    at successSteps (node:internal/deps/undici/undici:6472:27)
    at node:internal/deps/undici/undici:1145:60
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

I have also checked that it seems like Cloudflare is blocking the request, looks like this is gonna be hard.

Need explanation please

Hello Im new :D

So, the code should I copy it and paste it on python 3.10 and then

const CharacterAI = require('node_characterai');
const characterAI = new CharacterAI();

(async() => {
await characterAI.authenticateAsGuest();

const characterId = "8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw" // Discord moderator

const chat = await characterAI.createOrContinueChat(characterId);
const response = await chat.sendAndAwaitResponse('Hello discord mod!', true)

console.log(response);
// use response.text to use it in a string.

})();

where does the token go
Where should I put my character ID

Discussion

This is not an issue, I just didn't find anywhere else to contact you.

This is sick! Finally someone who made a stable thing out of my idea. Where can I contact you (Discord maybe)? I wanna talk about a few things including the internals of this wrapper.

How to receive data as a stream?

Hello. This project helps me a lot. However there is still a problem for me. When I call sendAndAwaitResponse. It seems that I have to wait until all the reply text generated. Is there any way to read the data little by little instead of reading all the response data?

invalid token error

i used authenticateWithToken and my token but it kept error
here is the error

SyntaxError: Invalid or unexpected token
โ†[90m    at internalCompileFunction (node:internal/vm:73:18)โ†[39m
โ†[90m    at wrapSafe (node:internal/modules/cjs/loader:1195:20)โ†[39m
โ†[90m    at Module._compile (node:internal/modules/cjs/loader:1239:27)โ†[39m
โ†[90m    at Module._extensions..js (node:internal/modules/cjs/loader:1329:10)โ†[39m
โ†[90m    at Module.load (node:internal/modules/cjs/loader:1133:32)โ†[39m
โ†[90m    at Module._load (node:internal/modules/cjs/loader:972:12)โ†[39m
โ†[90m    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)โ†[39m
โ†[90m    at node:internal/main/run_main_module:23:47โ†[39m 

here is my code

const Discord = require('discord.js');
const CharacterAI = require('node_characterai');

const client = new Discord.Client({
    intents: [Discord.GatewayIntentBits.GuildPresences, Discord.GatewayIntentBits.MessageContent, Discord.GatewayIntentBits.GuildMembers]
  });
const characterAI = new CharacterAI();

client.once('ready', async () => {
    console.log(`Logged in as ${client.user.tag}!`);
    
    try {
      await characterAI.authenticateWithToken(eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkVqYmxXUlVCWERJX0dDOTJCa2N1YyJ9.eyJpc3MiOiJodHRwczovL2NoYXJhY3Rlci1haS51cy5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMTYxOTg1OTU4MTI4NTc3NjAzNjgiLCJhdWQiOlsiaHR0cHM6Ly9hdXRoMC5jaGFyYWN0ZXIuYWkvIiwiaHR0cHM1Ly9jaGFyYWN0ZXItYWkudXMuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTY3OTEzNDYzNywiZXhwIjoxNjgxNzl7NjM3LCJhenAiOiJkeUQzZ0UyODFNcWdJU0c3RnVJWFloTDJXRWtucVp6diIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwifQ.oxq6E7ZjVBzRJL2tDOsLHauK2_MbsAFlCpSHiCkA0w_kmOqkTBF3ZutV0c7hE_WdVqQvaleR8-gT1RG2JlK2A_-61m9ZYuP0UNsWCGYOM5hO5pbDsALjccmB2Kw5ilnbv8ldEq3M3arlIyix-5GlHCZqJzK8_scfCNiXB79L7sKr-t8hahoolf4ta5bKsbtgHdVRu_0Ze-LIrRGB_TyoEzJthG34AbxmJ4Rifq1uQzkLS6B4Ts_F-Z_pag0J9SIPwe6uK5f1M7Sysfbla8D3WESKR9oKhDoYUO6YW20Thb2q8jazBPpXz964ySHxHGPGyPlZrhpI4HV3HYL3m39aYw);
      console.log('Node_CharacterAI authenticated with token successfully.');
    } catch (err) {
      console.error('Failed to authenticate with Node_CharacterAI token:', err);
      return;
    }
  
    const characterId = 'CzRyT0HsNgDipM-eqM2IwrTe76C3brMu1Qutx2-f-UY';
  
    try {
      const chat = await characterAI.createOrContinueChat(CzRyT0HsNgDipM-eqM2IwrTe76C3brMu1Qutx2-f-UY);
      const response = await chat.sendAndAwaitResponse('Hello discord mod!', true);
      console.log('Node_CharacterAI response:', response.text);
    } catch (err) {
      console.error('Failed to get Node_CharacterAI response:', err);
    }
  });
  
(async () => {
  await client.login('discord_token');
})();

i have changed the characterai token when posted but it should look like that
currently using node ver 19.8
i just learned to code so please explain easily understandable if you can

Demo on how to use it

Can anyone please help me use node_characterai. I'm quite new to development.

I've cloned the repo, installed the dependencies & got the access token & characterID. But not able to figure out how to run this on my machine.

Reply.getMessage() isn't working

Chat.getMessageById() seems to be causing the issue here. The message id is not string but rather BigNumber, and Chat.getMessageById() only accepts string.

Its load?

I got this response in the console but not with the response text

Screenshot_20230507-110033

fetch is not defined

I tried installing node-fetch manually but it didn't fix it.

client.js:193
const request = await fetch('https://beta.character.ai/chat/auth/lazy/', {
                ^
ReferenceError: fetch is not defined

Make the code work on replit

As I read the description, I found out that it opens a chrome window when running. Is there any way to make the code work on replit?

error no reply

message.js:107
const replyOptions = options.replies[0];
                                    ^
TypeError: Cannot read properties of undefined (reading '0')

Sometimes the reply gets deleted by c.ai if it is nsfw.

Include message deletion

There is a problem with the Character AI website and its bots because after chatting for a while, they start responding with the same messages over and over again. According to users, a solution is to delete the messages in the conversation from where it started repeating. Would it be possible to add this function to the package? Maybe delete the history or something

image

Thank you for reading!

response?

I am trying to return the response from the ai to use in my python environment, however no matter what I try it only returns this:
image
I can see the ai responding in the java terminal and in the website though. here are my codes:
image
image

Tokens don't work

I've tried using the authenticateAsGuest() method, which gives me Error: Failed to fetch a lazy token.
authenticateWithToken() throws an Error: Token is invalid.

I copied the access_token without the access_token:, and I tried it twice to make sure I hadn't copied the wrong line or hadn't copied the entire token as it is very long.

Console doesn't seem to give any more specific information. Using Node v19.7.0 on macOS 12.6.3.

.getMessageById always returns null

I have a code that gets a message by its id

image
But it always returns null, no matter which id I try.

If anything, there is no error in the id. Character ai gives me the same id:

image_2023-06-06_21-28-23

I tried to print out the ids it receives:

image

I'm new to node, but I think the whole reason is BigNumber. Or maybe I don't understand something.

1.1+ - Roadmap (bug fixes and more)

[Roadmap] Sum up of update goals: (from issue #14, merged here)

  • Switch to big int and convert to bigger ints (Added Parser class for this dedicated use) #14
  • Update some stuff in README.md
  • Fix some function arguments that required strings instead of ints #14
  • Fix node issues in #15
  • Fix fetch not defined issue (if possible)
  • Fix custom.util operations not working for some people #17
  • Fix net::ERR_ABORTED at https://beta.character.ai/chat/streaming/ error when parsing with puppeteer (priority)
  • Add new user agents to go around the new limitations in #16
  • Fix cloudflare limiting guest authentification in #13
  • Update package.json
  • Add ascending/descending mode to deleting in bulk (from up/down)
  • Added delete messages in array function [ids]
  • Converted message ids to strings instead of integers for big integers conversion in both classes and in functions
  • Make errors throw when an error occurs (message could not be sent for a reason such as nsfw, guest message limit)

This will be updated overtime.

Adding image support

Some of the characters generate images alongside text, thought it might be a good idea to include the image as well in the response.

Example character: https://beta.character.ai/chat?char=bQBlcCVVjfTAzv8OWK30dw7Tj-TNtKC_Rh0Z46Dx6fY

Small change can be added to include this in message.js for the Reply class by reading replyOptions.image_rel_path. Side note, I have noticed that the link itself doesn't generate an image immediately upon the url being returned in the response (gives a 404 if too soon), but usually needs a moment of wait before it's ready.

Also, may take a bit more work but these image path may be of interest for uploading images to be referenced in the chat as well:

  • beta.character.ai/chat/upload-image/
    • Request: image: (binary)
    • Response: {status: "...", value: "..."}
  • beta.character.ai/chat/generate-image/
    • Request: {image_prompt_text: "..."}
    • Response: {image_rel_path: "..."}

Message request also seems to have these fields now relating to images:

  • image_description: ""
  • image_description_type: "AUTO_IMAGE_CAPTIONING" (example)
  • image_origin_type: "UPLOADED" (example)
  • image_rel_path: "..."
  • REMOVED image_prompt_text

Help

I use this code for discord bot, and I run it on local successfully, but I try to run it on replit and my Vps there is an error like this, is there a solution?

[node_characterai] Puppeteer - This is an experimental feature. Please report any issues on github.

  Puppeteer old Headless deprecation warning:
    In the near feature `headless: true` will default to the new Headless mode
    for Chrome instead of the old Headless implementation. For more
    information, please see https://developer.chrome.com/articles/new-headless/.
    Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
    If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.

/home/runner/ru-chan/node_modules/puppeteer/node_modules/@puppeteer/browsers/lib/cjs/launch.js:259
                reject(new Error([
                       ^

Error: Failed to launch the browser process!
/home/runner/.cache/puppeteer/chrome/linux-113.0.5672.63/chrome-linux64/chrome: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory


TROUBLESHOOTING: https://pptr.dev/troubleshooting

    at Interface.onClose (/home/runner/ru-chan/node_modules/puppeteer/node_modules/@puppeteer/browsers/lib/cjs/launch.js:259:24)
    at Interface.emit (node:events:525:35)
    at Interface.emit (node:domain:489:12)
    at Interface.close (node:internal/readline/interface:536:10)
    at Socket.onend (node:internal/readline/interface:262:10)
    at Socket.emit (node:events:525:35)
    at Socket.emit (node:domain:489:12)
    at endReadableNT (node:internal/streams/readable:1359:12)

not working

So I just tried copying the example snippet in the README and running that, but it logs two messages and then stops, and doesn't print the response
image

Clear Chat Features

Delete Chat/Clear Chat Features on Character.AI would be good, Character AI's Characters sometimes being random if we don't clear the History Chat. Add an Option to Partially Clear Chat or Full Chat Deletion. Thanks

.createOrContinueChat hangs

requester.js:146[node_characterai] Puppeteer - ProtocolError: Page.navigate timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed.
Uncaught TypeError: Cannot read properties of undefined (reading 'status')

I'm authenticating with an ai+ token and it can authenticate the token, this is the code I'm trying to run:

const currentChat = new Promise(async (res, err) => {
    await character.authenticateWithToken(global.config.charAiToken);
    let chat = await character.createOrContinueChat("8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw")
    res (chat)
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.