Triggering Webhook with Multiple Button Presses

Hey guys,

I’ve been working with the Particle Photon lately and have finally made progress with my 5 Button Input to 5 Different Output setup. Basically, I’m trying to build a device with 5 buttons, with each one triggering a different action over the internet. Initially I worked it out with IFTTT. However, my Project Sponsor has asked me to look into triggering a Webhook with the button presses.

I’ve already setup the webhook as well, but I can’t figure out how to trigger a different action with all 5 buttons to the webhook. The way the API is structured is that it just needs a JSON payload of Date, Time, and one of the 5 keywords - Up/Down/Left/Right/Stop.

How can I go about this? I’m trying to go through as much literature on Particle and Webhooks and JSON as I can, but I’m really lost.

Help a brother out?

Do you mean passing an argument to a webhook that can perform differently based on the argument:

Example: IGet the weather for 5 different cities based on the pressed button

Or, are you looking to trigger 5 different webhooks?

Or, are you looking for something else?

Hi,

I meant getting the weather for 5 different cities based on the pressed button. Say, I press:
Button 1 = City 1
Button 2 = City 2


Button 5 = City 5

Is your question how to build the payload or how to the webhook needs to look?

Primarily on how to build the payload. But I’d love it if someone helps make sense of how the webhook needs to look as well.

I’m sorry if I’m sounding really daft here, pretty new to all of this!

That’s the easier part :wink:

However you are currently checking your buttons, you’d just need to do something like this

const char btnNames[][8] = { "Up", "Down", "Left", "Right", "Stop" }; 
const int  btnCnt = sizeof(btnNames) / sizeof(btnNames[0]);
int btnNr = -1; // no button is -1, other buttons 0 .. 4

void loop()
{
  static uint32_t ms;  // to heed the rate limit of max 1 publish per second

   ...

  if (btnNr >= 0 && btnNr < btnCnt && millis() - ms > 1010)
  {
    Particle.publish("yourEventName", btnNames[btnNr], PRIVATE);
    btnNr = -1;
    ms = millis();
  }
}

The current date and time are already part of the publish and can be accessed in the webhook via {{PARTICLE_PUBLISHED_AT}} (is UTC tho’)

If you want a more complex payload, you could build a JSON string via snprintf()

So I am using a single webhook to retrieve weather from weatherunderground, but the devices are in different locations. I pass an argument(s) during the publish event to the webhook. So, let’s first look at the webhook (which I use all the time).

{
	"event": "current_weather",
	"url": "http://api.wunderground.com/api/getYourOwnApiKey/conditions/q/{{my-state}}/{{my-city}}.json",
	"requestType": "POST",
	"headers": null,
	"query": null,
	"responseTemplate": "{{#response}}{{#current_observation}}{{#estimated}}{{weather}}~{{temp_f}}~{{relative_humidity}}~{{wind_dir}}~{{wind_gust_mph}}~{{dewpoint_f}}~{{/estimated}}{{/current_observation}}{{/response}}",
	"responseTopic": "{{SPARK_CORE_ID}}_current_weather",
	"json": null,
	"auth": null,
	"coreid": null,
	"deviceid": null,
	"mydevices": true
}

Notice in particular the {{my-state}} and {{my-city}} which are passed along in the url. Also, look where {{SPARK_CORE_ID}} is passed along as the first part of the responseTopic.

So, taking snippets from my code, I make calls to the same webhook from different devices with different deviceID’s (obviously) and the device itself is looking for any event that it asked for, like this:

Particle.subscribe(responseTopic, webhookHandler, MY_DEVICES);

you see… webhookHandler() is called for every event that that particular device ‘asks’ for.

I build the publish event like this, which you could easily dynamically set with the press of a button:

sprintf(publishString, "{\"my-city\": \"%s\", \"my-state\": \"%s\" }", cityLocation, stateLocation);
...
...
Particle.publish("current_weather", publishString, 60, PRIVATE); //<<<< note the event name here!

and then webHookHandler() looks like this:

void webhookHandler(const char *event, const char *data)
{
  if(strstr(event, "current_weather"))
  {
    gotWeather(event, data);
  }
  else if (strstr(event, "sun_time"))
  {
    sunTimeHandler(event, data);
  }
}

FYI, sun_time is a similarly structured webhook that gets me Sunrise, Sunset and DST offset, so here you go:

void sunTimeHandler(const char * event, const char * data)
{
  String sunriseReturn = String(data);
  char sunriseBuffer[125] = "";
  sunriseReturn.toCharArray(sunriseBuffer, 125); // example: \"5~37~20~30~\"
  webhookSunrise.theHour = atoi(strtok(sunriseBuffer, "\"~"));
  webhookSunrise.theMinute = atoi(strtok(NULL, "~"));
  webhookSunset.theHour = atoi(strtok(NULL, "~"));
  webhookSunset.theMinute = atoi(strtok(NULL, "~"));
  tvOnTime = webhookSunset;
  //Particle.publish("pushover", "Got times", 60, PRIVATE);
}

and the webhook, if you are interested there too… the same structure:

{
	"event": "sun_time",
	"url": "http://api.wunderground.com/api/getYouOwnApiKey/astronomy/q/{{my-state}}/{{my-city}}.json",  
	"requestType": "POST",
	"headers": null,
	"query": null,
	"responseTemplate": "{{#sun_phase}}{{sunrise.hour}}~{{sunrise.minute}}~{{sunset.hour}}~{{sunset.minute}}~{{#moon_phase}}{{current_time.hour}}~{{current_time.minute}}{{/moon_phase}}~{{/sun_phase}}",
	"responseTopic": "{{SPARK_CORE_ID}}_sun_time",
	"json": null,
	"auth": null,
	"coreid": null,
	"deviceid": null,
	"mydevices": true
}

I hope that helps!

1 Like