Python

This walkthrough will show you how to build an app that listens for tweets from a certain Twitter account, and then routes that tweets to a phone number through Live Link 365's SMS API.

This is not a production-ready application. Please take your time to enhance it for production so that it meets your specific business requirements.

Steps

Code

keyboard_arrow_down
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
; _Step_1
[API]
;Insert your api url here
base_url=https://livelink.sapdigitalinterconnect.com/api
;Insert your generated app key here
app_key=appKey
;Insert your generated app secret here
app_secret=appSecret

[TWITTER]
consumer_key=ckey
consumer_secret=csecret
access_token=atoken
access_token_secret=asecret
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import tweepy
import json
import twitter
import configparser

from SendSMS import MessageHandler

config = configparser.ConfigParser()
config.read('../resources/config.ini')

consumer_key = config['TWITTER']['consumer_key']
consumer_secret = config['TWITTER']['consumer_secret']
access_token = config['TWITTER']['access_token']
access_token_secret = config['TWITTER']['access_token_secret']
base_url = config['API']['base_url']
app_key = config['API']['app_key']
app_secret = config['API']['app_secret']

messageHandler = MessageHandler(base_url, app_key, app_secret)

class StdOutListener(StreamListener):

    def __init__(self, api=None):
        self.api = api
        self.handleNumberMapping=load_properties('properties.txt')

    # _Step_6
    def on_status(self, status):
        #print status.author.id_str
        if status.author.id_str in follow_users_ids:
            "true"
            numbers=[] #Phone numbers have to be in E.164 format.
            message = status.text
            message=message.replace("&", "and")
            print message
            #Adds numbers for the handle names mentioned in the properties file
            for key, value in self.handleNumberMapping.iteritems():
                if key in message:
                    numbers.append(value)

            #message = "+".join(message.split(' '))
            for number in numbers:
                messageHandler.sendSMS(message, number)

    def on_error(self, status):
        print status

# _Step_3 Loads handle names and numbers mapping
def load_properties(filepath, sep='=', comment_char='#'):
    """
    Read the file passed as parameter as a properties file.
    """
    props = {}
    with open(filepath, "rt") as f:
        for line in f:
            l = line.strip()
            if l and not l.startswith(comment_char):
                key_value = l.split(sep)
                key = key_value[0].strip()
                value = sep.join(key_value[1:]).strip().strip('"') 
                props[key] = value 
    return props


if __name__ == '__main__':

    # This handles Twitter authentification and the connection to Twitter Streaming API
    l = StdOutListener()
    auth = OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    stream = Stream(auth, l)

    # _Step_2
    #Need to get user ids of users and copy here to capture their live feeds
    #Here these are our user ids , you can get them from https://tweeterid.com/
    follow_users_ids = [] #Replace with Twitter ids

    stream.filter(follow=follow_users_ids)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# _Step_4
import base64
import json
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode

class MessageHandler():
    def __init__(self, base_url, app_key, app_secret):
        self.base_url = base_url
        self.app_key = app_key
        self.app_secret = app_secret

    def getAccessToken(self, key, secret):
        """
        This Function is used to retrieve oAuth2 access_tokens.
        This conforms to oAuth2 Spec client_credentials grant_type.
        This Function is not doing any validation regarding expiration of tokens.
        """
        token_url = self.base_url + '/oauth/token'
        credentials = "%s:%s" % (key, secret)
        encode_credential = base64.b64encode(credentials.encode('utf-8')).decode('utf-8').replace("\n", "")
        header_params = {
            "Authorization": ("Basic %s" % encode_credential),
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json"
        }
        param = {
            'grant_type': 'client_credentials'
        }

        token_data = urlencode(param)
        token_request = Request(url=token_url, headers=header_params, data=token_data.encode('ascii'))

        try:
            token_response = urlopen(token_request).read()
        except HTTPError as error:
            print ("Error " + error.reason)
        else:
            return json.loads(token_response.decode('UTF-8'))['access_token']

    # _Step_5
    def sendSMS(self, sms, number):
        token_url = self.base_url + '/v2/sms'
        header_params = {
            "Content-Type": "application/json",
            "Authorization": ("Bearer %s" % self.getAccessToken(self.app_key, self.app_secret))
        } 

        param = { 
            "message": sms,
            "origin": "", 
            "destination": number #Phone numbers have to be in E.164 format.
        }
        token_data = json.dumps(param).encode('ascii')
        token_request = Request(url=token_url, headers=header_params, data=token_data)
        # Exception handle example
        try:
            token_response = urlopen(token_request)
            print (token_response)
        except HTTPError as e:
            return 'HTTP Request error with status %i %s' % (e.code, e.reason)
        except URLError as e:
            return 'URL Request error with status %i %s' % (e.code, e.reason)
        else:
            return 'SMS Sent Successfully' #with OrderId:' #% json.loads(sms_response.read().decode('UTF-8'))['orderId']