I am trying to control my arduino with a google spreadsheet. The sheet is as well used to log data.
Data logging works fine via a "doGet" script.
By data gathering i got:
Status code: 302
Response: <HTML>
<HEAD>
<TITLE>Moved Temporarily</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Moved Temporarily</H1>
The document has moved <A HREF="https://script.googleusercontent.com/macros/echo?user_content_key=sfl6s47tbDyzqTmZlivpG2PJADDmLTBQYKAqbXw_FyRiYupVBQCy2dDmDlWGfpGdFvl7wklzor7id5GbVlDVoCi61bQMiqKpOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHa3RPuJqkvUROZaCe_pjVma7SmiJ9YXP6Gag2W0Sc4isrApF96gzrQTR0yx7NkUd_K5QZr9Setq5kZHMIxZvIaHLGQSpqBWNL-KDHPIhCQ5drda71HFMvP7Th5qV-y_4qEA&lib=Moa8oYzMClGGgF5550jyaC6-vHCGOnLBX">here</A>.
</BODY>
</HTML>
Most Arduino HTTP client libraries don't offer support to automatically handle redirections. You have to implement that yourself. But that's quite easy, if the response code is 302 (or 303) just make another get using the URL you got in the "Location" header.
Although this library implements the redirection case I wouldn't recommend it as it uses the String class and this should be avoided on AVR (and megaAVR) platforms.
It's also rather uncommon for a library to print debug information to the serial interface without setting a corresponding flag or the like.
By looping through the headers after reading the response code and checking that it was 302 or 303.
Post your code because you might have to change part of it to do this.
I tried something here but getting the 404 error.
By copying the new link in the browser it works...so the parsing should be OK.
Anyway thanks already for the support
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
char serverAddress[] = "script.google.com"; // server address
char serverAddress2[] = "script.googleusercontent.com"; // server address after redirect
int port = 443; // SSL Port
String GOOGLE_SCRIPT_ID = "AKfycbw7-xwd6z3u3TRix5n0ojuTvBjxQkec0hgNQhlo8Eh7HAnXIg__JDIndpSPgm1QhSix"; // ID von Params
WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network.
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
}
void loop() {
if (status == WL_CONNECTED) {
client = HttpClient(wifi, serverAddress, port);
Serial.println("making GET request");
String urlFinal = "/macros/s/" + GOOGLE_SCRIPT_ID + "/exec?read=B2&p1=1&p2=2";
client.get(urlFinal);
// read the status code and body of the response
int statusCode = client.responseStatusCode();
String response = client.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(response);
// now parse the response
int labelStart = response.indexOf("key");
// find the first = after key
int contentStart = response.indexOf("=", labelStart);
// find the following } and get what's between the braces:
int contentEnd = response.indexOf("\"", labelStart);
String red_ID = response.substring(contentStart + 1, contentEnd);
Serial.println("Parsed KEy");
Serial.println(red_ID);
Serial.println();
//Request after redirect
Serial.println("equest after redirect");
client = HttpClient(wifi, serverAddress2, port);
String urlFinal1 = "/macros/echo?user_content_key=" + red_ID;
client.get(urlFinal1);
// read the status code and body of the response
statusCode = client.responseStatusCode();
response = client.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(response);
delay(30000);
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
Sorry, parsing html output if you could get a defined header isn't very clever. That output can change without notice because the content isn't fixed by any standard. But at least you posted your code, so we can help.
That might be because the browser does a lot more things than just sending requests and showing the result. One example is the Cookie system. Your URL on Google returns 3 cookies (sorry, I just tried your URL to get that information) which the server expects to be included as headers in the next request sent, even if that is a redirection.
Thanks a alot for your reply. I see your code is way more elegant than my newbie stuff.
I see i have a lot to learn parse/html handling.
Does your already solve this 3 cookies (header) thing?
(I can test earliest in the evening
No problem in using my url, its for testing obly atm.
Hello
I tested out. I had to do some small modifications, but now i am getting the correct response
Thank you very much
Here what i modified. (one missing bracket and the plus 8 in building the server and path
if (statusCode == 302 || statusCode == 303) {
String location;
Serial.print(" Redirection");
while (client.headerAvailable()) {
if (client.readHeaderName() == "Location") {
location = client.readHeaderValue();
break;
}
}
if (location.length()) {
uint16_t path_begin = location.substring(8).indexOf('/');
String server = location.substring(8, path_begin + 8);
String path = location.substring(path_begin + 8);
client = HttpClient(wifi, server, port);
client.get(path);
statusCode = client.responseStatusCode();
Serial.print("Status code: after Redirect is: ");
Serial.println(statusCode);
}
}
Just for my understanding is it now working because in your code you are "updating" the client, while i created a new one, or why do i get now a 200 instead of a 404?
I'm not parsing the HTML returned but the header as the standard suggests. And your code relies on the Google server returning the parameters always in the same order and redirecting to the same URL except those parameters. That are probably too much assumptions.