Consult chat reports using admin sdk google workspace - python

I'm new to integrations with the API SDK GOOGLE, and I need to consume the Workspace activity reports regarding the use of google Chat, I configured the following code, but I believe it is wrong, I didn't find a documentation that helps me to validate the form correct way to make calls to the reports api
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from apiclient.discovery import build
import googleapiclient.discovery
#escopos necessarios
scopes = [
'https://www.googleapis.com/auth/admin.reports.usage.readonly',
'https://www.googleapis.com/auth/drive.metadata.readonly',
'https://www.googleapis.com/auth/admin.reports.usage.readonly',
'https://www.googleapis.com/auth/admin.reports.audit.readonly',
'https://www.googleapis.com/auth/analytics',
'https://www.googleapis.com/auth/analytics.readonly',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/apps.alerts',
'https://www.googleapis.com/auth/apps.order.readonly',
'https://www.googleapis.com/auth/apps.order',
'https://www.googleapis.com/auth/admin.directory.user.readonly',
'https://www.googleapis.com/auth/admin.directory.domain',
'https://www.googleapis.com/auth/admin.directory.domain.readonly',
'https://www.googleapis.com/auth/calendar.readonly' ,
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/admin.directory.user',
'https://www.googleapis.com/auth/cloud-platform'
]
#dominio que sera pesquisado
TARGET='dominio.test.com'
#credenciais de acesso
credentials = ServiceAccountCredentials.from_json_keyfile_name('./chave.json', scopes)
delegated_credentials = credentials.create_delegated('admin#email.com')
http_auth = credentials.authorize(Http())
service = googleapiclient.discovery.build('admin', 'directory_v1',
credentials=delegated_credentials)
response = service.activities().list(users='all',applicationName='chat')
print(response)
I've already used this code for other queries and it's working for accessing the directory and listing users but when I tried to adapt it to query chat activities it doesn't work I have the following error
response = service.activities().list(customerId='all',applicationName='chat')
AttributeError: 'Resource' object has no attribute 'activities'

Related

Error 400: invalid_request The out-of-band (OOB) flow has been blocked in order to keep users secure

using this quickstart.ipynb
I'm getting this error
You can’t sign in because "myapp" sent an invalid request. You can try again later, or contact the developer about this issue. Learn more about this error
If you are a developer of myapp, see error details.
Error 400: invalid_request
Error 400: invalid_request
The out-of-band (OOB) flow has been blocked in order to keep users secure. Follow the Out-of-Band (OOB) flow Migration Guide linked in the developer docs below to migrate your app to an alternative method.
Request details: redirect_uri=urn:ietf:wg:oauth:2.0:oob
This is the code which is running
from apiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
CLIENT_CONFIG = {
'installed': {
'client_id':'----------------------------------------------------------',
'client_secret': '------------------------------------------------------',
'auth_uri':'https://accounts.google.com/o/oauth2/auth',
'token_uri':'https://oauth2.googleapis.com/token'
}
}
SCOPES = ['https://www.googleapis.com/auth/androidmanagement']
flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, SCOPES)
credentials = flow.run_console()
androidmanagement = build('androidmanagement', 'v1', credentials=credentials)
print('\nAuthentication succeeded.')
Since Google has deprecated OOB
You have to use the new method run_local_server() if you are using the google_auth_oauthlib package
Replace the line
credentials = flow.run_console()
to
credentials = flow.run_local_server()
The out-of-band (OOB) flow has been blocked.
Use the below code Replace your 'your client id' and 'your client secret'
from apiclient.discovery import build
from google_auth_oauthlib.flow import Flow
# This is a public OAuth config that you can use to run this guide.
# However, use different credentials when building your own solution.
CLIENT_CONFIG = {
'web': {
'client_id':'your client id',
'auth_uri':'https://accounts.google.com/o/oauth2/auth',
'token_uri':'https://oauth2.googleapis.com/token',
'auth_provider_x509_cert_url':'https://www.googleapis.com/oauth2/v1/certs',
'client_secret':'your client secret'
}
}
SCOPES = ['https://www.googleapis.com/auth/androidmanagement']
CALLBACK_URL = 'https://google.github.io/android-management-api- samples/oauth_callback.html'
# Run the OAuth flow.
flow = Flow.from_client_config(CLIENT_CONFIG, SCOPES)
flow.redirect_uri = CALLBACK_URL
auth_url, _ = flow.authorization_url()
print('Please visit this URL to authorize this application: {}'.format(auth_url))
code = input('Enter the authorization code: ')
flow.fetch_token(code=code)
# Create the API client.
androidmanagement = build('androidmanagement', 'v1', credentials=flow.credentials)
print('\nAuthentication succeeded.')
full link for Android Management API Quick Start https://colab.research.google.com/github/google/android-management-api-samples/blob/master/notebooks/quickstart.ipynb

