title: Google App Script Api 404 error while running script via api
body: <p>i am currently trying to run an app script function when user connect there google account. when one row is finished typing i want the row information back to my server.so i came to a conclusion that app script is suitable for that.</p>
  
  <p>what i have do step by step is</p>
  
  <p>1) create a google console project</p>
  
  <p>2) enable app script</p>
  
  <p>3) enable google sheet api</p>
  
  <p>4) download credentials.json</p>
  
  <p>5) create a script</p>
  
  <pre><code>   &lt;?php
  require __DIR__ . '/vendor/autoload.php';
  
  if (php_sapi_name() != 'cli') {
      throw new Exception('This application must be run on the command line.');
  }
  
  /**
   * Returns an authorized API client.
   * @return Google_Client the authorized client object
   */
  function getClient()
  {
  
      $client = new Google_Client();
      $client-&gt;setApplicationName('Google Apps Script API PHP Quickstart');
      $client-&gt;setScopes(['https://www.googleapis.com/auth/script.projects','https://www.googleapis.com/auth/script.scriptapp','https://www.googleapis.com/auth/spreadsheets','https://www.googleapis.com/auth/spreadsheets.readonly','https://www.googleapis.com/auth/script.external_request','https://www.googleapis.com/auth/script.deployments']);
      $client-&gt;setAuthConfig('credentials.json');
      $client-&gt;setAccessType('offline');
      $client-&gt;setPrompt('select_account consent');
  
      // Load previously authorized token from a file, if it exists.
      // The file token.json stores the user's access and refresh tokens, and is
      // created automatically when the authorization flow completes for the first
      // time.
      $tokenPath = 'token.json';
      if (file_exists($tokenPath)) {
          $accessToken = json_decode(file_get_contents($tokenPath), true);
          $client-&gt;setAccessToken($accessToken);
      }
  
      // If there is no previous token or it's expired.
      if ($client-&gt;isAccessTokenExpired()) {
          // Refresh the token if possible, else fetch a new one.
          if ($client-&gt;getRefreshToken()) {
              $client-&gt;fetchAccessTokenWithRefreshToken($client-&gt;getRefreshToken());
          } else {
              // Request authorization from the user.
              $authUrl = $client-&gt;createAuthUrl();
              printf("Open the following link in your browser:\n%s\n", $authUrl);
              print 'Enter verification code: ';
              $authCode = trim(fgets(STDIN));
  
              // Exchange authorization code for an access token.
              $accessToken = $client-&gt;fetchAccessTokenWithAuthCode($authCode);
              $client-&gt;setAccessToken($accessToken);
  
              // Check to see if there was an error.
              if (array_key_exists('error', $accessToken)) {
                  throw new Exception(join(', ', $accessToken));
              }
          }
          // Save the token to a file.
          if (!file_exists(dirname($tokenPath))) {
              mkdir(dirname($tokenPath), 0700, true);
          }
          file_put_contents($tokenPath, json_encode($client-&gt;getAccessToken()));
      }
      return $client;
  }
  
  
  /**
   * Shows basic usage of the Apps Script API.
   *
   * Call the Apps Script API to create a new script project, upload files to the
   * project, and log the script's URL to the user.
   */
  $client = getClient();
  $service = new Google_Service_Script($client);
  
  // Create a management request object.
  $request = new Google_Service_Script_CreateProjectRequest();
  $request-&gt;setTitle('console script 44400');
  $response = $service-&gt;projects-&gt;create($request);
  
  $scriptId = $response-&gt;getScriptId();
  
  $code = &lt;&lt;&lt;EOT
  function customFunction(e) {
    var range = e.range;
    range.setNote('Last modified: ' + new Date());
    var ui = SpreadsheetApp.getUi();
    ui.alert('text');
  }
  
  ScriptApp.newTrigger('customFunction')
      .forSpreadsheet('xxxxxxxxxxxx')
      .onEdit()
      .create();
  EOT;
  $file1 = new Google_Service_Script_ScriptFile();
  $file1-&gt;setName('hello 111100');
  $file1-&gt;setType('SERVER_JS');
  $file1-&gt;setSource($code);
  
  $manifest = &lt;&lt;&lt;EOT
  {
    "timeZone": "America/New_York",
    "exceptionLogging": "CLOUD",
      "oauthScopes": [
      "https://www.googleapis.com/auth/spreadsheets.readonly",
      "https://www.googleapis.com/auth/userinfo.email",
      "https://www.googleapis.com/auth/script.scriptapp",
      "https://www.googleapis.com/auth/spreadsheets",
      "https://www.googleapis.com/auth/script.external_request",
      "https://www.googleapis.com/auth/drive",
      "https://www.googleapis.com/auth/drive.scripts"
    ]
  }
  EOT;
  $file2 = new Google_Service_Script_ScriptFile();
  $file2-&gt;setName('appsscript');
  $file2-&gt;setType('JSON');
  $file2-&gt;setSource($manifest);
  
  $request = new Google_Service_Script_Content();
  $request-&gt;setScriptId($scriptId);
  $request-&gt;setFiles([$file1, $file2]);
  
  
  
  $response = $service-&gt;projects-&gt;updateContent($scriptId, $request);
  echo "https://script.google.com/d/" . $response-&gt;getScriptId() . "/edit\n";
  
    $request = new \Google_Service_Script_ExecutionRequest();
  $request-&gt;setFunction('customFunction');
  $response = $service-&gt;scripts-&gt;run($scriptId, $request);
  </code></pre>
  
  <p>I got the response as</p>
  
  <pre><code>  Fatal error: Uncaught Google_Service_Exception: {
    "error": {
      "code": 404,
      "message": "Requested entity was not found.",
      "errors": [
        {
          "message": "Requested entity was not found.",
          "domain": "global",
          "reason": "notFound"
        }
      ],
      "status": "NOT_FOUND"
    }
  }
  </code></pre>
  
  <p>the error is due to </p>
  
  <pre><code>$request = new \Google_Service_Script_ExecutionRequest();
  $request-&gt;setFunction('customFunction');
  $response = $service-&gt;scripts-&gt;run($scriptId, $request);
  </code></pre>
  
  <p>i see similar errors on internet .but the solutions don't work for me. i pass all the necessary scopes</p>
  
  <pre><code>'https://www.googleapis.com/auth/script.projects','https://www.googleapis.com/auth/script.scriptapp','https://www.googleapis.com/auth/spreadsheets','https://www.googleapis.com/auth/spreadsheets.readonly','https://www.googleapis.com/auth/script.external_request','https://www.googleapis.com/auth/script.deployments'
  </code></pre>
  
  <p>between as a side note when i try to run the script manually in the script editor and try editing in the google sheet the above script work and the alert box shown. but this is not practical in case of user who connected there google account.we cannot guarantee that user run script manually to make things work.we need the api to run the script and make the trigger working.Please help</p>
  
  <p><strong>Edited</strong>
  version code added</p>
  
  <pre><code>$request1=new Google_Service_Script_Version();
  $request1-&gt;setScriptId($scriptId);
  $request1-&gt;setVersionNumber(1);
  $service-&gt;projects_versions-&gt;create($scriptId,$request1);
  </code></pre>
  
  <p>added above script run API code but still get same error</p>