Issues with multiple instances of Spark.subscribe( ) for Webhooks

Since one Spark.subscribe("hook-response/", webhookHandler, MY_DEVICES); would catch both webhooks, you will be able to do this

void webhookHandler(const char *event, const char *data)
{
  Serial.println(event);  // just for debugging
                          // to see how the webhook was actually called
  
  if (strpos(event, "gmail_count") >= 0)
    gotGmailFeed(event, data);
  if (strpos(event, "nj_weather") >= 0)
    gotWeather(event, data);
}
2 Likes

that did it…
MUCH appreciated. We will have to see what’s up here.

(using strstr(), FYI):

bool pubToggle = true;
int emailCount = -99;
int outdoorDewpoint = -99;
int windSpeed = -99;
String windDirection;
String weatherCondition;
int outsideHumid = -99;
int outsideTemp = -99;
unsigned long pubTime = 0;

//
void setup()
{
  Serial.begin(9600);
  delay(6000);
  Spark.subscribe("hook-response/", webhookHandler, MY_DEVICES);
  //Spark.subscribe("hook-response/", gotGmailFeed, MY_DEVICES);
  //Spark.subscribe("hook-response/", gotWeather, MY_DEVICES);

}
//
void loop()
{
  if (millis() - pubTime > 10000UL)
  {
    Serial.print("publishing...");
    if (pubToggle)
    {
      Spark.publish("gmail_count");
      Serial.println("gmail count");
    }
    else
    {
      Spark.publish("nj_weather");
      Serial.println("weather");
    }
    pubToggle = !pubToggle;
    pubTime = millis();
  }
}
void gotGmailFeed(const char *event, const char *data)
{
  String gMailBuffer = String(data);
  String emailReturn = extractString(gMailBuffer, "<fullcount>", "</fullcount>");
  if (emailReturn != NULL)
  {
    emailCount = emailReturn.toInt(); //
    Serial.println("Email Count Retrieved");
    Serial.println(emailCount);
  }
}
void gotWeather(const char *event, const char *data)
{
  Serial.println("getting Weather");
  String weatherBuffer = String(data);
  String temperatureReturn = extractString(weatherBuffer, "<temp_f>", "</temp_f>");
  if (temperatureReturn != NULL)
  {
    outsideTemp = temperatureReturn.toInt();
    Serial.print("outsideTemp = ");
    Serial.println(outsideTemp);
  }
  //
}

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);
}
void webhookHandler(const char *event, const char *data)
{
  Serial.println(event);  // just for debugging
                          // to see how the webhook was actually called

  if (strstr(event, "gmail_count"))
    gotGmailFeed(event, data);
  else if(strstr(event, "nj_weather"))
    gotWeather(event, data);
}

outputs:

publishing…gmail count
hook-response/gmail_count/0
Email Count Retrieved
7
hook-response/gmail_count/1
hook-response/gmail_count/2
hook-response/gmail_count/3
hook-response/gmail_count/4
hook-response/gmail_count/5
hook-response/gmail_count/6
hook-response/gmail_count/7
publishing…weather
hook-response/nj_weather/0
getting Weather
hook-response/nj_weather/1
getting Weather
hook-response/nj_weather/2
getting Weather
hook-response/nj_weather/3
getting Weather
outsideTemp = 37
hook-response/nj_weather/4
getting Weather
hook-response/nj_weather/5
getting Weather
hook-response/nj_weather/6
getting Weather
hook-response/nj_weather/7
getting Weather

2 Likes

Do I interpret this wrong or does only one of the eight retriggers of the webhook actually carry some data payload?

Could you try this

 void webhookHandler(const char *event, const char *data)
{
  Serial.print(event);         // debug full event name
  Serial.print(" (");    
  Serial.print(strlen(data));  // debug payload length 
  Serial.println(")");

  ...
}
1 Like

you can see when there is no email that much fewer chunks of data are sent… I am using the Weather Underground API to retrieve the weather. In the test code, I am only extracting a single value from the XML.

publishing…gmail count
hook-response/gmail_count/0
(361)
Email Count Retrieved
0
publishing…weather
hook-response/nj_weather/0
(560)
getting Weather
hook-response/nj_weather/1
(562)
getting Weather
hook-response/nj_weather/2
(547)
getting Weather
hook-response/nj_weather/3
(556)
getting Weather
outsideTemp = 25
hook-response/nj_weather/4
(569)
getting Weather
hook-response/nj_weather/5
(546)
getting Weather
hook-response/nj_weather/6
(573)
getting Weather
hook-response/nj_weather/7
(73)
getting Weather
publishing…gmail count
hook-response/gmail_count/0
(361)
Email Count Retrieved
0

