ti-enxame.com

Como faço para obter o HttpError 403 Insufficient Permission? (gmail api, python)

Eu continuo recebendo o seguinte erro quando eu executo o meu 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 é o meu 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)

Eu continuo lendo que eu preciso editar um arquivo de credenciais, mas não consigo encontrá-lo. Eu tenho o windows 7 instalado. Alguém sabe o que preciso fazer para superar esse erro? Eu sou um noob total para isso, por favor, me desculpe se eu pareço um pouco nooby sobre isso. Obrigado! 

17
semiflex

Mesmo que a resposta aceita seja 100% correta. Eu acho que vale a pena ressaltar porque esse é o caso.

Ao autorizar um cliente de serviço do Gmail, você pode especificar vários escopos diferentes: Todos, compor, rótulos, etc ...

Todos eles estão listados aqui: https://developers.google.com/gmail/api/auth/scopes

O escopo mencionado na resposta fornece acesso completo ao Gmail.

12
Olshansk

Resolveu alterando a linha SCOPES para:

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

Envio por email funciona perfeitamente 

9
semiflex

A API do Gmail tem esses escopos: gmail api scopes

Para enviar e-mails,https://www.googleapis.com/auth/gmail.sendé necessário ou acesso total https://mail.google.com/ .

Os escopos retirados de here .

9
apadana

Se você executar o " gmail-python-quickstart " antes, exclua o arquivo "gmail-quickstart.json" em seu sistema. Volte a executar o programa novamente para poder definir o privilégio como quiser. 

8
ccy

Além das respostas de:

  1. ccy
  2. apadana
  3. ragnampiza

e como um avanço da resposta da ccy ...


Solução 1 ...

... uma correção

Se você estiver usando o código gmail-python-quickstart original, atualize também o seguinte:

  1. CLIENT_SECRET_FILE = '/path/to/your/secret_client.json'
  2. Forçar get_credentials() para usar o caminho lógico de credenciais com falha ...

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)

para forçar True para que a operação lógica funcione definitivamente com as operações 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 é uma correção hacky, mas você vai se levantar e ir em pouco tempo. 

O problema...

  • O problema com essa abordagem é que ela força o código flow, que abre o navegador da janela de autenticação e exige que o usuário final aceite o protocolo de segurança antes de enviar o email.
  • Isso obviamente quebra o conceito de geração e envio automatizado de e-mail.

Solução 2 ...

... uma solução estável e mais automatizada

Eu achei que fazendo os seguintes trabalhos:

  1. Copie o arquivo secret-client-####.html.json baixado para o diretório definido no primeiro bloco de código do método get_credentials(). Basicamente, copie-o para o diretório user/.credentials
  2. Excluir o gmail-python-quickstart.json atual
  3. Renomeie o arquivo baixado para gmail-python-quickstart.json

Execute o seu código e, em seguida, ele deve funcionar bem.

Benefícios ...

  • A página de autenticação não aparece
  • O email é enviado automaticamente
1
Andrew

Se você usou o exemplo oficial do google, deve haver uma pasta no diretório ~/.credentials/ que seja antiga, remova tudo dentro desse diretório e execute novamente seu código. então você tem que adicionar novas permissões e então tudo está OK!

1
Iman Mirzadeh