'analytics' is not defined error with Upload data script with GA Management API

I'm trying to upload some custom data into GA with Python. It's the first I'm doing this so I'm not sure about nothing.
I've build the following script based on the example from the doc. When running it I have the following error :
File "import.py", line 50, in <module>
daily_upload = analytics.management().uploads().uploadData(
NameError: name 'analytics' is not defined
Here is my code :
import argparse
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
import httplib2
import urllib2
from oauth2client import client
from oauth2client import file
from oauth2client import tools
def get_service(api_name, api_version, scope, key_file_location,
service_account_email):
"""Get a service that communicates to a Google API.
Args:
api_name: The name of the api to connect to.
api_version: The api version to connect to.
scope: A list auth scopes to authorize for the application.
key_file_location: The path to a valid service account p12 key file.
service_account_email: The service account email address.
Returns:
A service that is connected to the specified API.
"""
credentials = ServiceAccountCredentials.from_p12_keyfile(
service_account_email, key_file_location, scopes=scope)
http = credentials.authorize(httplib2.Http())
# Build the service object.
service = build(api_name, api_version, http=http)
return service
from apiclient.http import MediaFileUpload
try:
media = MediaFileUpload('mycsv.csv',
mimetype='application/octet-stream',
resumable=False)
daily_upload = analytics.management().uploads().uploadData(
accountId='XXXXXX',
webPropertyId='XXXXXXX',
customDataSourceId='XXXXXXXXXX',
media_body=media).execute()
except TypeError, error:
# Handle errors in constructing a query.
print 'There was an error in constructing your query : %s' % error
def main():
# Define the auth scopes to request.
scope = ['https://www.googleapis.com/auth/analytics']
# Use the developer console and replace the values with your
# service account email and relative location of your key file.
service_account_email = 'XXXXXX#XXXXXX'
key_file_location = 'XXXXXXXXXX.p12'
# Authenticate and construct service.
service = get_service('analytics', 'v3', scope, key_file_location,
service_account_email)
profile = get_first_profile_id(service)
print_results(get_results(service, profile))
if __name__ == '__main__':
main()
If my code isn't clear or show some other obvious mistake different from the one I'm questioning please be comprehensive I'm learning !
Edit: I've checked in my API Manager the Analytics API is well enable
Ok. It is a simple block alignement issue. I needed to align this part :
from apiclient.http import MediaFileUpload
try:
media = MediaFileUpload('mycsv.csv',
mimetype='application/octet-stream',
resumable=False)
daily_upload = analytics.management().uploads().uploadData(
accountId='XXXXXX',
webPropertyId='XXXXXXX',
customDataSourceId='XXXXXXXXXX',
media_body=media).execute()
except TypeError, error:
# Handle errors in constructing a query.
print 'There was an error in constructing your query : %s' % error
with the first part !

People API returns no connections when authenticating via Service Account [duplicate]

I'm trying to programmatically access the list of contacts on my own personal Google Account using the Python Client Library
This is a script that will run on a server without user input, so I have it set up to use credentials from a Service Account I set up. My Google API console setup looks like this.
I'm using the following basic script, pulled from the examples provided in the API docs -
import json
from httplib2 import Http
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build
# Only need read-only access
scopes = ['https://www.googleapis.com/auth/contacts.readonly']
# JSON file downloaded from Google API Console when creating the service account
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'keep-in-touch-5d3ebc885d4c.json', scopes)
# Build the API Service
service = build('people', 'v1', credentials=credentials)
# Query for the results
results = service.people().connections().list(resourceName='people/me').execute()
# The result set is a dictionary and should contain the key 'connections'
connections = results.get('connections', [])
print connections #=> [] - empty!
When I hit the API it returns a result set without any 'connections' key. Specifically it returns -
>>> results
{u'nextSyncToken': u'CNP66PXjKhIBMRj-EioECAAQAQ'}
Is there something pertaining to my setup or code that's incorrect? Is there a way to see the response HTTP status code or get any further detail about what it's trying to do?
Thanks!
Side note: When I try it using the "Try it!" feature in the API docs, it correctly returns my contacts. Although I doubt that uses the client library and instead relies on user authorization via OAuth
The personFields mask is required. Specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people.connections/list/.
Additionally, use fields mask to specify which fields are included in a partial response.
Instead of:
results = service.people().connections().list(resourceName='people/me').execute()
... try:
results = service.people().connections().list(resourceName='people/me',personFields='names,emailAddresses',fields='connections,totalItems,nextSyncToken').execute()
Here is a working demo. I just tested it right now. Python 3.5.2
google-api-python-client==1.6.4
httplib2==0.10.3
oauth2client==4.1.2
You can save it to demo.py and then just run it. I left the create_contact function in case you might want to use it and have one more example on the API usage.
CLIENT_ID and CLIENT_SECRET are environment variables so I don't accidentally share that in code.
"""Google API stuff."""
import httplib2
import json
import os
from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run_flow
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
SCOPE = 'https://www.googleapis.com/auth/contacts'
USER_AGENT = 'JugDemoStackOverflow/v0.1'
def make_flow():
"""Make flow."""
flow = OAuth2WebServerFlow(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scope=SCOPE,
user_agent=USER_AGENT,
)
return flow
def get_people():
"""Return a people_service."""
flow = make_flow()
storage = Storage('info.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run_flow(flow, storage)
http = httplib2.Http()
http = credentials.authorize(http)
people_service = build(serviceName='people', version='v1', http=http)
return people_service
def create_contact(people, user):
"""Create a Google Contact."""
request = people.createContact(
body={
'names': [{'givenName': user.name}],
'phoneNumbers': [
{'canonicalForm': user.phone, 'value': user.phone}],
}
)
return request.execute()
def demo():
"""Demonstrate getting contacts from Google People."""
people_service = get_people()
people = people_service.people()
connections = people.connections().list(
resourceName='people/me',
personFields='names,emailAddresses,phoneNumbers',
pageSize=2000,
)
result = connections.execute()
s = json.dumps(result)
# with open('contacts.json', 'w') as f:
# f.write(s)
return s
if __name__ == '__main__':
print(demo())
With service account, in DwD - G Suite Domain-wide Delegation, is necessary impersonate or delegate user in this way
delegate = credentials.create_delegated('user#xxxx.xxx')
For fellow googlers: I have the same problem using the JS API.
I succeded on my personal gmail address, but not on my work one (g-suite) neither on my secondary gmail address.
Can't see the pattern. It's possible that the work one has contact listing deactivated.

Accessing Google spreadsheet with Python for server-to-server use

I am trying to update a Google spreadsheet from a server that some target users can see on a daily basis. Here is what I tried:
Created a project in "console.developers.google.com" then selected "drive API" -> "credentials" -> "add credentials" -> "service accounts" -> "create Json file"
Now with this JSON file (project name-e4sdfsdsdf0c.json) I tried to access Spreadsheets.
import gdata.spreadsheet.service
import gdata.service
import urlparse
import httplib2
from oauth2client.file import Storage
from oauth2client.client import flow_from_clientsecrets
from oauth2client import tools
spreadsheet_key = '13jQtgSUXKBExMvZjECf6sdfsfgLfmRFVmZw6t7hYyX3g0'
storage = Storage("creds.dat")
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow_from_clientsecrets("project name-e4sdfsdsdf0c.json", scope=["https://spreadsheets.google.com/feeds"]), storage)
if credentials.access_token_expired:
credentials.refresh(httplib2.Http())
spr_client = gdata.spreadsheet.service.SpreadsheetsService(
additional_headers={'Authorization' : 'Bearer %s' % credentials.access_token})
worksheets = spr_client.GetSpreadsheetsFeed(spreadsheet_key)
print worksheets.title
But I am getting this error:
Invalid file format. See https://developers.google.com/api-client-library/python/guide/aaa_client_secrets Expected a JSON object with a single property for a "web" or "installed" application"
You created a service account but it looks like you're trying to access it using a client flow.
Have a look at the service account documentation here:
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
The first step would be to go back to the developer console and generate a p12 key. Then the basic flow for Python looks like this:
from oauth2client.client import SignedJwtAssertionCredentials
scope = 'https://www.googleapis.com/auth/drive.readonly https://spreadsheets.google.com/feeds'
client_email = '<your service account email address>'
with open("MyProject.p12") as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, scope)
http_auth = credentials.authorize(Http())
Google Sheets API v4 appeared pretty straightforward here. After generating json file you may access spreadsheet with this code.
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from apiclient import discovery
scopes = ['https://www.googleapis.com/auth/spreadsheets']
credentials = ServiceAccountCredentials.from_json_keyfile_name(<path_to_your_client_secret.json>, scopes)
http_auth = credentials.authorize(Http())
discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?version=v4')
service = discovery.build('sheets', 'v4', http=http_auth, discoveryServiceUrl=discoveryUrl)
result = service.spreadsheets().values().update(...).execute()

