Ghost Threads

Support ghost message threads in your app

Ghost threads are a different type of thread that doesn't persist any messages to database storage. Instead, messages are sent from one peer to the rest of the network using ipfs pubsub, and upon receipt by other online peers are kept in-memory. New users coming online or just joining the network can request the message history from online peers.

Ghost threads are currently only available in the open variety, meaning that any user who knows the ghost thread name can read, join, and post messages in the thread.

Get Started

Step by step instructions on how to add ghost threads to your application:

  1. Add posts

1. Configure your threads

Before getting started, you should consider a few configuration options for your ghost thread, which will make later steps more simple.

You only need to perform this step if you are creating a new ghost thread. If you want to join an existing thread, then proceed to Step 3 (join an existing thread).

First, confirm you need a ghost thread.

The first step in configuring a ghost thread is making sure you actually need a Ghost Thread, and not a Persistent Thread. If you're unsure which type of thread to implement, read the page on choosing your thread.

Then, choose a name for your space.

Ghost threads are access controlled using 3Box spaces. These spaces are created and exist inside the 3Box of each user that joins the ghost thread, not in one single global space. Before proceeding you should choose a name for the space that you will use to store your app's Ghost threads.

In most cases, the name of the space should be the name of your application.

We recommend simply using the name of your application for this threads space, unless you want your application's threads managed by a different space for some reason. This space is an OrbitDB key-value store, so you can also keep other information and data related to your application inside it.

For example, if your application is called CheeseWizards, we would recommend your space be namedcheeseWizards.

Finally, choose a naming convention for your threads.

All ghost threads are uniquely identified by their space name and thread name. If either of these variables differs, you will get an entirely different thread.

For thread name, we recommend creating some standard convention that allows your application to easily create and manage many threads. While you can decide what this convention is, you may consider using some URL, a topic, or something else unique.

Spinning up a 3Box Ghost Pinbot server 👻

In order to provide you with better experience for using the Ghost Threads API we created a Ghost Pinbot service. This service lets you specify the one or more threads whose messages will be pinned, and in that way help you overcome the common issues in the decentralised realm of messaging such as peer discovery, the initial state sync time and others..

More information about the service and its usage can be found in this blogpost.

2. Create a new thread

Authenticate the Space

The first step in interacting with ghost threads is to authenticate the Space where the thread(s) will be accessed and referenced. This should have already been done in Step 3. Authenticate a Space of the overall flow of adding 3Box to your web app, but if you haven't first authenticated the Space for your Ghost Threads, use this code to do so:

const space = await box.openSpace('mySpace')

Note: If the user already has a space with this name, your application will gain access to it; if the user does not have the space, this method will automatically create one for them.

Create a new thread

In the code example below, let space be the space from the previous step, and 'myThread' be your specific thread name.

Use the space.joinThread() method to create a new thread:

const thread = await space.joinThread('myThread', {
ghost: true,
ghostBacklogLimit: 20 // optional and defaults to 50
})

3. Join an existing thread

Before joining an existing thread so you can post messages to it, you will need to authenticate the space which stores reference to the ghost thread, as mentioned in Step 2.

In the code example below, let space be the space from the previous step, and 'myThread' be your specific thread name.

Use the space.joinThread() method to join an existing ghost thread.

const thread = await space.joinThread('myThread', {
ghost: true,
ghostBacklogLimit: 20 // optional and defaults to 50
})

4. View posts

Display current posts in a Ghost Thread

To get all posts in a thread or request a specific number of messages from the backlog, use thread.getPosts().

const posts = await thread.getPosts()
console.log(posts)
// you can also specify a number of posts you want
const posts = await thread.getPosts(20)
console.log(posts)

Listen for updates to the Ghost Thread

To listen for updates to a thread, such as new posts, use thread.onUpdate(). This will allow you to immediately display new messages posted in the thread in your application.

thread.onUpdate(() => {
const posts = await thread.getPosts()
console.log(posts)
})

5. View Members

List current members in a Thread

The listMembers() method will return an array of space 3IDs for users in the chatroom.

const userList = await thread.listMembers()

Update when members join or leave the Thread

Use this code to optionally post a 'User joined/left the chat' message to the thread when new users join or leave:

thread.onNewCapabilities((event, did) => console.log(did, event, ' the chat'))

The event parameter is a string that is either: joined or left.

6. Add posts

Broadcast message to all peers

Everyone who can read the thread will have access to the message.

await thread.post('hello everyone')

7. Leave a thread

Leave the Ghost Thread

await thread.close()