electronicsguy / ESP8266

ESP8266 Projects
242 stars 183 forks source link

Cannot make a simple example work. Please help. #58

Closed JacquesBB closed 6 years ago

JacquesBB commented 6 years ago

Hi,

I have made the simple example I could make

#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"

// Fill ssid and password with your network credentials
const char* ssid = "xxxxx";
const char* password = "xxxxx";

const char* host = "script.google.com";

const char *GScriptId = "AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg";
const int httpsPort = 443;

// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout
const char* fingerprint = "B4:80:F7:C2:CF:C8:50:E2:5B:9B:E9:F0:E2:02:DD:C8:BD:C2:89:9A";

// Write to Google Spreadsheet
String url = String("/macros/s/") + GScriptId + "/exec?pressure=1021.79";

HTTPSRedirect* client = nullptr;

void setup() {
  Serial.begin(115200);
  Serial.flush();

  Serial.println();
  Serial.print("Connecting to wifi: ");
  Serial.println(ssid);
  // flush() is needed to print the above (connecting...) message reliably, 
  // in case the wireless connection doesn't go through
  Serial.flush();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use HTTPSRedirect class to create a new TLS connection
  client = new HTTPSRedirect(httpsPort);
  client->setPrintResponseBody(true);
  client->setContentTypeHeader("application/json");

  Serial.print("Connecting to ");
  Serial.println(host);

  // Try to connect for a maximum of 5 times
  bool flag = false;
  for (int i=0; i<5; i++){
    int retval = client->connect(host, httpsPort);
    if (retval == 1) {
       flag = true;
       break;
    }
    else
      Serial.println("Connection failed. Retrying...");
  }

  if (!flag){
    Serial.print("Could not connect to server: ");
    Serial.println(host);
    Serial.println("Exiting...");
    return;
  }

  if (client->verify(fingerprint, host)) {
    Serial.println("Certificate match.");
  } else {
    Serial.println("Certificate mis-match");
  }

  Serial.print("url : ");
  Serial.println(url);
  Serial.println("\nGET: Write into cell 'A1'");
  Serial.println("=========================");

  // fetch spreadsheet data
  client->GET(url, host);

  Serial.println("=========END===========");
}

void loop(){}

But it does not work ( although the https request on the browser is fine). Here is the output with the debug on .

.......
WiFi connected
IP address: 
192.168.1.169
Connecting to script.google.com
Certificate match.
url : /macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure=1021.79

GET: Write into cell 'A1'
=========================
GET /macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure=1021.79 HTTP/1.1
Host: script.google.com
User-Agent: ESP8266

Status code: 302
Reason phrase: Moved Temporarily
_redirHost: accounts.google.com
_redirUrl: /ServiceLogin?service=wise&passive=1209600&continue=https://script.google.com/macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure%3D1021.79&followup=https://script.google.com/macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure%3D1021.79
GET /ServiceLogin?service=wise&passive=1209600&continue=https://script.google.com/macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure%3D1021.79&followup=https://script.google.com/macros/s/AKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg/exec?pressure%3D102 HTTP/1.1
Host: accounts.google.com
User-Agent: ESP8266

Status code: 200
Reason phrase: OK
Content-Type: text/html; charset=UTF-8
X-Frame-Options: DENY
Link: <https://www.google.com/intl/en/drive/>; rel="canonical"
x-auto-login: realm=com.google&args=service%3Dwise%26continue%3Dhttps%253A%252F%252Fscript.google.com%252Fmacros%252Fs%252FAKfycbykOQiFIrtU73UJF1A3ZGvjpXPsqS6k7j6O74OeESVObV7jIJg%252Fexec%253Fpressure%253D1021.79
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Sat, 31 Mar 2018 16:22:06 GMT
Transfer-Encoding: chunked
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: script-src 'report-sample' 'nonce-Uy4VJd/ANGabRt569cMJ7eBKSNU' 'unsafe-inline' 'strict-dynamic' https: http: 'unsafe-eval';object-src 'none';base-uri 'self';report-uri /cspreport
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Server: GSE
Set-Cookie: GAPS=1:OaMch1F_KGCyPaMsvQUMWvG1TdVaCQ:JCn2fEx-dHDK54QL;Path=/;Expires=Mon, 30-Mar-2020 16:22:06 GMT;Secure;HttpOnly;Priority=HIGH
Alt-Svc: hq=":443"; ma=2592000; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="42,41,39,35"

Chunk Size: 28678

<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8">
... 

then tons of HTML

Please help .

Traste commented 6 years ago

I just tried out the example script some hour ago for the first time, and it took some work to get running, and even then it is problematic. The example GoogleDocs.ino it self seems to be an example to display its faults as it posts a rapidly declining memory availability and then the ESP8266 dumps its stack and reboots (if you are lucky). It might still be useful for single posts or short bursts with a deep sleep in between to clear out the memory leaks. Also there are quite a few details missing from the instructions. It seems there is some authentication issue, based on the output you posted, it probably works in the browser, because you are already authenticated there. You need to publish the google script as a web app that is executable for "Anyone even anonymous" (unless you have figures out a way the library allows you to authenticate). I tried posting using your script (sorry for the garbage data), and that seemed to work (it responded "Written on column C"). By that, you also need to have allowed anyone access to the google sheet you are using, and for the calendar fetch, also that calendar needs to be publicly available.

Traste commented 6 years ago

To be honest, i would not rely on this library for anything to be used other than in a test, it is too dodgy for my taste. I will take look at the official Google Cloud APIs a instead.

JacquesBB commented 6 years ago

Thanks a lot Traste, this was extremely helpful. The key point was

You need to publish the google script as a web app that is executable for "Anyone even anonymous" 

It is working now. I will see now what I can do with it, and if it suits my need without bugging. As it is, it should correspond to what I want to do, logging data every minute or so.

electronicsguy commented 6 years ago

@JacquesBB and @Traste JacquesBB, thanks for reporting. There may be something unique in your setup. IT does work, in the sense the HTTP requests and happening and re-direction is working. Please post the entire output of the second http request on pastebin, so that we can debug.

As far as the concerns raised by Traste: Yes this is a hobby project. Everything you've mentioned is clearly documented in the Readme. Please go through it again. The authentication is a Google requirement (and very rightly so). There are 2 ways to do it - anonymous authentication or OAUTH for every app and every request. I chose to do it the first way since I find it way more streamlined. Again, all details are in the Readme. (Read Sec. IV(b), "Server Side", Point 5)

Please let me know what exactly you find missing and I'll be happy to add it to the documentation.

The example code is requesting memory. There is a lag till it's released by the HTTPClient handler. This is not a bug, it's the way it's designed.

Traste commented 6 years ago

Design, feature, bug.... it is all in the eyes of the debugger. :)