diff --git a/simyo/README.md b/simyo/README.md index fe3e12c..528caad 100644 --- a/simyo/README.md +++ b/simyo/README.md @@ -2,18 +2,18 @@ (reverse engineered from the com.simyo mobile app) - The password used by the API is your Simyo password encripted using -TripleDES with this key: `25d1d4cb0a08403e2acbcbe0f25a2` +TripleDES with this key: `TFq2VBDo3BizNAcPEw1vB7i5` - All requests to the API have a signature which is sent in the parameter "`apiSig=xxxx`", this signature is calculated like this: 1. convert to lowercase the complete request URL except the apiSig parameter - 2. concatenate the string "`f25a2s1m10`" + the lowercased URL + 2. concatenate the string "`BHqCzYg8BAmZ`" + the lowercased URL 3. the signature is obtained by computing the HMAC-SHA256 hash of the -string obtained in the previous step, using the key "`f25a2s1m10`". +string obtained in the previous step, using the key "`BHqCzYg8BAmZ`". - All api requests need the parameter "`publicKey=xxxx`", the value of -this public key is: `a654fb77dc654a17f65f979ba8794c34` +this public key is: `1SCOPDqVeSPjTKy` The rest is a piece of cake, make the request and parse the received json response. diff --git a/simyo/simyo.py b/simyo/simyo.py index fa0cccb..aa1688b 100755 --- a/simyo/simyo.py +++ b/simyo/simyo.py @@ -29,12 +29,14 @@ USERNAME = "" PASSWORD = "" +BASE_URL = "https://api.simyo.es/simyo-api" + def getApiSig(url): - dig = hmac.new(b'f25a2s1m10', msg='f25a2s1m10' + url.lower(), digestmod=hashlib.sha256).digest() + dig = hmac.new(b'BHqCzYg8BAmZ', msg='BHqCzYg8BAmZ' + url.lower(), digestmod=hashlib.sha256).digest() return url + "&apiSig=" + dig.encode('hex') def simyopass(): - k = pyDes.triple_des("25d1d4cb0a08403e2acbcbe0", pyDes.ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5) + k = pyDes.triple_des("TFq2VBDo3BizNAcPEw1vB7i5", pyDes.ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5) d = urllib.quote(base64.b64encode(k.encrypt(PASSWORD)) + '\n') #print "Encrypted: %r" % d #print "Decrypted: %r" % k.decrypt(base64.b64decode(urllib.unquote(d))) @@ -61,7 +63,7 @@ def epoch2date(timestamp, format='%d/%m/%Y'): return datetime.datetime.fromtimestamp(int(timestamp)).strftime(format) def api_request(url, data="", check=True): - kPublicKey="a654fb77dc654a17f65f979ba8794c34" + kPublicKey="1SCOPDqVeSPjTKy" if url[-1:] == "?": url=url + "publicKey=" + kPublicKey @@ -102,7 +104,7 @@ def api_request(url, data="", check=True): return result def api_logout(): - URL="https://www.simyo.es/api/logout?sessionId=" + str(sessionId) + URL=BASE_URL+"/logout?sessionId=" + str(sessionId) result = api_request(URL,"",False) if VERBOSE: print result + "\n" @@ -110,7 +112,7 @@ def api_login(): global sessionId, customerId SIMYOPASS = simyopass() - URL="https://www.simyo.es/api/login?" + URL=BASE_URL+"/login?" data = "user=" + USERNAME + "&password=" + SIMYOPASS + "&apiSig=null" result = api_request(URL,data) if VERBOSE: print result + "\n" @@ -121,7 +123,7 @@ def api_login(): def subscriptions(): global registerDate, mainProductId, billCycleType, msisdn, subscriberId, payType - URL="https://www.simyo.es/api/subscriptions/" + str(customerId) + "?sessionId=" + str(sessionId) + URL=BASE_URL+"/subscriptions/" + str(customerId) + "?sessionId=" + str(sessionId) result = api_request(URL) if VERBOSE: print result + "\n" @@ -144,7 +146,7 @@ def subscriptions(): sys.exit(0) def consumptionByCycle(billCycleCount=1): - URL="https://www.simyo.es/api/consumptionByCycle/" + str(customerId) + "?sessionId=" + str(sessionId) + "&msisdn=" + str(msisdn) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&billCycle=" + str(billCycle) + "&billCycleCount=" + str(billCycleCount) + "&payType=" + str(payType) + URL=BASE_URL+"/consumptionByCycle/" + str(customerId) + "?sessionId=" + str(sessionId) + "&msisdn=" + str(msisdn) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&billCycle=" + str(billCycle) + "&billCycleCount=" + str(billCycleCount) + "&payType=" + str(payType) result = api_request(URL) if VERBOSE: print result + "\n" @@ -229,7 +231,7 @@ def consumptionByCycle(billCycleCount=1): print "\nConsumo total: " + str(chargeTotal) + " EUR\n" def consumptionDetailByCycle(billCycleCount=1): - URL="https://www.simyo.es/api/consumptionDetailByCycle/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&billCycleCount=" + str(billCycleCount) + "&payType=" + str(payType) + URL=BASE_URL+"/consumptionDetailByCycle/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&billCycleCount=" + str(billCycleCount) + "&payType=" + str(payType) result = api_request(URL) if VERBOSE: print result + "\n" @@ -286,7 +288,7 @@ def consumptionDetailByCycle(billCycleCount=1): def frequentNumbers(): month=billCycle # Parameter month is mandatory - URL="https://www.simyo.es/api/frequentNumbers/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&month=" + str(month) + URL=BASE_URL+"/frequentNumbers/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&month=" + str(month) result = api_request(URL) if VERBOSE: print result + "\n" @@ -299,7 +301,7 @@ def frequentNumbers(): def messages(): start=1 count=500 - URL="https://www.simyo.es/api/messages/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&start=" + str(start) + "&count=" + str(count) + URL=BASE_URL+"/messages/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&start=" + str(start) + "&count=" + str(count) result = api_request(URL) if VERBOSE: print result + "\n" @@ -321,7 +323,7 @@ def messages(): def voiceCalls(): start=1 count=500 - URL="https://www.simyo.es/api/voiceCalls/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&start=" + str(start) + "&count=" + str(count) + URL=BASE_URL+"/voiceCalls/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "&billCycle=" + str(billCycle) + "®isterDate=" + str(registerDate) + "&start=" + str(start) + "&count=" + str(count) result = api_request(URL) if VERBOSE: print result + "\n" @@ -350,7 +352,7 @@ def rechargeHistory(): startDate=registerDate endDate = time() endDate = int(endDate) * 1000 - URL="https://www.simyo.es/api/rechargeHistory/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&startDate=" + str(startDate) + "&endDate=" + str(endDate) + URL=BASE_URL+"/rechargeHistory/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + "&startDate=" + str(startDate) + "&endDate=" + str(endDate) result = api_request(URL) if VERBOSE: print result + "\n" @@ -365,7 +367,7 @@ def rechargeHistory(): print '{0}\t\t{1}'.format(date, fee) def mgmHistory(): - URL="https://www.simyo.es/api/mgmHistory/" + str(customerId) + "?sessionId=" + str(sessionId) + URL=BASE_URL+"/mgmHistory/" + str(customerId) + "?sessionId=" + str(sessionId) result = api_request(URL) if VERBOSE: print result + "\n" @@ -379,7 +381,7 @@ def mgmHistory(): print "TOTAL DISPONIBLE: " + str(totalAvailablePoints) def invoiceList(): - URL="https://www.simyo.es/api/invoiceList/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) + URL=BASE_URL+"/invoiceList/" + str(customerId) + "?msisdn=" + str(msisdn) + "&sessionId=" + str(sessionId) + "&billCycleType=" + str(billCycleType) + "®isterDate=" + str(registerDate) result = api_request(URL) if VERBOSE: print result + "\n" @@ -408,7 +410,7 @@ def downloadInvoice(): print "Can't find invoice with id = " + str(reqInvoiceId) sys.exit(1) - URL="https://www.simyo.es/api/downloadInvoice?sessionId=" + str (sessionId) + "&invoiceNO=" + str(invoiceNO) + "&invoiceId=" + str(invoiceId) + URL=BASE_URL+"/downloadInvoice?sessionId=" + str (sessionId) + "&invoiceNO=" + str(invoiceNO) + "&invoiceId=" + str(invoiceId) result = api_request(URL) if VERBOSE: print result + "\n" @@ -511,4 +513,4 @@ def parse_cmd(): sys.exit(0) #TODO: -#https://www.simyo.es/api/contact +#https://api.simyo.es/api/contact