Telstra Notification add-on

"""
Telstra API platform for notify component.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.telstra/
"""
import logging

import requests
import voluptuous as vol

from homeassistant.components.notify import (
    BaseNotificationService, ATTR_TITLE, PLATFORM_SCHEMA)
from homeassistant.const import CONTENT_TYPE_JSON, HTTP_HEADER_CONTENT_TYPE
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

CONF_CONSUMER_KEY = 'consumer_key'
CONF_CONSUMER_SECRET = 'consumer_secret'
CONF_PHONE_NUMBER = 'phone_number'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_CONSUMER_KEY): cv.string,
    vol.Required(CONF_CONSUMER_SECRET): cv.string,
    vol.Required(CONF_PHONE_NUMBER): cv.string,
})


def get_service(hass, config, discovery_info=None):
    """Get the Telstra SMS API notification service."""
    consumer_key = config.get(CONF_CONSUMER_KEY)
    consumer_secret = config.get(CONF_CONSUMER_SECRET)
    phone_number = config.get(CONF_PHONE_NUMBER)

    if _authenticate(consumer_key, consumer_secret) is False:
        _LOGGER.exception("Error obtaining authorization from Telstra API")
        return None

    return TelstraNotificationService(
        consumer_key, consumer_secret, phone_number)


class TelstraNotificationService(BaseNotificationService):
    """Implementation of a notification service for the Telstra SMS API."""

    def __init__(self, consumer_key, consumer_secret, phone_number):
        """Initialize the service."""
        self._consumer_key = consumer_key
        self._consumer_secret = consumer_secret
        self._phone_number = phone_number

    def send_message(self, message="", **kwargs):
        """Send a message to a user."""
        title = kwargs.get(ATTR_TITLE)

        # Retrieve authorization first
        token_response = _authenticate(
            self._consumer_key, self._consumer_secret)
        if token_response is False:
            _LOGGER.exception("Error obtaining authorization from Telstra API")
            return

        provision_response = _provision(token_response)
        if provision_response is False:
            _LOGGER.exception("Error provisioning number from Telstra API")
            return

        # Send the SMS
        if title:
            text = '{} {}'.format(title, message)
        else:
            text = message

        message_data = {
            'to': self._phone_number,
            'body': text,
            'replyRequest':"False",
        }
        message_resource = 'https://tapi.telstra.com/v2/messages/sms'
        message_headers = {
            HTTP_HEADER_CONTENT_TYPE: CONTENT_TYPE_JSON,
            'Authorization': 'Bearer ' + token_response['access_token'],
        }
        message_response = requests.post(
            message_resource, headers=message_headers, json=message_data,
            timeout=10)

        if message_response.status_code != 202:
            _LOGGER.exception("Failed to send SMS. Status code: %d",
                              message_response.status_code)


def _authenticate(consumer_key, consumer_secret):
    """Authenticate with the Telstra API."""
    token_data = {
        'client_id': consumer_key,
        'client_secret': consumer_secret,
        'grant_type': 'client_credentials',
        'scope': 'NSMS'
    }
    token_resource = 'https://sapi.telstra.com/v1/oauth/token'
    token_response = requests.get(
        token_resource, params=token_data, timeout=10).json()

    if 'error' in token_response:
        return False

    return token_response
	
	
	
def _provision(token_response):
    """Provision a number with the Telstra API."""
    provision_data = {
        'Authorization': 'Bearer ' + token_response['access_token'],
        'cache-control':'no-cache',
        'Content-Type':'application/json',
        'activedays':"30",
        'notifyurl':"",
        'callbackdata':""
    }

    provision_resource = 'https://tapi.telstra.com/v2/messages/provisioning/subscriptions'
    provision_response = requests.get(
        provision_resource, params=provision_data, timeout=10).json()

    if 'error' in provision_response:
        return False

    return provision_response

Thanks @psy