How to create Google API OAuth Credentials object from alternate source

I am working with this simple Google API example:
import httplib2
from apiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run
# Path to the client_secret.json file downloaded from the Developer Console
CLIENT_SECRET_FILE = 'client_secret.json'
# Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
# Location of the credentials storage file
STORAGE = Storage('gmail.storage')
# Start the OAuth flow to retrieve credentials
flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
http = httplib2.Http()
# Try to retrieve credentials from storage or run the flow to generate them
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
credentials = run(flow, STORAGE, http=http)
# Authorize the httplib2.Http object with our credentials
http = credentials.authorize(http)
# Build the Gmail service from discovery
gmail_service = build('gmail', 'v1', http=http)
And seeing as I have already gone through the OAuth flow previously (in a different non-Python app) and have my refresh tokens, etc. I would like to skip the first portion of this example and either manually create the expected storage file gmail.storage or create the credentials object some other way.
The problem is I can't find any documentation about the expected format of this storage file, or what should be in it, or how to instantiate the credentials object in any other way. Sorry that I cannot show any work here, but I'm at a loss. Any point in the right direction would be greatly appreciated.
Very simple, apparently this works:
from oauth2client.client import GoogleCredentials
from oauth2client import GOOGLE_TOKEN_URI
access_token = None
token_expiry = None
token_uri = GOOGLE_TOKEN_URI
user_agent = 'Python client library'
revoke_uri = None
gCreds = GoogleCredentials(
access_token,
client_id,
client_secret,
refresh_token,
token_expiry,
token_uri,
user_agent,
revoke_uri=revoke_uri
)
As explained here: in Google Cloud Platform's github
you can also use a string to setup this. Specially a json string
import json
import os
from google.oauth2 import service_account
from google.cloud import translate
info = json.loads(os.environ['GOOGLE_APPLICATION_CREDENTIALS_JSON_STRING'])
creds = service_account.Credentials.from_service_account_info(info)
# Instantiates a client
translate_client = translate.Client(credentials=creds)
Please note that I used Google Translate's API for this example but it's the same logic.
There is a bit more explanation in this git issue too: https://github.com/GoogleCloudPlatform/google-cloud-python/issues/4477
The oauth2client.file.Storage lib might be of interest to you:
from oauth2client.file import Storage
storage = Storage('gmail.storage')
credentials = storage.get()
storage.put(credentials)

Categories