Last active
November 27, 2018 02:12
-
-
Save mjvo/c5ca35bebfe7807b540dc8b723e95328 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Arduino library dependencies | |
#include <SPI.h> | |
#include <WiFi101.h> | |
#include <timer.h> | |
#include <ArduinoJson.h> | |
// ************ | |
// Enter your wifi access credentials in the tab: arduino_secrets.h | |
// ************ | |
#include "arduino_secrets.h" | |
char ssid[] = SECRET_SSID; | |
char pass[] = SECRET_PASS; | |
int wifi_status = WL_IDLE_STATUS; // the WiFi radio's status | |
// variables for Instagram | |
char token[] = ACCESS_TOKEN; | |
unsigned int last_followers = NULL; | |
String last_post_id = ""; | |
unsigned int last_likes_count = NULL; | |
// instantiate a secure WiFi client | |
// (most APIs require https connections) | |
WiFiSSLClient client; | |
// create a timer with default settings | |
auto doQuery = timer_create_default(); | |
void setup() { | |
//Initialize serial: | |
Serial.begin(9600); | |
// Feather M0-specific WiFi pins | |
WiFi.setPins(8, 7, 4, 2); | |
// do initial WiFi connect | |
wifiConnect(); | |
// Query Instagram - https://www.instagram.com/developer/endpoints/users/ | |
// Followers available from GET /users/self | |
queryFollowers(false); | |
// Media posts available from GET /users/self/media/recent | |
queryPosts(false); | |
// establish regular query intervals using timer library | |
setQueryIntervals(); | |
} | |
void setQueryIntervals() { | |
// syntax: doQuery.every(milliseconds, callbackFunction); | |
doQuery.every(60000, queryFollowers); // queries Instagram followers every 1 min | |
doQuery.every(60000, queryPosts); // queries Instagram posts every 1 min | |
} | |
// *********** | |
// QUERY FOLLOWERS function | |
// *********** | |
bool queryFollowers(void *) { | |
Serial.println("Querying Instagram Followers..."); | |
client.setTimeout(10000); | |
client.connect("api.instagram.com", 443); | |
// Send HTTP request | |
client.print("GET /v1/users/self/?access_token="); | |
client.print(token); | |
client.println(" HTTP/1.1"); | |
client.println(F("Host: api.instagram.com")); | |
client.println(F("User-Agent: FeatherQuery")); | |
if (client.println() == 0) { | |
Serial.println(F("Failed to send request")); | |
return true; // break out of queryFollowers function | |
} | |
// Check HTTP status | |
char status[32] = {0}; | |
client.readBytesUntil('\r', status, sizeof(status)); | |
if (strcmp(status, "HTTP/1.1 200 OK") != 0) { | |
Serial.print(F("Unexpected response: ")); | |
Serial.println(status); | |
return true; // break out of queryFollowers function | |
} | |
// Skip response headers | |
char endOfHeaders[] = "\r\n\r\n"; | |
client.find(endOfHeaders); | |
// Allocate JsonBuffer per https://arduinojson.org/v5/assistant/ | |
const size_t capacity = JSON_OBJECT_SIZE(1) + | |
JSON_OBJECT_SIZE(2) + | |
JSON_OBJECT_SIZE(3) + | |
JSON_OBJECT_SIZE(8) + 350; | |
StaticJsonBuffer<capacity>jsonBuffer; | |
// Parse response | |
JsonObject& root = jsonBuffer.parseObject(client); | |
// Extract the data | |
JsonObject& data = root["data"]; | |
// Extract values | |
Serial.print("Welcome "); | |
Serial.println(data["full_name"].as<char*>()); | |
JsonObject& counts = data["counts"]; | |
unsigned int followers = counts["followed_by"]; | |
Serial.print("Followers: "); | |
Serial.println(followers); | |
// DO SOMETHING HERE with follower info | |
// Such as: | |
if (followers > last_followers) { | |
int new_followers = followers - last_followers; | |
Serial.print("New followers since last query: "); | |
Serial.println(new_followers); | |
last_followers = followers; | |
} | |
else { | |
Serial.println("No new followers since last query."); | |
} | |
// Disconnect | |
client.println(F("Connection: close")); | |
Serial.println("Query closed."); | |
client.stop(); | |
return true; // repeat | |
} | |
// *********** | |
// QUERY MEDIA POSTS function | |
// *********** | |
bool queryPosts(void *) { | |
Serial.println("Querying Instagram Posts..."); | |
client.setTimeout(10000); | |
client.connect("api.instagram.com", 443); | |
// Send HTTP request | |
client.print("GET /v1/users/self/media/recent/?count=1&access_token="); | |
client.print(token); | |
client.println(" HTTP/1.1"); | |
client.println(F("Host: api.instagram.com")); | |
client.println(F("User-Agent: FeatherQuery")); | |
if (client.println() == 0) { | |
Serial.println(F("Failed to send recent posts request")); | |
return true; // break out of queryPosts function | |
} | |
// Check HTTP status | |
char status[32] = {0}; | |
client.readBytesUntil('\r', status, sizeof(status)); | |
if (strcmp(status, "HTTP/1.1 200 OK") != 0) { | |
Serial.print(F("Unexpected response: ")); | |
Serial.println(status); | |
return true; // break out of queryPosts function | |
} | |
// Skip response headers | |
char endOfHeaders[] = "\r\n\r\n"; | |
client.find(endOfHeaders); | |
// Allocate JsonBuffer per https://arduinojson.org/v5/assistant/ | |
const size_t capacity = 2*JSON_ARRAY_SIZE(0) + | |
JSON_ARRAY_SIZE(1) + | |
JSON_OBJECT_SIZE(0) + | |
3*JSON_OBJECT_SIZE(1) + | |
5*JSON_OBJECT_SIZE(3) + | |
3*JSON_OBJECT_SIZE(4) + | |
JSON_OBJECT_SIZE(15) + 2500; | |
StaticJsonBuffer<capacity>jsonBuffer; | |
// Parse response | |
JsonObject& root = jsonBuffer.parseObject(client); | |
// Extract the data | |
JsonObject& most_recent_post = root["data"][0]; | |
String post_id = most_recent_post["id"]; | |
int likes_count = most_recent_post["likes"]["count"]; | |
// Extract values | |
Serial.print("Most recent post by "); | |
Serial.println(most_recent_post["user"]["full_name"].as<char*>()); | |
Serial.print("Post ID: "); | |
Serial.println(post_id); | |
// DO SOMETHING HERE with post and like information | |
// Such as: | |
if (post_id == last_post_id){ | |
Serial.println("Not a new post"); | |
Serial.print("Likes: "); | |
Serial.println(likes_count); | |
if (likes_count != last_likes_count){ | |
Serial.println("# of likes have changed since last query"); | |
last_likes_count = likes_count; | |
} | |
else { | |
Serial.println("No change in likes"); | |
} | |
} | |
else { | |
Serial.println("New post since last query!"); | |
last_post_id = post_id; | |
Serial.print("Likes: "); | |
Serial.println(likes_count); | |
last_likes_count = likes_count; | |
} | |
// Disconnect | |
client.println(F("Connection: close")); | |
client.stop(); | |
return true; // repeat | |
} | |
void loop() { | |
// check if wifi lost and if yes, reconnect | |
if (WiFi.status() != WL_CONNECTED) { | |
Serial.println("WiFi connection lost. Reconnecting..."); | |
wifi_status = WL_IDLE_STATUS; | |
wifiConnect(); | |
} | |
doQuery.tick(); | |
} | |
// connect to WiFi (or reconnect if WiFi lost) | |
void wifiConnect() { | |
// check for the presence of the shield: | |
if (WiFi.status() == WL_NO_SHIELD) { | |
Serial.println("WiFi chip not present or accessible"); | |
// don't continue: | |
while (true); | |
} | |
// attempt to connect to WiFi network: | |
while ( wifi_status != WL_CONNECTED) { | |
Serial.print("Attempting to connect to SSID: "); | |
Serial.println(ssid); | |
// Connect to WiFi: | |
if (sizeof(pass) <= 1) { | |
wifi_status = WiFi.begin(ssid); | |
} | |
else { | |
wifi_status = WiFi.begin(ssid, pass); | |
} | |
// wait 2 seconds for connection: | |
delay(2000); | |
} | |
// you're connected now, so print out a success message: | |
Serial.println("You're connected to the network"); | |
// print your Feather's IP address: | |
IPAddress ip = WiFi.localIP(); | |
Serial.print("Device IP Address: "); | |
Serial.println(ip); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment