Skip to content

Messaging

Our platform relies on secure and encrypted messaging for all communication between nodes.

These messages are basically JSON objects containing the necessary information for each operation.

Let's have a look at how you can send and receive messages with the Self SDK.

Sending a Message

Sending messages is straightforward, you just need to provide the message content and the recipient address.

1
2
3
4
5
content, err := message.NewChat().
    Message("Hello world!").
    Finish()

err := selfAccount.MessageSend(address, content)
1
2
3
4
5
6
val chat = ChatBuilder()
    .message("Hello world!")
    .finish()

val sendStatus = account.messageSend(address, chat)
println("send status:${sendStatus.code()} - messageId:${chat.id().toHexString()}")
1
2
3
4
5
6
7
8
val chat = ChatMessage.Builder()
    .setToIdentifier(address)
    .setMessage("Hello world!")        
    .build()

account.send(chat) { messageId, _ ->
    println("sent chat messageId:${messageId}")
}

Note: Check out the Discovery section for documentation on how to obtain the node address.

Content is the message payload, which can be of different types, such as TypeChat, TypeDiscoveryRequest, TypeCredentialVerificationRequest, etc.

The SDK provides several helper methods to create the content of the message, such as NewChat(), NewDiscoveryRequest(), NewCredentialVerificationRequest(), and so on.

Each type of message has its own set of properties and methods, but they all follow the same pattern of being created with a builder pattern, using the Finish() method to return the final message content.

Receiving Messages

During the SDK configuration process, you can set the OnMessage hook to handle incoming messages.

Same as when sending messages, you will receive different types of messages, each one with its own type and payload.

First thing to do when receiving a message is to check its type:

1
2
3
4
5
6
7
8
cfg.Callbacks.OnMessage = func(selfAccount *account.Account, msg *event.Message) {
    switch event.ContentType(msg) {
    case event.TypeChat:
        // ...
    case event.TypeDiscoveryResponse:
        // ...
    }
}
account.configure(
    // ... other config options ...
    onMessage = { message: Message ->
        val content = message.content()
        when (content.contentType()) {
            ContentType.CHAT -> {
                // Handle chat messages
            }
            ContentType.DISCOVERY_RESPONSE -> {
                // Handle discovery responses
            }
        }
    }
)
1
2
3
account.setOnMessageListener { msg ->
    println("received message $msg")
}

Once you have identified the type of message, you can decode it using the appropriate decoder function. For chat messages, you can access various properties like this:

case event.TypeChat:
    chat, err := message.DecodeChat(msg.Content())
    if err != nil {
        log.Warn("failed to decode chat", "error", err)
        return
    }

    log.Info(
        "received chat message",
        "from", msg.FromAddress().String(),
        "messageId", hex.EncodeToString(msg.ID()),
        "referencing", hex.EncodeToString(chat.Referencing()),
        "message", chat.Message(),
        "attachments", len(chat.Attachments()),
    )
ContentType.CHAT -> {
    val chat = Chat.decode(content)
    println(
        "received chat message " +
        "\nfrom:${message.fromAddress().encodeHex()}" +
        "\nmessageId:${message.id().toHexString()}" +
        "\nmessage:${chat.message()}" +
        "\nattachments:${chat.attachments().size}"
    )
}
account.setOnMessageListener { msg ->
    when (msg) {
        is ChatMessage -> {
            println(
                "received chat message " +
                "\nfrom:${msg.fromIdentifier()}" +
                "\nmessageId:${msg.id()}" +
                "\nmessage:${msg.message()}" +
                "\nattachments:${msg.attachments().size}"
            )
        }
        is Receipt -> {
        }
    }
}

Each type of message has its own set of properties and methods that you can use to access the message content and metadata.

Note: You can find a complete example at https://github.com/joinself/self-go-sdk/blob/main/examples/chat/main.go