Unlike an Android or IOS phone, the Librem 5 and Liberty Phones are easily scriptable. You can bend your phone software to your will in a variety of programming languages. In this Easy App Development blog, we’ll cover making a text-forwarding system. Elements covered here can be used to take full control of your phone’s texting capabilities. 

PureOS Texting

On PureOS, messaging (including texting), is handled with our app Chatty. This is a convenient way to handle Matrix chat, XMPP, and Texting all in the same place. For text messaging, Chatty uses the backend called mmcli, and mmcli is where all the magic really happens. You can get an idea of what mmcli can do by running man mmcli. At the end of the day, mmcli is what will be talking to our modem. 

Conflicting Software

Playing around with mmcli, I noticed texts don’t stay on the modem; another process was handling these and removing them. Of course, this is just Chatty processing texts as it adds them to the user interface. As a simple way to quit chatty, the killall command is quick and dirty. 

# Bash
for i in 1 2 3; do killall chatty; done

# Python
for i in range(0,10):
    os.system("killall chatty")

Reading Incoming Texts

With Chatty stopped, we are free to use mmcli to read what messages are on the modem. 

mmcli -m any --messaging-list-sms

    /org/freedesktop/ModemManager1/SMS/0 (received)

This shows that we have an SMS with the ID of 0 on the modem. Use the following to get the details, including message text. 

mmcli -s <TEXT_ID> --output-keyvalue

To read our SMS with ID 0, the following outputs the data in an easily parsable manner. 

$ mmcli -s 0 --output-keyvalue
sms.dbus-path : /org/freedesktop/ModemManager1/SMS/0
sms.content.number : +1111111111
sms.content.text : Test
sms.content.data : --
sms.properties.pdu-type : deliver
sms.properties.state : received
sms.properties.validity : --
sms.properties.storage : me
sms.properties.smsc : +140500000
sms.properties.class : --
sms.properties.teleservice-id : --
sms.properties.service-category : --
sms.properties.delivery-report : --
sms.properties.message-reference : --
sms.properties.timestamp : 2024-01-12T10:18:52-08
sms.properties.delivery-state : --
sms.properties.discharge-timestamp : --

In Python, you can get messages ready for reading with:

def get_new_messages(raw_messages):
    received_ids = []
    for line in raw_messages.split("\n"):
        if "received" in line:
            received_ids.append(int(line.split("/")[-1].split(" ")[0]))
    return(received_ids)

And read that data with:

def get_text_by_id(ID):
    cmd = ['mmcli', '-s', str(ID), '--output-keyvalue']
    result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    sender_phone = ""
    for line in result.decode().split('\n'):
        if line.startswith("sms.content.number"):
            sender_phone = line.split("sms.content.number")[-1]
            sender_phone = sender_phone.strip()
            sender_phone = sender_phone[2:]
            sender_phone = sender_phone.replace('\\n','\n')
            # TODO check sender_phone and return
        if line.startswith("sms.content.text"):
            text = line.split("sms.content.text")[-1]
            text = text.strip()
            text = text[2:]
            text = text.replace('\\n','\n')
            return(sender_phone, text)

Cleaning Up 

Once you read and process a text, you need to remove it from the modem. If you don’t do this, things will get messy very fast. 

Remove message from modem

sudo mmcli -m any --messaging-delete-sms=<TEXT_ID>

Remove message with ID 0

sudo mmcli -m any --messaging-delete-sms=0

Sending Texts

To send a message, we need to create the message on the modem and then use the mmclisend option on your newly created Text ID. Finally, we need to remove the sent text from the modem. In bash that looks like this:

text="Example Text"
phone="+12223334444"
message_values="text='$text',number='$phone'"
# Send text to the modem
output=$(sudo mmcli -m any --messaging-create-sms="$message_values")
# Send SMS
message_id=$(echo $output | rev | cut -d '/' -f1 | rev)
sudo mmcli -s $message_id --send
# Remove the sent message from the modem
sudo mmcli -m any --messaging-delete-sms=$message_id

Email forwarding

For programmatic email forwarding, an email service that supports SMTP, like our Librem.one service, is very handy. In python something like this works perfectly. 

import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

############### Needed Email Info ##############
#################### Target ####################
FOWARD_EMAIL="" #Email to forward texts to #
#################### SENDER ####################
ACCOUNT="" #Email to use for sending #
ACCOUNT_PASSWD="" #Account Password #
ACCOUNT_SMTP="" #SMTP host #
ACCOUNT_PORT = 465 #SMTP port #
################################################
def send_email(title, message_text):
    message = MIMEMultipart("alternative")
    message["Subject"] = title
    message["From"] = ACCOUNT
    message["To"] = FOWARD_EMAIL
    message.attach(MIMEText(message_text, "plain"))

    with smtplib.SMTP_SSL(ACCOUNT_SMTP, ACCOUNT_PORT, context=context) as server:
        server.login(ACCOUNT, ACCOUNT_PASSWD)
        server.sendmail(ACCOUNT, FOWARD_EMAIL, message.as_string())
    print("Sent email")

Putting It Together

With all those bits, a text-to-email forwarding system looks something like this. You can rearrange this script into an auto-reply system or proper texting app or slowly transfer whatever data you want over a very slow data pipe. 

Purism Products and Availability Chart

 ModelStatusLead Time 
USB Security Token Purism Librem KeyLibrem Key

(Made in USA)
In Stock
($59+)
10 business days
Librem 5In Stock
($699+)
3GB/32GB
10 business days
Librem 5 COMSEC BundleIn Stock
($1299+)
Qty 2; 3GB/32GB
10 business days
Purism Liberty Phone with Made in USA ElectronicsLiberty Phone
(Made in USA Electronics)
Backorder
($1,999+)
4GB/128GB
Estimated fulfillment February
Librem 5 + SIMple
(3 GB Data)
In Stock
($99/mo)
10 business days
Librem 5 + SIMple Plus
(5 GB Data)
In Stock
($129/mo)
10 business days
Librem 5 + AweSIM
(Unlimited Data)
In Stock
($169/mo)
10 business days
Librem 11In Stock
($999+)
8GB/1TB
10 business days
Most Secure Laptop Purism Librem 14Librem 14Backorder
($1,370+)
Estimated fulfillment December
Most Secure PC Purism Librem Mini
Librem MiniBackorder
($799+)
10 business days
Most Secure Server Purism Librem ServersLibrem ServerIn Stock
($2,999+)
45 business days
The current product and shipping chart of Purism products, updated on October 18th, 2024

Recent Posts

Related Content

Tags