That looks great. All would be working I think except the API says I have exceeded my quota so the SMS didnt send :frowning: I havent tried 1000 times so looks like their API still needs some work tracking usage but I cant complain since it was free!

Cheers!

It’s a 1000 sms limit in total, not per month.

Yeah I wouldnt have tried sending 1000 times. Might have to create a new account…

can you push this into the next update of HA please

Just out of interest, if you have time, could you look at your telstra.dev account and see how many messages it says you have sent and see if that looks about right?

That graph is hard to read.

8th - 13th November - starts at 0 and ramps up to 5.
Then the axis changes from dates to 6,7,8 with values of 2,4 & 8.

If the date axis and values are correct then it appears somewhat accurate (increase by 1 message a day) - however I’m pretty sure I don’t send sms messages on a weekend. (currently sending 1 every weekday in an automation).

Hi Leeb98,

does this updated code work for you?
If so, Ill work out how to push the changes.

Cheers
Psy.

Hi psy

i’m currently running HASSIO and it’s a pain to mod
I was hoping the update would be pushed through to HASSIO

currently looking going back to a normal install , but having issue with installing MQTT !!
once i have the new install up and running i will apply the update , that could be weeks

Lee

Hi,

I am running Home Assistant in a docker not HASSIO, I too am getting authorization error:

Error obtaining authorization from Telstra API NoneType: None

What do I have to do to fix this issue? what code to update and in which files?

Thanks

telstra.py file.
Contents posted above.

Have submitted an update.

Hi. Thanks.

I am looking for an sms gateway solution in Australia not getting a good vibe with Telstra.

Have you tried any other service like clicksend or globalsms?

For what it’s worth, I found that this code didnt work as is and had to change some of the definitions and where they import from.

"""
Telstra API platform for notify component.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.telstra/
"""
import logging

from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
import requests
import voluptuous as vol

from homeassistant.components.notify import (
    BaseNotificationService, ATTR_TITLE, PLATFORM_SCHEMA)
from homeassistant.const import CONTENT_TYPE_JSON
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

HTTP_HEADER_CONTENT_TYPE = 'content-type'

CONF_CONSUMER_KEY = 'consumer_key'
CONF_CONSUMER_SECRET = 'consumer_secret'
CONF_PHONE_NUMBER = 'phone_number'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_CONSUMER_KEY): cv.string,
    vol.Required(CONF_CONSUMER_SECRET): cv.string,
    vol.Required(CONF_PHONE_NUMBER): cv.string,
})


def get_service(hass, config, discovery_info=None):
    """Get the Telstra SMS API notification service."""
    consumer_key = config.get(CONF_CONSUMER_KEY)
    consumer_secret = config.get(CONF_CONSUMER_SECRET)
    phone_number = config.get(CONF_PHONE_NUMBER)

    if _authenticate(consumer_key, consumer_secret) is False:
        _LOGGER.exception("Error obtaining authorization from Telstra API")
        return None

    return TelstraNotificationService(
        consumer_key, consumer_secret, phone_number)


class TelstraNotificationService(BaseNotificationService):
    """Implementation of a notification service for the Telstra SMS API."""

    def __init__(self, consumer_key, consumer_secret, phone_number):
        """Initialize the service."""
        self._consumer_key = consumer_key
        self._consumer_secret = consumer_secret
        self._phone_number = phone_number

    def send_message(self, message="", **kwargs):
        """Send a message to a user."""
        title = kwargs.get(ATTR_TITLE)

        # Retrieve authorization first
        token_response = _authenticate(
            self._consumer_key, self._consumer_secret)
        if token_response is False:
            _LOGGER.exception("Error obtaining authorization from Telstra API")
            return

        provision_response = _provision(token_response)
        if provision_response is False:
            _LOGGER.exception("Error provisioning number from Telstra API")
            return

        # Send the SMS
        if title:
            text = '{} {}'.format(title, message)
        else:
            text = message

        message_data = {
            'to': self._phone_number,
            'body': text,
            'replyRequest':"False",
        }
        message_resource = 'https://tapi.telstra.com/v2/messages/sms'
        message_headers = {
            HTTP_HEADER_CONTENT_TYPE: CONTENT_TYPE_JSON,
            'Authorization': 'Bearer ' + token_response['access_token'],
        }
        message_response = requests.post(
            message_resource, headers=message_headers, json=message_data,
            timeout=10)

        if message_response.status_code != 202:
            _LOGGER.exception("Failed to send SMS. Status code: %d",
                              message_response.status_code)


