Skip to content

Instantly share code, notes, and snippets.

@mjvo
Last active November 27, 2018 02:12
Show Gist options
  • Save mjvo/c5ca35bebfe7807b540dc8b723e95328 to your computer and use it in GitHub Desktop.
Save mjvo/c5ca35bebfe7807b540dc8b723e95328 to your computer and use it in GitHub Desktop.
// 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