Writing a simple SMS sending reminder app for absolute absent minded people like me.
Tags: python, telstraapi, sms, schedule
Published: 2019-12-13 01:23:43

---
title: Writing a simple SMS sending reminder app for absolute absent minded people like me.
published: true
description: Simple SMS reminder.
tags: #python #telstraapi #SMS #schedule
---

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](https://dev.telstra.com/content/messaging-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](https://pypi.org/project/schedule/) module to help me manage my schedules. So let's begin!

First of all lets import all required stuff:
```python
from __future__ import print_function
import time
import Telstra_Messaging
from Telstra_Messaging.rest import ApiException
from datetime import datetime
```


Now lets setup the Telstra SMS API:

```python

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)
```

As you can see, each function does a specific work. <pre>authenticate_client</pre> Authenticates with our client id and secret with the Telstra API. After that <pre>provision_client</pre> provision's our client with a new phone number. In the end <pre>send_sms</pre> 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:

```python
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()
```

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.

```python
    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)
```

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:

```python
    def send_alarm(self, msg, to):
        sender = SMSender()
        sender.authenticate_client()
        sender.provision_client()
        sender.send_sms(to, msg)
        print("Alarm successfully sent!")
```

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:

```python
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)
```

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.](https://github.com/emalp/reminder)