Skip to content

Commit 2f7e8ad

Browse files
committed
fixing issue if body wasnt ready before headers were finished
1 parent 13c1533 commit 2f7e8ad

File tree

4 files changed

+189
-11
lines changed

4 files changed

+189
-11
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ cache:
1010

1111
env:
1212
- SCRIPT=platformioSingle EXAMPLE_NAME=ChannelStatistics EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini
13+
- SCRIPT=platformioSingle EXAMPLE_NAME=ChannelStatisticsWithWifiManager EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini
1314

1415

1516
install:
@@ -19,5 +20,7 @@ install:
1920
#
2021
# http://platformio.org/lib/show/64/ArduinoJson
2122
- platformio lib -g install 64
23+
# http://platformio.org/lib/show/567/WifiManager
24+
- platformio lib -g install 567
2225

2326
script: scripts/travis/$SCRIPT.sh

examples/ESP8266/ChannelStatistics/ChannelStatistics.ino

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
#include <YoutubeApi.h>
2-
31
/*******************************************************************
4-
* An example of bot that echos back any messages received *
2+
* Read YouTube Channel statistics from the YouTube API *
53
* *
6-
* written by Giacarlo Bacchio (Gianbacchio on Github) *
7-
* adapted by Brian Lough *
4+
* By Brian Lough *
5+
* https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA *
86
*******************************************************************/
97

10-
8+
#include <YoutubeApi.h>
119
#include <ESP8266WiFi.h>
1210
#include <WiFiClientSecure.h>
1311

12+
#include <ArduinoJson.h> // This Sketch doesn't technically need this, but the library does so it must be installed.
13+
1414
//------- Replace the following! ------
1515
char ssid[] = "xxx"; // your network SSID (name)
1616
char password[] = "yyyy"; // your network key
1717
#define API_KEY "zzzz" // your google apps API Token
18-
#define CHANNEL_ID "UCu7_D0o48KbfhpEohoP7YSQ" // makes up the url of channel
19-
20-
18+
#define CHANNEL_ID "UCezJOfu7OtqGzd5xrP3q6WA" // makes up the url of channel
2119

2220

