I'm trying to send a Google Chat message from Python in much the same way you can send a Gmail message:
https://developers.google.com/gmail/api/quickstart/python
I see documentation on how to create a Chat Bot (https://developers.google.com/chat/how-tos/bots-develop), but these typically require that you create your own https server that google can access.
I've tried using the scope 'https://www.googleapis.com/auth/chat', and it successfully goes through the authorization flow, and in particular the 'chat' scope claims to grant permissions to send messages, etc:
(see https://vizycam.com/wp-content/uploads/2022/01/Image-634-1.jpg)
I can build a request using build() and the granted credentials:
from googleapiclient.discovery import build
...
service = build('chat', 'v1', credentials=gcloud.creds())
and I can see that it has methods dms(), rooms(), spaces(), etc. that I could use to create a message, but I'm unable to get any requests to work.
Is it possible to send a chat message from a user account programmatically, in much the same way the Gmail example above does?
Related
I'm making a desktop app in Python that sends mail from Gmail. The problem is that after receiving consent (OAuth 2) through the browser, the user for whom the software receives the consent, continues to be logged in to the browser in Gmail. Is there a way to go through the authorization process without staying logged in to Gmail in your browser?
What you are referring to is Oauth2. Oauth2 gives users the ability to grant applications like yours consent to access their private data. Private data is data that is owned by someone. My gmail data is mine your application can not use it unless I grant you access.
Is there a way to go through the authorization process without staying logged in to Gmail in your browser?
Lets clear up some confusion in this statement you mention authorization which is correct a user is authorizing your application to access their data. Yet you also mention logged in which has nothing to do with authorization. Logging in a user is authentication and is not part of Oauth2. It is part of something else called openid connect.
As for how to request authorization of a user without using the browser. Once the user has consented to your application accessing my data once then your application should have what its called a refresh token, this refresh token can be used at a latter time for your application to request a new access token. Granting you access to may data without using the browser to access my data again. So you could store this refresh token in the backend some where and use that to continue to access the users data without needing to use the browser again.
storing user credentials in an installed application
It is hard to know exactly what you are doing since you did not include any code in your question, and your question is a little unclear.
In the following example please note how the users credentials are stored in gmail.dat using this code in an installed application will cause it to load the refresh token the next time the user runs the app meaning that the consent screen should not be shown, as the credentials are already stored for that user.
def initialize_gmail():
"""Initializes the gmail service object.
Returns:
analytics an authorized gmail service object.
"""
# Parse command-line arguments.
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args([])
# Set up a Flow object to be used if we need to authenticate.
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_PATH, scope=SCOPES,
message=tools.message_if_missing(CLIENT_SECRETS_PATH))
# Prepare credentials, and authorize HTTP object with them.
# If the credentials don't exist or are invalid run through the native client
# flow. The Storage object will ensure that if successful the good
# credentials will get written back to a file.
storage = file.Storage('gmail.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())
# Build the service object.
service = build('gmail ', 'v1', http=http)
return service
Utilizing Twilio, upon receiving any SMS I'm seeking to trigger a Python function that reads the contents of the message, then conditionally performs an action.
I'm referencing from Twilio docs right now (.py):
# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client
# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
auth_token = 'your_auth_token'
client = Client(account_sid, auth_token)
message = client.messages('MMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').fetch()
print(message.to)
Does anyone know how to automatically set up a trigger OnReceive?
The example you show fetches a known message (a message that has already been received and you know its ID).
In order to have a script that is triggered by incoming message you need to setup a webhook and you need to have an endpoint (server) where you can pick up a trigger sent to you by twilio (eg at www.yourdomain.com/sms).
You might not be able to do it just from within a raspbery pi connected to the internet. You need to setup a trigger somewhere on a server, store the incoming messages somehow and then one solution would be to keep polling the server from raspberry pi, fetching new messages and clearing the list.
I am trying to build an flask app on AWS lambda, which needs to access https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly to get the Mac Address of chrome devices by domain name and chrome device id.
Basically the working flow is blew:
A Chrome Extension deployed by G-Suit sends an request with domain name and device id to AWS(as we are using AWS), then the AWS sends an request with domain name and device id to Google Cloud to get Mac Address.
I started with using an access the directory API as a service account like service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES, subject="username#domainName.com"), and it works. However, I realised it was wrong implementation as the domainName would be changed and subject will be different for each domain as the Chrome Extension can be deployed via different domains.
Then I started to use the sample code from Google(https://developers.google.com/api-client-library/python/auth/web-app), and I was able to access the domain and get the Mac Address of each device.
However, the problem is it requires to choose the email when you call the google api for the first time. But as I mentioned above, this app is going to run on AWS, so clearly users cannot choose the email.
So is that possible that we just use the domainName instead of choosing email to do the authentication and access the different directories? If so, is there any examples or documentations I need to read?
I suspect I need to modify this part from the sample, but I am still getting confused how it works.
#app.route('/adminlogin')
def authorize():
# Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
approval_prompt="force",
# Enable incremental authorization. Recommended as a best practice.
#include_granted_scopes='true'
)
# Store the state so the callback can verify the auth server response.
flask.session['state'] = state
return flask.redirect(authorization_url)
Any hint will be helpful.
I am trying to obtain a token from Azure AD from Python client application. I want users to seamlessly authenticate with just a username and password (client_id / secret will be embedded in the app). I registered my app and given it all permissions and hit the "grant permissions" button in the new portal according to this post:
The user or administrator has not consented to use the application - Send an interactive authorization request for this user and resource
I am sending an http post to:
https://login.microsoftonline.com/{tenant_id}/oauth2/token
with the following data:
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
body = "resource={0}&grant_type=password&username={1}&password={2}&client_id={3}&client_secret={4}&scope=openid".format(app_id_uri,user,password,client_id,client_secret)
I cannot seem to get past this error no matter what I try:
b'{"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID \'078c1175-e384-4ac7-9116-efbebda7ccc2\'. Send an interactive authorization request for this user and resource.
Again, my goal:
User enters user / pass and nothing else. App sends user / pass / client_id / client_secret, obtains token.
According to your comment:
The message I'm receiving says to do an interactive request but that is exactly what I'm trying to avoid because this is a python app with no web browser and I'm trying to avoid complexity.
I think you want to build a daemon app or an app only application integrating with Azure AD. You can refer to https://graph.microsoft.io/en-us/docs/authorization/app_only for the general introduction.
Furthermore, you can leverage the ADAL for Python to implement this functionality with a ease. Also, you can refer to client_credentials_sample.py for a quick start.
You should try logging in as an admin to be able to give consent to use the application on your tenant at all.
I'm using the following library for Salesforce OAuth Request: https://github.com/heroku/salesforce-oauth-request
I've created a Connected App, but have no idea what to set the redirect uri. Can I just set it to "https://www.google.com/"?
I just want to connect to Salesforce's Chatter API via python code, and don't care where the user gets directed as long as I get a refresh token from the oauth2 protocol