1 Like

Hmm, am I reading this right? you’re getting bad echo’s / responses of the hook firing?

Thanks,
David

No… I cannot get more than one webhook to return (without a custom handler like @ScruffR advised).

check out the first post…

Hmm, that’s weird, I’ll check things on this end.

Thanks!
David

Just wrote up this demo,

void setup() {
    Serial.begin(115200);
    
    Spark.subscribe("one", oneHandler);
    Spark.subscribe("two", twoHandler);
    Spark.subscribe("three", threeHandler);
    Spark.subscribe("four", fourHandler);
    
    Serial.println("subscribed!  waiting...");
}

void oneHandler(const char *topic, const char *data) {
    Serial.println("1.)" + String(topic) + ": " + String(data));
}
void twoHandler(const char *topic, const char *data) {
    Serial.println("2.)" + String(topic) + ": " + String(data));
}
void threeHandler(const char *topic, const char *data) {
    Serial.println("3.)" + String(topic) + ": " + String(data));
}
void fourHandler(const char *topic, const char *data) {
    Serial.println("4.)" + String(topic) + ": " + String(data));
}

void loop() {

}

With the CLI:

spark publish one 123
spark publish two 234
spark publish three 345
spark publish four 456

Serial output:

1.)one: 123
2.)two: 234
3.)three: 345
4.)four: 456

It’s possible you’re using webhooks too fast? You’re limited to 10 hook triggers per minute per core on your account, so if you have two you’re triggering every 10 seconds, you might be running over the limits?

I hope that helps!

Thanks,
David

1 Like

@Dave

my issue was tied to webhooks created like this:

5.) Hook #55171cbc2df05a607a544e1b is watching for "nj_weather"
and posting to: http://api.wunderground.com/api/MyApiKey/conditions/q/NJ/Princeton.xml
created at 2015-03-28T21:27:24.305Z

trying to work with another webhook like this:

3.) Hook #55006fa9a32e23062da048db is watching for "gmail_count"
and posting to: https://myEmail:MyPassword@mail.google.com/mail/feed/atom/
created at 2015-03-11T16:39:05.758Z

Calling (alternating) once per minute…

1 Like

Hi @BulldogLowell,

I think you’re right that there might be an issue here, digging in to see if I can track it down.

Thanks!
David

1 Like

thanks @Dave I appreciate your looking into it.

1 Like

Hi All,

Not wanted to create a new article so i use this one.

I have two webhooks configured. Plus in my code two times “spark.subscribe” defined in setup() which both call their own function. After some fiddling i detected that only the first defined spark.subscribe works.

How can i subscribe to two webhooks at the same time?!

Regards,
Bart

Have you read through the whole thread. There is your answer already :wink:

@ScruffR Humz, i think i have written over it, time for weekend i think :wink: … i’ll read it again, if I do not succeed i’ll let you know!

Update; Works! webhookHandler FTW!

2 Likes

To save you some reading :wink:

and the following post of the OP.

But it would still be interesting if @Dave found another solution.

3 Likes

I’m still tracking this down, sorry about the lack of news! You can also watch the responses from your hooks with the CLI with a quick spark subscribe mine :slight_smile:

Thanks,
David

2 Likes

@dave when monitoring the webhook response through dashboard/curl/node.js it just sometimes does not come through.
I see my webserver giving an response when the core publishes towards the webhook. But somewhere somehow the response is just not received or handled by the Spark Cloud.

How may I be able to monitor this better than through dashboard/curl/node.js

Regards,
Bart

Hi @bartjenniskens,

Sorry about the slow reply, so much going on! :slight_smile:

If your webserver doesn’t have any body in the http response, then the webhook won’t publish a response event. Can you make sure your server has a non-empty response?

Thanks,
David

1 Like

Hi all,

It took me a good two hours (edit: just realised how much time has gone!) to trim down my code to the bare webhooks, delete/readd webhooks, test, test, google, test, test, google. You get the idea.

This is a definite bug, I can replicate it and I know via particle CLI that the hook-responses of both have valid data. The first webhook subscribed to gets called, not the second, when you are publishing to both. You guys have pretty good support - though can I suggest someone updates the docs example to show the webhookHandler approach with a note there is a pending bug with multiple subscribe/publish pairs?

For the time being I’ll steal the webhookHandler idea.

1 Like

hate to ask, but has the behaviour suddenly changed?

subscribing to hook-response works, ‘hook-response/’ doesn’t appear to work anymore.