-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlambda_function.py
164 lines (122 loc) · 6.75 KB
/
lambda_function.py
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# -*- coding: utf-8 -*-
from __future__ import print_function
"""Comcast Internet Usage Alexa Skill
Author: Kevin Fowlks
Date: 12/05/2016
TODO: Add code to cache JSON response from Comcast
The comcast python code was stolen from https://github.com/lachesis/comcast
pip install requests -t <path to this project>
Note: This code uses ask-alexa-pykit release python_lambda_0.5_release
git checkout python_lambda_0.5_release
You'll need to set the below Environment variables in your AWS Lambda console
COMCAST_USERNAME
COMCAST_PASSWORD
See below for more detailed usage instructions
https://github.com/kfowlks/aws_alexa_comcast_data_usage_lambda/blob/master/README.md
"""
from ask import alexa
from datetime import datetime
import logging
import os
import re
import requests
import datetime
import json
import calendar
import time
class MyUsage(object):
monthLongName = ""
unitOfMeasure = ""
homeUsage=0
allowableUsage=1000
# The class "constructor" - It's actually an initializer
def __init__(self, monthLongName, unitOfMeasure, homeUsage, allowableUsage):
self.monthLongName = monthLongName
self.unitOfMeasure = unitOfMeasure
self.homeUsage = homeUsage
self.allowableUsage = allowableUsage
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
logging.getLogger('requests').setLevel(logging.ERROR)
def lambda_handler(request_obj, context=None):
myUsageMonths = {}
jsonStr = getUsage()
if jsonStr == None:
card = alexa.create_card(title="GetInternetUsage activated", subtitle=None,
content="asked alexa to get internet usage")
return alexa.create_response("Sorry unable to retrieve comcast account information", end_session=True, card_obj=card)
jsonObj = json.loads(jsonStr)
usageMonths = jsonObj['usageMonths']
for usageMonth in usageMonths:
monthName = calendar.month_name[int(usageMonth['startDate'][:2])]
myUsageMonths[monthName] = MyUsage( monthName, usageMonth['unitOfMeasure'], usageMonth['homeUsage'], usageMonth['allowableUsage'])
metadata = {'usageMonths' : myUsageMonths }
return alexa.route_request(request_obj, metadata)
@alexa.default_handler()
def default_handler(request):
return alexa.create_response(message="Just ask").with_card('What is my current internet usage')
@alexa.request_handler("LaunchRequest")
def launch_request_handler(request):
return alexa.create_response(message="Hello Welcome to Internet Usage!")
@alexa.request_handler("SessionEndedRequest")
def session_ended_request_handler(request):
return alexa.create_response(message="Goodbye!")
@alexa.intent_handler('GetInternetUsage')
def get_internet_usage_intent_handler(request):
myUsageMonths = request.metadata['usageMonths']
requestMonth = request.slots["Date"]
if requestMonth == None:
currentDT = datetime.datetime.now() # If users request does not have a date lets default to the current date
requestUserMonthByName = currentDT.strftime("%B") # Get Month by name e.g.
else:
requestUserMonthByName = calendar.month_name[int(requestMonth[5] + requestMonth[6])]
if requestUserMonthByName not in myUsageMonths:
card = alexa.create_card(title="GetInternetUsage activated", subtitle=None,
content="asked alexa to get internet usage using {}".format(requestMonth))
return alexa.create_response("Sorry no usage data exist for the requested month {}".format(requestMonth), end_session=False, card_obj=card)
else:
card = alexa.create_card(title="GetInternetUsage activated", subtitle=None,
content="You have used %s%s out of %s%s for the month of %s!" % (myUsageMonths[requestUserMonthByName].homeUsage,
myUsageMonths[requestUserMonthByName].unitOfMeasure,
myUsageMonths[requestUserMonthByName].allowableUsage,
myUsageMonths[requestUserMonthByName].unitOfMeasure,
myUsageMonths[requestUserMonthByName].monthLongName ))
return alexa.create_response("You have used %s%s out of %s%s for the month of %s!" % (myUsageMonths[requestUserMonthByName].homeUsage,
myUsageMonths[requestUserMonthByName].unitOfMeasure,
myUsageMonths[requestUserMonthByName].allowableUsage,
myUsageMonths[requestUserMonthByName].unitOfMeasure,
myUsageMonths[requestUserMonthByName].monthLongName ), end_session=False, card_obj=card)
def getUsage():
session = requests.Session()
username = os.environ['COMCAST_USERNAME']
password = os.environ['COMCAST_PASSWORD']
logger.debug("Finding req_id for login...")
res = session.get('https://login.comcast.net/login?r=comcast.net&s=oauth&continue=https%3A%2F%2Flogin.comcast.net%2Foauth%2Fauthorize%3Fclient_id%3Dmy-account-web%26redirect_uri%3Dhttps%253A%252F%252Fcustomer.xfinity.com%252Foauth%252Fcallback%26response_type%3Dcode%26state%3D%2523%252Fdevices%26response%3D1&client_id=my-account-web')
if res.status_code != 200:
return None
m = re.search(r'<input type="hidden" name="reqId" value="(.*?)">', res.text)
req_id = m.group(1)
logger.debug("Found req_id = %r", req_id)
data = {
'user': username,
'passwd': password,
'reqId': req_id,
'deviceAuthn': 'false',
's': 'oauth',
'forceAuthn': '0',
'r': 'comcast.net',
'ipAddrAuthn': 'false',
'continue': 'https://login.comcast.net/oauth/authorize?client_id=my-account-web&redirect_uri=https%3A%2F%2Fcustomer.xfinity.com%2Foauth%2Fcallback&response_type=code&state=%23%2Fdevices&response=1',
'passive': 'false',
'client_id': 'my-account-web',
'lang': 'en',
}
logger.debug("Posting to login...")
res = session.post('https://login.comcast.net/login', data=data)
if res.status_code != 200:
return None
logger.debug("Fetching internet usage AJAX...")
res = session.get('https://customer.xfinity.com/apis/services/internet/usage')
if res.status_code != 200:
return None
return res.text