it-swarm-es.com

¿Cómo puedo evitar el permiso insuficiente de HttpError 403? (gmail api, python)

Sigo recibiendo el siguiente error cuando ejecuto mi código:

An error occurred: <HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Insufficient Permission">

Este es mi código:

import httplib2
import os
from httplib2 import Http

from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

#SCOPES = 'https://www.googleapis.com/'
SCOPES = 'https://www.googleapis.com/auth/gmail.compose'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Quickstart'

def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'gmail-quickstart.json')

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatability with Python 2.6
            credentials = tools.run(flow, store)
        print 'Storing credentials to ' + credential_path
    return credentials

def CreateMessage(sender, to, subject, message_text):
  """Create a message for an email.

  Args:
    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.

  Returns:
    An object containing a base64 encoded email object.
  """
  message = MIMEText(message_text)
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject
  return {'raw': base64.b64encode(message.as_string())}

testMessage = CreateMessage('ENTER SENDERS EMAIL ADDRESS', 'ENTER RECEIVERRS EMAIL ADDRESS', 'ENTER SUBJECT', 'ENTER EMAIL BODY')

def SendMessage(service, user_id, message):
  """Send an email message.

  Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    message: Message to be sent.

  Returns:
    Sent Message.
  """
  try:
    message = (service.users().messages().send(userId=user_id, body=message)
               .execute())
    print 'Message Id: %s' % message['id']
    return message
  except errors.HttpError, error:
    print 'An error occurred: %s' % error


testSend = SendMessage(service, 'me', testMessage)

Sigo leyendo que necesito editar un archivo de credenciales, pero parece que no puedo encontrarlo. Tengo Windows 7 instalado. ¿Alguien sabe lo que necesito hacer para superar este error? Soy un noob total en esto, así que discúlpeme si me parece un poco nooby sobre esto. ¡Gracias!

17
semiflex

A pesar de que la respuesta aceptada es 100% correcta. Creo que vale la pena señalar que ese es el caso.

Cuando autoriza un cliente de servicio gmail, puede especificar varios ámbitos diferentes: Todos, componer, etiquetas, etc.

Estos están todos listados aquí: https://developers.google.com/gmail/api/auth/scopes

El alcance mencionado en la respuesta proporciona acceso completo a gmail.

12
Olshansk

Resuelto cambiando la línea de SCOPES a:

SCOPES = 'https://mail.google.com/'

El envío de correo electrónico funciona perfectamente

9
semiflex

La API de Gmail tiene estos ámbitos: gmail api scopes

Para enviar correos electrónicos, se necesita https://www.googleapis.com/auth/gmail.send o acceso completo - https://mail.google.com/ .

Los ámbitos tomados de aquí .

9
apadana

Si ejecuta el " gmail-python-quickstart " oficial antes, elimine el archivo "gmail-quickstart.json" en su sistema. Vuelva a ejecutar su programa para que pueda establecer el privilegio que desee.

8
ccy

Además de las respuestas de:

  1. ccy
  2. apadana
  3. ragnampiza

y como avance de la respuesta de ccy ...


Solución 1 ...

... un arreglo de hack

Si está utilizando el código gmail-python-quickstart original, asegúrese de actualizar también lo siguiente:

  1. CLIENT_SECRET_FILE = '/path/to/your/secret_client.json'
  2. Forzar get_credentials() para usar la ruta lógica de credenciales fallidas ...

if True: flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) flow.user_agent = APPLICATION_NAME if flags: credentials = tools.run_flow(flow, store, flags) else: # Needed only for compatibility with Python 2.6 credentials = tools.run(flow, store) print('Storing credentials to ' + credential_path)

forzar True para que la operación lógica funcione definitivamente las operaciones client.flow:

if True: flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) flow.user_agent = APPLICATION_NAME if flags: credentials = tools.run_flow(flow, store, flags) else: # Needed only for compatibility with Python 2.6 credentials = tools.run(flow, store) print('Storing credentials to ' + credential_path)

Esta es una solución difícil, pero te pondrá en marcha en poco tiempo.

El problema...

  • El problema con este enfoque es que fuerza el código flow, que abre el navegador de la ventana de autenticación y requiere que el usuario final acepte el protocolo de seguridad antes de enviar el correo electrónico.
  • Esto obviamente rompe el concepto de generación y envío automatizados de correo electrónico.

Solución 2 ...

... una solución estable, más automatizada

Encontré que haciendo los siguientes trabajos:

  1. Copie el archivo secret-client-####.html.json descargado en el directorio definido en el primer bloque de código del método get_credentials(). Básicamente, cópielo en su directorio user/.credentials
  2. Borre el gmail-python-quickstart.json actual
  3. Cambie el nombre de su archivo descargado a gmail-python-quickstart.json

Ejecute su código, y luego debería funcionar bien.

Beneficios ...

  • La página de autenticación no aparece.
  • El correo electrónico se envía automáticamente.
1
Andrew

Si usó el ejemplo oficial de google, debería haber una carpeta en el directorio ~/.credentials/ que sea antigua, elimine todo lo que esté dentro de ese directorio y vuelva a ejecutar su código. entonces tienes que agregar nuevos permisos y entonces todo está bien!

1
Iman Mirzadeh