def _authenticate(consumer_key, consumer_secret):
    """Authenticate with the Telstra API."""
    token_data = {
        'client_id': consumer_key,
        'client_secret': consumer_secret,
        'grant_type': 'client_credentials',
        'scope': 'NSMS'
    }
    token_resource = 'https://sapi.telstra.com/v1/oauth/token'
    token_response = requests.get(
        token_resource, params=token_data, timeout=10).json()

    if 'error' in token_response:
        return False

    return token_response
	
	
	
def _provision(token_response):
    """Provision a number with the Telstra API."""
    provision_data = {
        'Authorization': 'Bearer ' + token_response['access_token'],
        'cache-control':'no-cache',
        'Content-Type':'application/json',
        'activedays':"30",
        'notifyurl':"",
        'callbackdata':""
    }

    provision_resource = 'https://tapi.telstra.com/v2/messages/provisioning/subscriptions'
    provision_response = requests.get(
        provision_resource, params=provision_data, timeout=10).json()

    if 'error' in provision_response:
        return False

    return provision_response

I found this service completely unreliable and ended up switching to Pushbullet. 100% reliable and I can attach links & pictures.

Just wondering if anyone has reported this over on github? I had a quick look but didn’t see any issues or PR’s for this problem.

I would agree with most this thread, the shipped component doesn’t work.

I’ve been using it since it was released and it’s still working for me on Hassio, but I have just received an email from Telstra advising the API is to be decommissioned. Perhaps the sign up and authentication for the initial version changed some time ago.

Telstra will switch off the SMS API v1 across all geographic regions on 31st May, 2018. The service will be unavailable and all API Keys to SMS API v1 will automatically expire on this date.

I’m not sure if I’ll bother switching over unless the component is updated as I’m already using pushover for a bunch of other things but one thing that would be nice in the new API is having the dedicated number.

Managed to make the Telstra Messaging V2 works via shell script.

my bash scripting is a bit over the place but this one works…

create a shell script .sh

#!/bin/bash
MESSAGE=“Test Message”
DEST_MOBILE1=$1
CONSUMER_KEY=""
CONSUMER_SECRET=""
SMS_MESSAGE=$(cat)
ACCESS_TOKEN=curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \ -d "grant_type=client_credentials&client_id=$CONSUMER_KEY&client_secret=$CONSUMER_SECRET&scope=NSMS" \ 'https://tapi.telstra.com/v2/oauth/token' | cut -d'"' -f4

MOBILE_NUMBER=curl -X POST \ https://tapi.telstra.com/v2/messages/provisioning/subscriptions \ -H "authorization: Bearer ${ACCESS_TOKEN}" \ -H 'cache-control: no-cache' \ -H 'content-type: application/json' \ -d '{ "activeDays":30, "notifyURL":"http://example.com/callback", "callbackData": { "anything":"some data" } }'
FROM_NUMBER=echo $MOBILE_NUMBER | cut -d'"' -f4

POST="{ “to”: “${DEST_MOBILE1}”,
“body”: “${SMS_MESSAGE}”,
“from”: “${FROM_NUMBER}”,
“notifyURL”: “”,
“replyRequest”: false
}"

curl -X POST
https://tapi.telstra.com/v2/messages/sms
-H “authorization: Bearer ${ACCESS_TOKEN}”
-H ‘cache-control: no-cache’
-H ‘content-type: application/json’
-d “${POST}”