DEV Community

Emalp
Emalp

Posted on

Writing a simple SMS sending reminder app for absolute absent minded people like me.

I am very very very forgetful and am too lazy to do anything about it. I wanted the simplest form of reminder where I would not need to download any complex apps and the notification sent by the reminder would repeat itself after a certain specified days.

Finally I gathered the guts in my uni holidays to write something that is absolutely in it's simplest form and would hit in the most precious human activation zone; the SMS text. So I'll try and write a simple program that sends me a SMS every certain days with a special message.

For this I'll be using the Telstra SMS API. It gives us 1000 free SMS which is enough for me as I'll be sending maximum of just 2 SMS per week, thats only about 104 SMS per year. I'll also be utilising the python Schedule module to help me manage my schedules. So let's begin!

First of all lets import all required stuff:

from __future__ import print_function
import time
import Telstra_Messaging
from Telstra_Messaging.rest import ApiException
from datetime import datetime
Enter fullscreen mode Exit fullscreen mode

Now lets setup the Telstra SMS API:


class SMSender():
    client_id = 'your_client_id' # str | 
    client_secret = 'your_client_secret' # str | 
    grant_type = 'client_credentials' # str |  (default to 'client_credentials')

    def __init__(self):
        self.configuration = Telstra_Messaging.Configuration()

    def authenticate_client(self):
        api_instance = Telstra_Messaging.AuthenticationApi(Telstra_Messaging.ApiClient(self.configuration))

        try:
            # Generate OAuth2 token
            self.api_response = api_instance.auth_token(self.client_id, self.client_secret, self.grant_type)

        except ApiException as e:
            print("Exception when calling AuthenticationApi->auth_token: %s\n" % e)

    def provision_client(self):
        self.configuration.access_token = self.api_response.access_token
        api_instance = Telstra_Messaging.ProvisioningApi(Telstra_Messaging.ApiClient(self.configuration))
        provision_number_request = Telstra_Messaging.ProvisionNumberRequest() 

        try:
            # Create Subscription
            api_response = api_instance.create_subscription(provision_number_request)
            api_response = api_instance.get_subscription()

        except ApiException as e:
            print("Exception when calling ProvisioningApi->create_subscription: %s\n" % e)

    def send_sms(self, msg_to, msg_body):
        api_instance = Telstra_Messaging.MessagingApi(Telstra_Messaging.ApiClient(self.configuration))
        send_sms_request = Telstra_Messaging.SendSMSRequest(to=msg_to, body=msg_body)

        try:
            # Send SMS
            api_response = api_instance.send_sms(send_sms_request)
            return True

        except ApiException as e:
            print("Exception when calling MessagingApi->send_sms: %s\n" % e)
Enter fullscreen mode Exit fullscreen mode

As you can see, each function does a specific work.

authenticate_client
Authenticates with our client id and secret with the Telstra API. After that
provision_client
provision's our client with a new phone number. In the end
send_sms
is a simple method to send SMS to whatever phone number with specific message.

Now for the fun part, let's start to code our Scheduling portion of the program.

We will have 3 functions for this part.
The first one is add_repeat_sequence:

def add_repeat_sequence(self, date_from=datetime.today(),\
         repeat_after_days=1, at_time="09:30", msg="This is your alarm!!", to="0444444444"):


        right_now = int(datetime.today().timestamp())
        date_from = int(date_from.timestamp())

        if date_from < today:
            raise ValueError("date_from cannot be before right_now")
        else:
            time_diff = date_from - right_now

            t = Timer(time_diff, self.set_alarm, [repeat_after_days, at_time, msg, to])
            t.start()
Enter fullscreen mode Exit fullscreen mode

This function is to basically set an alarm at an specified date, given by "date_from". After our timer completes it runs the "set_alarm" function with the parameters given in the list.

We will now write the "set_alarm" function which is passed in the Timer's parameter. This function will be called when our timer setting date has approached.

    def set_alarm(self, day_diff, time_alarm, msg, to):

        self.send_alarm(msg, to)

        if day_diff <= 1:
            schedule.every().day.at(time_alarm).do(self.send_alarm, msg, to)
        else:
            schedule.every(day_diff).days.at(time_alarm).do(self.send_alarm, msg, to)
Enter fullscreen mode Exit fullscreen mode

Here, out set_alarm basically leverages our 'schedule' package to repeat the timer at certain days interval.

Finally the "send_alarm" used by "set_alarm" is used to send the actual message:

    def send_alarm(self, msg, to):
        sender = SMSender()
        sender.authenticate_client()
        sender.provision_client()
        sender.send_sms(to, msg)
        print("Alarm successfully sent!")
Enter fullscreen mode Exit fullscreen mode

The send_alarm uses the previously coded SMSender to send the message.
Finally wrap these three functions into a Repeater class and that's it!

Finally our main function looks like:

if __name__ == "__main__":

    repeat = Repeater()
    starting_date = datetime.today()
    repeat.add_repeat_sequence(date_from=starting_date, repeat_after_days=14, msg="Heyaaaaa!", \
        to="+61444444444")


    while True:
        schedule.run_pending()
        time.sleep(1)
Enter fullscreen mode Exit fullscreen mode

This will successfully send us a "Heyaaaaa!" every 14 days starting today.

Hope you liked the post. This is only a simple skeleton to provide a gist. There's still a lot of space for proper error checking, code testing and good code design. Feel free to change the code in whatever way you'd find yourself using it! All you need to do is run it in a server somewhere where it can run uninterrupted.

Thanks a lot!

You can find the full version of the code here in my github.

Top comments (2)

Collapse
 
owurasafo profile image
owurasafo

I'm novice in python programming. I entered the whole projwct in jupyter notebook and ran it. I had no error. How do I let it work after saving it?

Collapse
 
emalp profile image
Emalp

Jupyter notebook is only meant to make the development easier. After your project works in jupyter, you need to rewrite it and change it into an individual python project using an IDE. After that you can just run the project as a background application in a server. An easy way to do this would be to run it using "python app.py &" in a linux server.