Skip to content

Instantly share code, notes, and snippets.

@theriverman
Forked from msmorul/lync-sample1.py
Last active March 31, 2018 10:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theriverman/adfcb5cf1ae006d68e7004acfb5634a6 to your computer and use it in GitHub Desktop.
Save theriverman/adfcb5cf1ae006d68e7004acfb5634a6 to your computer and use it in GitHub Desktop.
Example python3 script for authenticating to Lync and creating an application endpoint that lists all of a persons contacts. Python example for what's described here https://ucwa.lync.com/documentation/keytasks-createapplication
import requests
import json
from urllib.parse import urlparse
sip_domain = "SIP_DOMAIN.COM"
username = "USERNAME@SIP_DOMAIN.COM"
password = "YOUR_LYNC_PASSWORD"
def extract_auth_url(_string):
start = _string.find('MsRtcOAuth')
q1 = _string.find('"', start)
q2 = _string.find('"', q1+1)
if q1 == -1 or q2 == -1:
raise Exception("cannot find auth string")
return _string[q1+1:q2]
#
# Lookup discovery URL to determine user/auth url, hardcoded to external. change to lyncdiscoverinternal for internal users
#
discover_url = "https://lyncdiscover.{}/".format(sip_domain)
print("--1. GET: {0}".format(discover_url))
r1 = requests.get(discover_url)
print("--Response Code: {}".format(r1.status_code))
j = r1.json()
user_url = j['_links']['user']['href']
#
# ping the user url, expect a 401/address of oath server
#
print("--2. GET: {0}".format(user_url))
r2 = requests.get(user_url)
print("--Response Code: {0}".format(r2.status_code))
auth_url = extract_auth_url(r2.headers['www-authenticate'])
#
# send auth request, expect 200/authentication token
#
r3_data = {'grant_type': 'password', 'username': username, 'password': password}
print("--3. POST: {0}".format(auth_url))
r3 = requests.post(auth_url, data=r3_data)
print("--Response Code: {0}".format(r3.status_code))
access_token = r3.json()
#
# resend user request w/ oath headers, look for applications url
#
auth_headers = {'Authorization': "{} {}".format(access_token['token_type'], access_token['access_token'])}
print("--4. GET: {0}".format(user_url))
r4 = requests.get(user_url, headers=auth_headers)
print("--Response Code: {}".format(r4.status_code))
#
# create an application endpoint, takes a json query w/ app identifier and appropriate content type
#
application_data = {'culture': 'en-us', 'endpointId': '1235637', 'userAgent': 'pythonApp/1.0 (CritterOS)'}
applications_url = r4.json()['_links']['applications']['href']
print("--5. GET: {0}".format(applications_url))
r5_headers = {'content-type': 'application/json'}
r5_headers.update(auth_headers)
r5 = requests.post(applications_url, headers=r5_headers, data=json.dumps(application_data))
print("--Response Code: {0}".format(r5.status_code))
apps = r5.json()
# print json.dumps(r5.json(),indent=4)
up = urlparse(applications_url)
application_base = "{0}://{1}".format(up.scheme, up.netloc)
#
# invoke a plain GET to the myContacts url we found above.
#
r6_url = application_base + apps['_embedded']['people']['_links']['myContacts']['href']
print("--6. GET: {0}".format(r6_url))
r6 = requests.get(r6_url, headers=auth_headers)
print("--Response Code: {0}".format(r6.status_code))
# print json.dumps(r6.json(),indent=4)
for contact in r6.json()['_embedded']['contact']:
print("Name " + contact['name'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment