Getting Started
@skyware/bot makes it easy to build bots for Bluesky. This guide will walk you getting set up and making your first post.
Setting up
You’ll need an existing Bluesky account for the bot to log in to.
Once you’ve created an account and noted the credentials, you should store them in a .env file in the root of your project. You can use the dotenv package to load these credentials into your project.
BSKY_USERNAME=user.bsky.social
BSKY_PASSWORD=your-password
Logging in
To log in,
import { class BotA bot that can interact with a Bluesky PDS.Bot } from "@skyware/bot";
const const bot: Botbot = new new Bot({ service, langs, emitEvents, emitChatEvents, rateLimitOptions, cacheOptions, eventEmitterOptions, chatEmitterOptions, }?: BotOptions): BotCreate a new bot.Bot();
await const bot: Botbot.Bot.login({ identifier, password }: BotLoginOptions): Promise<AtpSessionData>Log in with an identifier and password.login({
BotLoginOptions.identifier: stringThe bot account's email, handle, or DID.identifier: var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvThe process.env property returns an object containing the user environment.
See `environ(7)`.
An example of this object looks like:
{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}
It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:
$ node -e 'process.env.foo = "bar"' && echo $foo
While the following will:
import { env } from 'process';
env.foo = 'bar';
console.log(env.foo);
Assigning a property on process.env will implicitly convert the value
to a string. **This behavior is deprecated.** Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.
import { env } from 'process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'
Use delete to delete a property from process.env.
import { env } from 'process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined
On Windows operating systems, environment variables are case-insensitive.
import { env } from 'process';
env.TEST = 1;
console.log(env.test);
// => 1
Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread’s process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons.env.stringBSKY_USERNAME,
BotLoginOptions.password: stringThe bot account's password.password: var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvThe process.env property returns an object containing the user environment.
See `environ(7)`.
An example of this object looks like:
{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}
It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:
$ node -e 'process.env.foo = "bar"' && echo $foo
While the following will:
import { env } from 'process';
env.foo = 'bar';
console.log(env.foo);
Assigning a property on process.env will implicitly convert the value
to a string. **This behavior is deprecated.** Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.
import { env } from 'process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'
Use delete to delete a property from process.env.
import { env } from 'process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined
On Windows operating systems, environment variables are case-insensitive.
import { env } from 'process';
env.TEST = 1;
console.log(env.test);
// => 1
Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread’s process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons.env.stringBSKY_PASSWORD,
});
When calling new Bot(), you may choose to pass an optional BotOptions object to configure the bot. This object can contain the following properties:
service: The PDS to log into. Defaults tohttps://bsky.social.langs: An array of two-letter language codes signifying the languages the bot will post in. Clients may use this information to show users posts in languages they understand, and to offer the option to translate a post. Defaults to["en"].emitEvents: Whether the bot should emit events. You’ll learn more about this in Listening to events. Defaults totrue.emitChatEvents: Whether the bot should emit chat events. More on this in Chatting with Users. Defaults tofalse.- and various other configuration options — refer to the BotOptions documentation for the full list.
Posting
Making a post is just as simple.
const const post: PostReferencepost = await const bot: Botbot.Bot.post(payload: PostPayload, options?: BotPostOptions): Promise<PostReference>Create a post.post({
PostPayload.text: string | RichtextBuilderThe post text. Can be a string or a RichText instance containing facets.text: "hello, sky!"
});
var console: ConsoleThe console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A Console class with methods such as console.log(), console.error() andconsole.warn() that can be used to write to any Node.js stream.
* A global console instance configured to write to process.stdout and process.stderr. The global console can be used without callingrequire('console').
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to errconsole.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to `printf(3)` (the arguments are all passed to util.format()).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format() for more information.log(const post: PostReferencepost.PostReference.uri: ResourceUriThe post's AT URI.uri);
Refer to the Bot#post method documentation for more information on the available options.
If the post is successful, you should see its URI logged to your console.
You may notice that the URI begins with at://. This is an AT URI, used by AT Protocol applications to refer to data, such as posts, follows, and lists. More on this in the glossary!