Webhooks Tutorial - get your unread gmail count

Now it is really easy to do, using gmail’s atom capability and the power of Webhooks…

first set up your Webhook in the Spark CLI:

spark webhook create gmail_count https://<GMAIL_USER_NAME>:<GMAIL_PASSWORD>@mail.google.com/mail/feed/atom/

you will get:

Sending webhook request  { uri: 'https://api.spark.io/v1/webhooks',
  method: 'POST',
  json: true,
  form: 
   { event: 'gmail_count',
     url: 'https://YourUsername:YourPassword@mail.google.com/mail/feed/atom/',
     deviceid: undefined,
     access_token: 'yourAccessToken',
     requestType: undefined,
     headers: undefined,
     json: undefined,
     query: undefined,
     auth: undefined,
     mydevices: undefined } }
Successfully created webhook!

then the code (right from the Spark Documents):


int emailCount = -99;
unsigned long myTimer;

void setup() {
    //Serial.begin(115200);
    Spark.subscribe("hook-response/gmail_count", gotGmailAtomFeed, MY_DEVICES);
    Spark.variable("EmailCount", &emailCount, INT);
    Spark.publish("gmail_count");
    myTimer = millis();
}

void loop() 
{
    if (millis() - myTimer > 60000UL)
    {
      //Serial.println("Requesting Gmail Count!");
      Spark.publish("gmail_count");
      myTimer = millis();
      //char buffer[25];
      //sprintf(buffer, "You have %d email%s", emailCount, (emailCount == 0 || emailCount > 1)? "s." :".");
      //Serial.println(buffer);
    }
}

void gotGmailAtomFeed(const char *event, const char *data) 
{
    String buffer = String(data);
    String emailReturn = extractString(buffer, "<fullcount>", "</fullcount>");
    if (emailReturn != NULL) 
      emailCount = emailReturn.toInt(); //
}

String extractString(String myString, const char* start, const char* end) 
{
    if (myString == NULL) 
    {
        return NULL;
    }
    int idx = myString.indexOf(start);
    if (idx < 0) {
        return NULL;
    }
    int endIdx = myString.indexOf(end);
    if (endIdx < 0) {
        return NULL;
    }
    return myString.substring(idx + strlen(start), endIdx);
}

and it will quite nicely display your count!

EDIT: pasted wrong code, is correct now.

4 Likes

Anyone have any idea why the above sample that I wrote back then does not return correctly now ?

this is an example of the return… the only thing I can think of is that it is getting split somewhere in the search text:

<feed xmlns="http://purl.org/atom/ns#" version="0.3">
<title>Gmail - Inbox for yrEmailName@gmail.com</title>
<tagline>New messages in your Gmail Inbox</tagline>
<fullcount>1</fullcount>
<link rel="alternate" href="https://mail.google.com/mail" type="text/html"/>
<modified>2015-06-23T03:17:21Z</modified>
<entry>
<title>REDLINE: Draft Week is Here</title>
<summary>
Click here if you are having trouble viewing this message. DRAFT WEEK HAS ARRIVED Friday and Saturday
</summary>
<link rel="alternate" href="https://mail.google.com/mail?account_id=yrEmailName@gmail.com&message_id=14e1cab089648790&view=conv&extsrc=atom" type="text/html"/>
<modified>2015-06-22T19:07:27Z</modified>
<issued>2015-06-22T19:07:27Z</issued>
<id>tag:gmail.google.com,2004:1504706610086578064</id>
<author>
<name>Florida Panthers Ho.</name>
<email>newsandnotes@floridapanthers.com</email>
</author>
</entry>
</feed>

I thought I read that String was 622 bytes… it seems like I should not have this problem…

@Dave… Any thoughts?

Hmm, it should be breaking the response into 512 byte chunks, can you try dumping the subscribe contents onto Serial.println calls or something and seeing what you get back? Or you can watch what comes back with a subscribe or with the CLI / etc:

particle subscribe mine

Can you check and see what’s coming back over the wire?

Thanks,
David

I PM’m the response using:

particle subscribe mine

it looks like I am getting null returns…

I don’t think i have a rate limiting problem on gmail…

@Dave

it seems that re-updating the firmware helped a lot (I didn’t think I had to do that again) but now I am only dealing with spark.publish( ) events that are not reliably returning my webhook. I think that is a known problem.

int emailCount = -99;
unsigned long myTimer;

void setup() {
    Serial.begin(115200);
    Spark.subscribe("hook-response/gmail_count", gotGmailAtomFeed, MY_DEVICES);
    Spark.variable("EmailCount", &emailCount, INT);
    Spark.publish("gmail_count");
    myTimer = millis();
    Serial.println("Restarting...");
}

void loop()
{
    if (millis() - myTimer > 15000UL)
    {
      Serial.println("Requesting Gmail Count!");
      char aBuffer[35];
      sprintf(aBuffer, "Last check you had %d email%s", emailCount, (emailCount == 0 || emailCount > 1)? "s." :".");
      Serial.println(aBuffer);
      Spark.publish("gmail_count");
      myTimer = millis();
    }
}

void gotGmailAtomFeed(const char *event, const char *data)
{
    String buffer = String(data);
    String emailReturn = extractString(buffer, "<fullcount>", "</fullcount>");
    if (emailReturn != NULL)
    {
      emailCount = emailReturn.toInt(); //
      char buffer[35];
      sprintf(buffer, "Now, you have %d email%s", emailCount, (emailCount == 0 || emailCount > 1)? "s." :".");
      Serial.println(buffer);
    }
}

String extractString(String myString, const char* start, const char* end)
{
    if (myString == NULL)
    {
        return NULL;
    }
    int idx = myString.indexOf(start);
    if (idx < 0) {
        return NULL;
    }
    int endIdx = myString.indexOf(end);
    if (endIdx < 0) {
        return NULL;
    }
    return myString.substring(idx + strlen(start), endIdx);
}
1 Like

@Dave,

Is there any way you could you tell me if your server has been blocked by Google? this seems not to work anymore; calling a webhook as created above:

particle webhook create gmail_count https://<GMAIL_USER_NAME>:<GMAIL_PASSWORD>@mail.google.com/mail/feed/atom/

Found it… You cannot use 2-Step verification setting on GMail !!

1 Like

Sorry about the delay, glad you got this settled!

Thanks,
David