Threema Message API
Threema stellt kein grafisches User-Interface für den Threema Gateway zur Verfügung. Das Message API ist eine Schnittstelle, die aus kundenspezifischer Software heraus angesprochen werden kann, um Nachrichten via Threema Gateway zu versenden und zu empfangen.
Installation
Install PHP 8.1 or later: https://php.net/manual/en/install.php. No further installation steps should be required (except for Windows users).
Please make sure that a suitable OpenSSL version is present on your system (it should be).
Furthermore, you should verify that extension=php_sodium.dll
is present inside the php.ini
file (use either php.ini-development
or php.ini-production
as a template).
Make sure the config does not contain any errors by checking the output of php --ini
.
Afterwards, please verify the output of php -i
and make sure the line sodium support => enabled
is present or php -m
to see whether the "sodium" module is loaded.
Please note that OpenSSL can be extremely slow on Windows which might excessively slow down cryptographic operations.
Use console client
Local operations (no network communication)
Encrypt
./threema-msgapi-tool -e <privateKey> <publicKey>
Encrypt standard input using the given sender’s private key and the recipient’s public key. This prints two lines to standard output: first the nonce (hex), and then the box (hex).
Decrypt
./threema-msgapi-tool -D <privateKey> <publicKey> <nonce>
Decrypt standard input using the given recipient’s private key and the sender’s public key. The nonce must be given in the command line, and the box (hex) in the standard input. This prints the decrypted message to standard output.
$ echo "aff0..." | ./threema-msgapi-tool -D private:[PRIVATE_KEY] public:[PUBLIC_KEY] [NONCE]
Here, “aff0...” indicates the box (hex).As of version 2.1.0, the “
private:
“ and “public:
“ prefixes are optional for every occurrence of the respective key types in all commands (they were mandatory before).Hash Email Address
./threema-msgapi-tool -h -e <email>
Hash an email address for identity lookup. This prints the hash in hex.
Hash Phone Number
./threema-msgapi-tool -h -p <phoneNo>
Hash a phone number for identity lookup. This prints the hash in hex.
Generate Key Pair
./threema-msgapi-tool -g <privateKeyFile> <publicKeyFile>
Generate a new key pair and write the private and public keys to the respective files (in hex).
Derive Public Key
./threema-msgapi-tool -d <privateKey>
Derive the public key that corresponds with the given private key.
Network operations
Basic:
Send Simple Message
./threema-msgapi-tool -s <threemaId> <from> <secret>
Send a message from standard input with server-side encryption to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
E2E Messages:
Send End-to-End Encrypted Text Message
./threema-msgapi-tool -S <threemaId> <from> <secret> <privateKey> <quotedMessageId>
Encrypt standard input and send the text message to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
Send an End-to-End Encrypted File Message
./threema-msgapi-tool -S -f <threemaId> <from> <secret> <privateKey> <file> <renderingType> <thumbnailFile> <caption>
Encrypt the file (with renderingType, thumbnail, caption if given) and send the message to the given ID. 'from' is the API identity and 'secret' is the API secret. 'renderingType' must be either of 0 (file), 1 (media) or 2 (sticker). This prints the message ID on success.
Send an End-to-End Encrypted Image Message (deprecated, use the File Message type instead)
./threema-msgapi-tool -S -i <threemaId> <from> <secret> <privateKey> <imageFile>
Encrypt the image file and send the message to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
Send an End-to-End Encrypted Video Message (deprecated, use the File Message type instead)
./threema-msgapi-tool -S -v <threemaId> <from> <secret> <privateKey> <duration> <videoFile> <thumbnailFile>
Encrypt the video and thumbnail file and send the message to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
Send an End-to-End Encrypted Audio Message (deprecated, use the File Message type instead)
./threema-msgapi-tool -S -a <threemaId> <from> <secret> <privateKey> <duration> <audioFile>
Encrypt the audio file and send the message to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
Send an End-to-End Encrypted Location Message
./threema-msgapi-tool -S -l <threemaId> <from> <secret> <privateKey> <latitude> <longitude> <accuracy> <poiName> <poiAddress>
Encrypt a location and send the message to the given ID. 'from' is the API identity and 'secret' is the API secret. This prints the message ID on success.
Send an End-to-End Encrypted Ballot Create Message
./threema-msgapi-tool -S -b -c <threemaId> <from> <secret> <privateKey> <ballotId> <ballotTitle> <ballotChoices> <ballotDisplayMode>
Send a ballot create message. This prints the message ID on success.
Send an End-to-End Encrypted Ballot Vote Message
./threema-msgapi-tool -S -b -v <threemaId> <from> <secret> <privateKey> <ballotId> <ballotVotes>
Send a ballot vote message. This prints the message ID on success.
Send an End-to-End Encrypted Ballot Close Message
./threema-msgapi-tool -S -b -d <threemaId> <from> <secret> <privateKey> <ballotId> <ballotTitle> <ballotChoices> <ballotResults> <ballotDisplayMode>
Send a ballot close message. This prints the message ID on success.
Send an End-to-End Encrypted Group Create Message
./threema-msgapi-tool -G -c <threemaIds> <from> <secret> <privateKey> <groupId> <members>
Send a group create to the given IDs (members are comma-separated group members, no members = remove group).
Send an End-to-End Encrypted Group Rename Message
./threema-msgapi-tool -G -r <threemaIds> <from> <secret> <privateKey> <groupId> <subject>
Send a group rename to the given IDs.
Group Messages:
Send an End-to-End Encrypted Set Group Photo Message
./threema-msgapi-tool -G -p <threemaIds> <from> <secret> <privateKey> <groupId> <photo>
Send group avatar.
Send an End-to-End Encrypted Delete Group Photo Message
./threema-msgapi-tool -G -d -p <threemaIds> <from> <secret> <privateKey> <groupId>
Delete group avatar.
Send an End-to-End Encrypted Group Ballot Create Message
./threema-msgapi-tool -G -b -c <threemaIds> <from> <secret> <privateKey> <groupId> <ballotId> <ballotTitle> <ballotChoices> <ballotDisplayMode>
Send a group ballot create message. This prints the message IDs on success.
Send an End-to-End Encrypted Group Ballot Vote Message
./threema-msgapi-tool -G -b -v <threemaIds> <from> <secret> <privateKey> <groupId> <ballotId> <ballotVotes>
Send a group ballot vote message. This prints the message IDs on success.
Send an End-to-End Encrypted Group Ballot Close Message
./threema-msgapi-tool -G -b -d <threemaIds> <from> <secret> <privateKey> <groupId> <ballotId> <ballotTitle> <ballotChoices> <ballotResults> <ballotDisplayMode>
Send a group ballot close message. This prints the message IDs on success.
Send End-to-End Encrypted Group Text Message
./threema-msgapi-tool -G -S <threemaIds> <from> <secret> <privateKey> <groupId> <quotedMessageId>
Encrypt standard input and send the group text message to the given IDs. 'from' is the API identity and 'secret' is the API secret. The 'groupId' consists of both the group creator (for this example we will call it "*GATEWAY") + group identifier (here, "GROUPID1"), e.g., "*GATEWAYGROUPID1". This prints the message IDs on success.
Send an End-to-End Encrypted Group File Message
./threema-msgapi-tool -G -S -f <threemaIds> <from> <secret> <privateKey> <groupId> <file> <renderingType> <thumbnailFile> <caption>
Encrypt the file (with renderingType, thumbnail, caption if given) and send the messages to the given IDs. 'from' is the API identity and 'secret' is the API secret. The 'groupId' consists of both the group creator (for this example we will call it "*GATEWAY") + group identifier (here, "GROUPID1"), e.g., "*GATEWAYGROUPID1". 'renderingType' must be either of 0 (file), 1 (media) or 2 (sticker). This prints the message IDs on success.
Send an End-to-End Encrypted Group Location Message
./threema-msgapi-tool -G -S -l <threemaId> <from> <secret> <privateKey> <groupId> <latitude> <longitude> <accuracy> <poiName> <poiAddress>
Encrypt a group location and send it to the given IDs. 'from' is the API identity and 'secret' is the API secret. The 'groupId' consists of both the group creator (for this example we will call it "*GATEWAY") + group identifier (here, "GROUPID1"), e.g., "*GATEWAYGROUPID1". This prints the message IDs on success.
Lookup:
ID-Lookup By Email Address
./threema-msgapi-tool -l -e <email> <from> <secret>
Lookup the ID linked to the given email address (will be hashed locally).
ID-Lookup By Phone Number
./threema-msgapi-tool -l -p <phoneNo> <from> <secret>
Lookup the ID linked to the given phone number (will be hashed locally).
Bulk ID-Lookup By Email Addresses and Phone Numbers
./threema-msgapi-tool -l -B <from> <secret> <emailAddresses> <phoneNumbers>
Lookup the ID linked to the given phone number (will be hashed locally).
Fetch Public Key
./threema-msgapi-tool -l -k <threemaId> <from> <secret>
Lookup the public key for the given ID.
Fetch Capabilities
./threema-msgapi-tool -c <threemaId> <from> <secret>
Fetch the capabilities of a Threema ID.
Decrypt a Message and download the Files
./threema-msgapi-tool -r <threemaId> <from> <secret> <privateKey> <messageId> <nonce> <outputFolder>
Decrypt a box (must be provided on stdin) message and download (if the message is an image or file message) the file(s) to the given <outputFolder> folder.
Remaining credits
./threema-msgapi-tool -C <from> <secret>
Fetch remaining credits.
<publicKey>
describes the recipient’s key, not the key of the Gateway ID.Create a Connection
use Threema\MsgApi\Connection;
use Threema\MsgApi\ConnectionSettings;
use Threema\MsgApi\Receiver;
require_once('vendor/autoload.php');
//define your connection settings
$settings = new ConnectionSettings(
'*YOUR_GATEWAY_THREEMA_ID',
'YOUR_GATEWAY_THREEMA_ID_SECRET'
);
$publicKeyStore = new Threema\MsgApi\PublicKeyStores\File('/path/to/your/keystore.txt');
$connector = new Connection($settings, $publicKeyStore);
Send a Text Message to a Threema ID (Basic Mode)
//create the connection
//(...)
//create a receiver
$receiver = new Receiver('ABCD1234', Receiver::TYPE_ID);
$result = $connector->sendSimple($receiver, "This is a Test Message");
if($result->isSuccess()) {
echo 'Message ID: '.$result->getMessageId();
} else {
echo 'Error: '.$result->getErrorMessage();
}
Send a Text Message to a Phone-Number (Basic Mode)
//create the connection
//(...)
//create a receiver
$receiver = new Receiver('12345678901', Receiver::TYPE_PHONE);
$result = $connector->sendSimple($receiver, "This is a Test Message");
if($result->isSuccess()) {
echo 'Message ID: '.$result->getMessageId();
}
else {
echo 'Error: '.$result->getErrorMessage();
}
Send a Text Message to a Threema ID (End-To-End Mode)
//create the connection
//(...)
$threemaId = 'ABCD1234';
$msg = "This is an end-to-end encrypted message";
// Specify your own private key in hex below (without the "private:" prefix)
$senderPrivateKey = hex2bin("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
$e2eHelper = new \Threema\MsgApi\Helpers\E2EHelper($senderPrivateKey,$connector);
$result = $e2eHelper->sendTextMessage($threemaId, $msg);
if(true === $result->isSuccess()) {
echo 'Message ID: '.$result->getMessageId() . "\n";
} else {
echo 'Error: '.$result->getErrorMessage() . "\n";
}
Send a File Message to a Threema ID (End-To-End Mode)
//create the connection
//(...)
$threemaId = 'ABCD1234';
$msg = "This is an end-to-end encrypted message";
$filePath = "/path/to/my/file.pdf";
// Specify your own private key in hex below (without the "private:" prefix)
$senderPrivateKey = hex2bin("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
$e2eHelper = new E2EHelper($this->senderPrivateKey, $this->connector);
$result = $e2eHelper->sendFileMessage($threemaId, $filePath, caption: $msg, renderingType: FileRenderingType::MEDIA);
if (true === $result->isSuccess()) {
echo 'Message ID: ' . $result->getMessageId() . "\n";
} else {
echo 'Error: ' . $result->getErrorMessage() . "\n";
}
Receiving messages at the incoming message URL (End-To-End Mode only)
//create the connection
//(...)
//get incoming data
$data = $_REQUEST;
$result = $e2eHelper->receiveMessage($data['from'], $data['messageId'], $data['box'], $data['nonce'], ...);
if (true === $result->isSuccess()) {
$msg = $result->getThreemaMessage();
if ($msg instanceof TextMessage) {
echo 'IS QUOTE: ' . $msg->isQuote();
$messageText = $msg->getText();
} else {
// ...
}
echo 'Message ID: ' . $result->getMessageId() . "\n";
}
Creating a connection with advanced options
Attention
These settings change internal values of the TLS connection. Choosing wrong settings can weaken the TLS connection or prevent a successful connection to the server. Use them with care!
Each of the additional options shown below is optional. You can leave it out or use null to use the default value for this option.
use Threema\MsgApi\Connection;
use Threema\MsgApi\ConnectionSettings;
use Threema\MsgApi\Receiver;
require_once('vendor/autoload.php');
//define your connection with advanced options
$settings = new ConnectionSettings(
'*THREEMA',
'THISISMYSECRET'
//the host to be used, set to null for default (recommend)
null, [
//set to true to force HTTPS, default: false
'forceHttps' => true,
//set the version of TLS to be used, default: null
'tlsVersion' => '1.2',
//choose a cipher or a list of ciphers, default: null
'tlsCipher' => 'ECDHE-RSA-AES128-GCM-SHA256'
]
);
//simple php file to store the public keys
$publicKeyStore = new Threema\MsgApi\PublicKeyStores\PhpFile('/path/to/my/keystore.php');
//create a connection
$connector = new Connection($settings, $publicKeyStore);