PrivMX DOCS
Version 2.3/Threads

Managing Threads

At their core, Threads provide a secure way for assigned members to exchange encrypted messages.

  • Threads allow users to communicate using topic-specific communication channels.
  • Each Context can contain any number of Threads with a unique identifier (threadId) used to distinguish them.
  • Threads do not need to have unique names or assigned public keys.

Permissions

Threads differentiate two types of users - Managers and Regular Users. The table below shows the differences in their permissions:

ActivityUserManager
Sending messagesyesyes
Editing Threadnoyes
Deleting messagesonly their ownall messages

The values above are the default policy values defined by PrivMX. To read more about Policies and learn how to modify them, go to Policies.

Initial Assumptions

The initial assumptions for all the code examples below are as follows:

#include <privmx/endpoint/core/Connection.hpp>
#include <privmx/endpoint/thread/ThreadApi.hpp>
#include <privmx/endpoint/core/Buffer.hpp>
// ...

/* 
All the values below like BRIDGE_URL, SOLUTION_ID, CONTEXT_ID
should be replaced by the ones corresponding to your Bridge Server instance.

The private keys here are for demonstration purposes only. 
Normally, they should be kept separately by each user and stored in a safe place,
or generated from a password (see the derivePrivateKey2() method in the Crypto API).
*/

std::string BRIDGE_URL {"http://localhost:9111"};
std::string SOLUTION_ID {"YOUR_SOLUTION_ID"};
std::string CONTEXT_ID {"YOUR_CONTEXT_ID"};

std::string USER1_ID {"user_1"};
std::string USER1_PUBLIC_KEY {"PUBLIC_KEY_1"};
std::string USER1_PRIV {"PRIVATE_KEY_1"};

std::string USER2_ID {"user_2"};
std::string USER2_PUBLIC_KEY {"PUBLIC_KEY_2"};

std::string USER3_ID {"user_3"};
std::string USER3_PUBLIC_KEY {"PUBLIC_KEY_3"};

// initialize Endpoint connection and Threads API
auto connection {core::Connection::connect(USER1_PRIV, SOLUTION_ID, BRIDGE_URL)};
auto threadApi {thread::ThreadApi::create(connection)};

Creating Threads

To create a Thread, you need a name and a list of public key - userID pairs. Due to the fact that each Thread is inside a Context, all the public keys have to be registered inside the given Context. You can do it using PrivMX Bridge API.

After creating a Thread, all the users with management rights will be able to edit the Thread.

Below you can see some examples of creating Threads that function as a chat feature in your application, with access management capabilities similar to those found in other popular collaboration tools.

std::vector<core::UserWithPubKey> managers{
    core::UserWithPubKey{USER1_ID, USER1_PUBLIC_KEY}
};
std::vector<core::UserWithPubKey> users{
    core::UserWithPubKey{USER1_ID, USER1_PUBLIC_KEY},
    core::UserWithPubKey{USER2_ID, USER2_PUBLIC_KEY}
};
auto threadId {threadApi.createThread(CONTEXT_ID, users, managers, 
    core::Buffer::from("some thread's public meta-data"), 
    core::Buffer::from("some thread's private meta-data")
)};

Listing Threads

Your application may include multiple Threads, each associated with different Contexts. You can retrieve a list of all Threads within a given Context. This list will include useful metadata about the Threads, such as the creation date, the last message upload date, user list, and information about the last modification. However, to optimize performance, the list will only include the total number of messages in each Thread, not the full message content.

Here's an example of how to download the last 30 Threads created within a Context:

// list threads
core::PagingQuery query = {.skip = 0, .limit = 30, .sortOrder = "desc"};

auto result {threadApi.listThreads(CONTEXT_ID, query)};
for (const auto& thread : result.readItems) {
    std::cout << "Thread ID: " << thread.threadId << std::endl;
}

To limit collecting too much data when downloading Threads, specify the page index (starting from 0) and the number of items to be included on each page.

Modifying Threads

Depending on your project's specification, it may be necessary to modify a Thread. It could be e.g. changing the name or adding/removing users. Each user with management rights is able to modify Thread, delete them as a whole or only particular messages.

Updating a Thread means overwriting it with the provided data. To successfully update a Thread, you must specify its current version. The version field is mandatory to handle multiple updates on the server and it is incremented by 1 with each update.

Below there is an example of modifying a Thread:

std::vector<core::UserWithPubKey> newUsersList{
    core::UserWithPubKey{USER1_ID, USER1_PUBLIC_KEY},
    core::UserWithPubKey{USER2_ID, USER2_PUBLIC_KEY}
    core::UserWithPubKey{USER3_ID, USER3_PUBLIC_KEY}
};

auto threadInfo {threadApi.getThread(threadId)};

threadApi.updateThread(threadId, newUsersList, managers, 
    core::Buffer::from("some new thread's public meta-data"), 
    core::Buffer::from("some new thread's private meta-data"), threadInfo.version, false, false
);

Three additional options are available when changing the list of users inside a Thread:

  • force - applies an update, without checking the current version;
  • forceGenerateNewKey - re-encrypts messages in the Thread. It's useful when a user is removed and we want to prevent them from accessing the Thread.
  • policies - allow you to manage access to Threads and messages. Read more about Policies.

Deleting Threads

Deleting a Thread also removes all message data associated with it.

Below there is an example of deleting a Thread:

threadApi.deleteThread(threadId);

We use cookies on our website. We use them to ensure the proper functioning of the site and, if you agree, for purposes we set, such as analytics or marketing.

This is documentation for PrivMX v2.3, which is no longer actively maintained.

For up-to-date documentation, go to latest here

On this page