Chatmail API for Go
July 24, 2026 · View on GitHub
Chatmail client & bot API for Golang.
Install
go get -u github.com/chatmail/rpc-client-go/v2
Installing deltachat-rpc-server
This package depends on a standalone Chatmail RPC server
deltachat-rpc-server program that must be available in your
PATH. For installation instructions check:
https://github.com/chatmail/core/tree/main/deltachat-rpc-server
WARNING: Install the version of deltachat-rpc-server that matches the version of this package,
different versions might be incompatible and cause unexpected errors.
Developing bots faster ⚡
If you want to develop bots, you should probably use this library together with deltabot-cli-go, it takes away the repetitive process of creating the bot CLI and let you focus on writing your message processing logic.
Usage
Example echo-bot that will echo back any text message you send to it:
package main
import (
"context"
"log"
"os"
"github.com/chatmail/rpc-client-go/v2/deltachat"
)
func logEvent(bot *deltachat.Bot, accId uint32, event deltachat.EventType) {
switch ev := event.(type) {
case *deltachat.EventTypeInfo:
log.Printf("INFO: %v", ev.Msg)
case *deltachat.EventTypeWarning:
log.Printf("WARNING: %v", ev.Msg)
case *deltachat.EventTypeError:
log.Printf("ERROR: %v", ev.Msg)
}
}
func runEchoBot(bot *deltachat.Bot, accId uint32) {
sysinfo, _ := bot.Rpc.GetSystemInfo()
log.Println("Running deltachat core", sysinfo["deltachat_core_version"])
bot.On(&deltachat.EventTypeInfo{}, logEvent)
bot.On(&deltachat.EventTypeWarning{}, logEvent)
bot.On(&deltachat.EventTypeError{}, logEvent)
bot.OnNewMsg(func(bot *deltachat.Bot, accId uint32, msgId uint32) {
msg, _ := bot.Rpc.GetMessage(accId, msgId)
if msg.FromId > deltachat.ContactLastSpecial {
reply := deltachat.MessageData{Text: &msg.Text}
if _, err := bot.Rpc.SendMsg(accId, msg.ChatId, reply); err != nil {
log.Printf("ERROR: %v", err)
}
}
})
if isConf, _ := bot.Rpc.IsConfigured(accId); !isConf {
log.Println("Bot not configured, configuring...")
botFlag := "1"
if err := bot.Rpc.SetConfig(accId, "bot", &botFlag); err != nil {
log.Fatalln(err)
}
if err := bot.Rpc.AddTransportFromQr(accId, os.Args[1]); err != nil {
log.Fatalln(err)
}
}
inviteLink, _ := bot.Rpc.GetChatSecurejoinQrCode(accId, nil)
log.Println("Listening at:", inviteLink)
if err := bot.Run(); err != nil {
log.Fatalln(err)
}
}
// Get the first available account or create a new one if none exists.
func getAccount(rpc *deltachat.Rpc) uint32 {
accounts, _ := rpc.GetAllAccountIds()
var accId uint32
if len(accounts) == 0 {
accId, _ = rpc.AddAccount()
} else {
accId = accounts[0]
}
return accId
}
func main() {
trans := deltachat.NewIOTransport()
if err := trans.Open(); err != nil {
log.Fatalln(err)
}
defer trans.Close()
rpc := &deltachat.Rpc{Context: context.Background(), Transport: trans}
runEchoBot(deltachat.NewBot(rpc), getAccount(rpc))
}
Save the previous code snippet as echobot.go then run:
go mod init echobot; go mod tidy
go run ./echobot.go dcaccount:nine.testrun.org
Check the examples folder for more examples.
Testing your code
deltachat.AcFactory is provided to help users of this library
to unit-test their code.
Using AcFactory
Create a file called main_test.go inside your tests folder,
and save it with the following content:
package main // replace with your package name
import (
"testing"
"github.com/chatmail/rpc-client-go/v2/deltachat"
)
var acfactory *deltachat.AcFactory
func TestMain(m *testing.M) {
acfactory = &deltachat.AcFactory{}
acfactory.TearUp()
defer acfactory.TearDown()
m.Run()
}
Now in your other test files you can do:
package main // replace with your package name
import (
"testing"
"github.com/chatmail/rpc-client-go/v2/deltachat"
"github.com/stretchr/testify/assert"
)
func TestEchoBot(t *testing.T) {
acfactory.WithOnlineBot(func(bot *deltachat.Bot, botAcc uint32) {
go runEchoBot(bot, botAcc) // this is the function we are testing
acfactory.WithOnlineAccount(func(uRpc *deltachat.Rpc, uAccId uint32) {
chatId := acfactory.CreateChat(uRpc, uAccId, bot.Rpc, botAcc)
_, _ = uRpc.MiscSendTextMessage(uAccId, chatId, "hi")
msg := acfactory.NextMsg(uRpc, uAccId)
assert.Equal(t, "hi", msg.Text) // check that bot echoes back the "hi" message from user
})
})
}
Check the complete example at examples/echobot_full
Contributing
Pull requests are welcome! check CONTRIBUTING.md