2321
WiFiClientSecure client;
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*******************************************************************
2+
* Read YouTube Channel statistics from the YouTube API *
3+
* This sketch uses the WiFiManager Library for configuraiton *
4+
* *
5+
* By Brian Lough *
6+
* https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA *
7+
*******************************************************************/
8+
9+
#include <YoutubeApi.h>
10+
#include <ESP8266WiFi.h>
11+
#include <WiFiClientSecure.h>
12+
13+
// For storing configurations
14+
#include "FS.h"
15+
#include <ArduinoJson.h>
16+
17+
// WiFiManager Libraries
18+
#include <DNSServer.h> //Local DNS Server used for redirecting all rs to the configuration portal
19+
#include <ESP8266WebServer.h> //Local WebServer used to serve the configuration portal
20+
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
21+
22+
const int resetConfigPin = D8; //When high will reset the wifi manager config
23+
24+
char apiKey[45] = "";
25+
char channelId[30] = "UCezJOfu7OtqGzd5xrP3q6WA";
26+
27+
WiFiClientSecure client;
28+
YoutubeApi *api;
29+
30+
unsigned long api_mtbs = 60000; //mean time between api requests
31+
unsigned long api_lasttime; //last time api request has been done
32+
33+
long subs = 0;
34+
35+
// flag for saving data
36+
bool shouldSaveConfig = false;
37+
38+
//callback notifying us of the need to save config
39+
void saveConfigCallback () {
40+
Serial.println("Should save config");
41+
shouldSaveConfig = true;
42+
}
43+
44+
void setup() {
45+
46+
Serial.begin(115200);
47+
48+
if (!SPIFFS.begin()) {
49+
Serial.println("Failed to mount FS");
50+
return;
51+
}
52+
53+
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
54+
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level
55+
loadConfig();
56+
57+
WiFiManager wifiManager;
58+
wifiManager.setSaveConfigCallback(saveConfigCallback);
59+
60+
// Adding an additional config on the WIFI manager webpage for the API Key and Channel ID
61+
WiFiManagerParameter customApiKey("apiKey", "API Key", apiKey, 50);
62+
WiFiManagerParameter customChannelId("channelId", "Channel ID", channelId, 35);
63+
wifiManager.addParameter(&customApiKey);
64+
wifiManager.addParameter(&customChannelId);
65+
66+
// If it fails to connect it will create a YouTube-Counter access point
67+
wifiManager.autoConnect("YouTube-Counter", "supersecret");
68+
69+
strcpy(apiKey, customApiKey.getValue());
70+
strcpy(channelId, customChannelId.getValue());
71+
72+
if (shouldSaveConfig) {
73+
saveConfig();
74+
}
75+
76+
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
77+
// Force Config mode if there is no API key
78+
if(strcmp(apiKey, "") > 0) {
79+
Serial.println("Init YouTube API");
80+
api = new YoutubeApi(apiKey, client);
81+
} else {
82+
Serial.println("Forcing Config Mode");
83+
forceConfigMode();
84+
}
85+
api = new YoutubeApi(apiKey, client);
86+
Serial.println("");
87+
Serial.println("WiFi connected");
88+
Serial.println("IP address: ");
89+
IPAddress ip = WiFi.localIP();
90+
Serial.println(ip);
91+
92+
}
93+
94+
bool loadConfig() {
95+
File configFile = SPIFFS.open("/config.json", "r");
96+
if (!configFile) {
97+
Serial.println("Failed to open config file");
98+
return false;
99+
}
100+
101+
size_t size = configFile.size();
102+
if (size > 1024) {
103+
Serial.println("Config file size is too large");
104+
return false;
105+
}
106+
107+
// Allocate a buffer to store contents of the file.
108+
std::unique_ptr<char[]> buf(new char[size]);
109+
110+
configFile.readBytes(buf.get(), size);
111+
112+
StaticJsonBuffer<200> jsonBuffer;
113+
JsonObject& json = jsonBuffer.parseObject(buf.get());
114+
115+
if (!json.success()) {
116+
Serial.println("Failed to parse config file");
117+
return false;
118+
}
119+
120+
strcpy(apiKey, json["apiKey"]);
121+
strcpy(channelId, json["channelId"]);
122+
return true;
123+
}
124+
125+
bool saveConfig() {
126+
StaticJsonBuffer<200> jsonBuffer;
127+
JsonObject& json = jsonBuffer.createObject();
128+
json["apiKey"] = apiKey;
129+
json["channelId"] = channelId;
130+
131+
File configFile = SPIFFS.open("/config.json", "w");
132+
if (!configFile) {
133+
Serial.println("Failed to open config file for writing");
134+
return false;
135+
}
136+
137+
json.printTo(configFile);
138+
return true;
139+
}
140+
141+
void forceConfigMode() {
142+
Serial.println("Reset");
143+
WiFi.disconnect();
144+
Serial.println("Dq");
145+
delay(500);
146+
ESP.reset();
147+
delay(5000);
148+
}
149+
150+
void loop() {
151+
152+
if (digitalRead(resetConfigPin) == HIGH) {
153+
forceConfigMode();
154+
}
155+
if (millis() - api_lasttime > api_mtbs) {
156+
if(api->getChannelStatistics(channelId))
157+
{
158+
Serial.println("---------Stats---------");
159+
Serial.print("Subscriber Count: ");
160+
Serial.println(api->channelStats.subscriberCount);
161+
Serial.print("View Count: ");
162+
Serial.println(api->channelStats.viewCount);
163+
Serial.print("Comment Count: ");
164+
Serial.println(api->channelStats.commentCount);
165+
Serial.print("Video Count: ");
166+
Serial.println(api->channelStats.videoCount);
167+
// Probably not needed :)
168+
//Serial.print("hiddenSubscriberCount: ");
169+
//Serial.println(api->channelStats.hiddenSubscriberCount);
170+
Serial.println("------------------------");
171+
172+
}
173+
api_lasttime = millis();
174+
}
175+
}

src/YoutubeApi.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ String YoutubeApi::sendGetToYoutube(String command) {
4444
avail=false;
4545
while (millis() - now < YTAPI_TIMEOUT) {
4646
while (client->available()) {
47+
48+
// Allow body to be parsed before finishing
49+
avail = finishedHeaders;
4750
char c = client->read();
4851
//Serial.write(c);
4952

@@ -67,8 +70,6 @@ String YoutubeApi::sendGetToYoutube(String command) {
6770
}else if (c != '\r') {
6871
currentLineIsBlank = false;
6972
}
70-
71-
avail=true;
7273
}
7374
if (avail) {
7475
//Serial.println("Body:");
@@ -84,6 +85,7 @@ String YoutubeApi::sendGetToYoutube(String command) {
8485

8586
bool YoutubeApi::getChannelStatistics(String channelId){
8687
String command="https://" YTAPI_HOST "/youtube/v3/channels?part=statistics&id="+channelId; //If you can't find it(for example if you have a custom url) look here: https://www.youtube.com/account_advanced
88+
Serial.println(command);
8789
String response = sendGetToYoutube(command); //recieve reply from youtube
8890
DynamicJsonBuffer jsonBuffer;
8991
JsonObject& root = jsonBuffer.parseObject(response);

0 commit comments

Comments
 (0)