title: How to set credentials to use Gmail API from GCE VM Command Line?
body: <p>I'm trying to enable my Linux VM on GCE to access my Gmail account in order to send emails.</p>
  <p>I've found this article, <a href="https://developers.google.com/gmail/api/quickstart/python" rel="nofollow noreferrer">https://developers.google.com/gmail/api/quickstart/python</a>, which reads some Gmail account information (it's useful since I just want to test my connection).</p>
  <pre><code>from __future__ import print_function
  import pickle
  import os.path
  from googleapiclient.discovery import build
  from google_auth_oauthlib.flow import InstalledAppFlow
  from google.auth.transport.requests import Request
  
  # If modifying these scopes, delete the file token.pickle.
  SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
  
  def main():
      &quot;&quot;&quot;Shows basic usage of the Gmail API.
      Lists the user's Gmail labels.
      &quot;&quot;&quot;
      creds = None
      # The file token.pickle stores the user's access and refresh tokens, and is
      # created automatically when the authorization flow completes for the first
      # time.
      if os.path.exists('token.pickle'):
          with open('token.pickle', 'rb') as token:
              creds = pickle.load(token)
      # If there are no (valid) credentials available, let the user log in.
      if not creds or not creds.valid:
          if creds and creds.expired and creds.refresh_token:
              creds.refresh(Request())
          else:
              flow = InstalledAppFlow.from_client_secrets_file(
                  'credentials.json', SCOPES)
              creds = flow.run_local_server(port=0)
          # Save the credentials for the next run
          with open('token.pickle', 'wb') as token:
              pickle.dump(creds, token)
  
      service = build('gmail', 'v1', credentials=creds)
  
      # Call the Gmail API
      results = service.users().labels().list(userId='me').execute()
      labels = results.get('labels', [])
  
      if not labels:
          print('No labels found.')
      else:
          print('Labels:')
          for label in labels:
              print(label['name'])
  
  if __name__ == '__main__':
      main()
  </code></pre>
  <p>However, I'm not sure which Credentials I need to set, as when I set and use:</p>
  <ol>
  <li><p><strong>Service Account</strong>: I receive the following message <code>ValueError: Client secrets must be for a web or installed app.</code></p>
  </li>
  <li><p><strong>OAuth client ID for Web Application type</strong>: the code runs well, however I receive the following message when trying to first authorize the application's access:</p>
  </li>
  </ol>
  <blockquote>
  <p>Erro 400: redirect_uri_mismatch
  The redirect URI in the request, http://localhost:60443/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: <a href="https://console.developers.google.com/apis/credentials/oauthclient/$%7Byour_client_id%7D?project=$%7Byour_project_number%7D" rel="nofollow noreferrer">https://console.developers.google.com/apis/credentials/oauthclient/${your_client_id}?project=${your_project_number}</a></p>
  </blockquote>
  <ol start="3">
  <li><strong>OAuth client ID for Desktop type</strong>: the code runs well, however I receive the following message when trying to first authorize the application's access:</li>
  </ol>
  <blockquote>
  <p>localhost connection has been refused</p>
  </blockquote>
  <p>Does anyone know how is the correct setup and if I'm missing anything?</p>
  <p>Thanks</p>
  <hr />
  <p><strong>[Nov17th]</strong></p>
  <p>After adding the gmail scope to my VM's scopes I ran the python script and I got the following error:</p>
  <pre><code>    Traceback (most recent call last):
    File &quot;quickstart2.py&quot;, line 29, in &lt;module&gt;
      main()
    File &quot;quickstart2.py&quot;, line 18, in main
      results = service.users().labels().list(userId=&quot;107628233971924038182&quot;).execute()
    File &quot;/home/lucasnunesfe9/.local/lib/python3.7/site-packages/googleapiclient/_helpers.py&quot;, line 134, in positional_wrapper
      return wrapped(*args, **kwargs)
    File &quot;/home/lucasnunesfe9/.local/lib/python3.7/site-packages/googleapiclient/http.py&quot;, line 915, in execute
      raise HttpError(resp, content, uri=self.uri)
  googleapiclient.errors.HttpError: &lt;HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/107628233971924038182/labels?alt=json returned &quot;Precondition check failed.&quot;&gt;
  </code></pre>
  <p>I checked the error HTTP link and it shows:</p>
  <pre><code>{
    &quot;error&quot;: {
      &quot;code&quot;: 401,
      &quot;message&quot;: &quot;Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.&quot;,
      &quot;errors&quot;: [
        {
          &quot;message&quot;: &quot;Login Required.&quot;,
          &quot;domain&quot;: &quot;global&quot;,
          &quot;reason&quot;: &quot;required&quot;,
          &quot;location&quot;: &quot;Authorization&quot;,
          &quot;locationType&quot;: &quot;header&quot;
        }
      ],
      &quot;status&quot;: &quot;UNAUTHENTICATED&quot;
    }
  }
  </code></pre>
  <p>Is any manual procedure needed in a &quot;first authorization step&quot;?</p>
  <p><em>PS: reinforcing that I have already enabled my Service Account to &quot;G Suite Domain-wide Delegation&quot;. This action generated an OAuth 2.0 Client ID, which is being used in the python script (variable userId).</em></p>