[Webhook SmartApp] Context Store for API calls

Nayely,
Thanks for the response.
I think I clouded the issue by referencing the whole Zoom thing.
Completely ignoring Zoom, here’s what I’m attempting, using the SDK for Node JS.

Short version:
How do I re-authenticate my webhook endpoint in the ABSENCE of lifecycle events. That is, when my webhook starts running on my server, how do I authenticate it.

Long version:
I’m trying to run a Smartthings webhook endpoint on my own server. This app must make requests to the Smartthings API that are NOT a result of a lifecycle event. This app may be restarted for any number of reasons (server maintenance, etc.). Except for installation, the app is unlikely to receive many lifecycle events from either the user (e.g. ‘update’) or from event subscriptions, etc.

Generalized flow control:

  1. Initialize smartapp
  2. get status of switch chosen in the UI
  3. subscribe to that switch
  4. if switch is ‘ON’ get status of other switches chosen in UI

Here’s what I’ve accomplished:

I’ve written the endpoint and it functions fine. It is, for now, using a local FileContextStore.

Here’s where I’m stuck:

If the application is “idle” for a long enough period and then gets restarted, any Smartthings API call returns a ‘401 not authorized’ error. This can be corrected by having the user generate an ‘update’ lifecycle event. Seemingly the authorization tokens in the FileContextStore are expiring and the ‘update’ lifecycle event refreshes them. The application must make API calls that ARE NOT in response to a lifecycle event each time it starts up.
I cannot however find a way to “re-authenticate” the endpoint without the use of a lifecycle event.

I’ve tried multiple things, like getting the context from the FileContextStore, etc., but continue to get ‘401’ until I generate a lifecycle event from the UI.

Saving the SmartApp context helps you to save the Authorization Token and if you’re using the SmartApp SDK, when you try to make an active API call from within the SmartApp, it should be refreshed automatically.
The token expires in 24 hrs, is it after or before this time when you receive the 401 error?
If so, I need to take a look further at your configuration so I can see what can be blocking the automatic Token refresh. Please, send an email to build@smartthings.com with the following info:

  • Your SmartApp definition (it can be in a zip file)
  • Where are you hosting the SmartApp?

I’m not sure I completely follow what your trying to do, but I generated a personal access token that I use for my server startup and all non-lifecycle event API calls. You might look there if you haven’t already.

Thanks Jeff.
I started out that way but came to realize I need the SmartApp context (which contains a list of selected devices among other things) when the app fires up without a lifecycle event. Even went as far as building my own FileContextStore, but am trying to use the SDK one and built-in refresh token.

What language are you using? If you’re using Python, I can help you with more detail.

I just created a local database to store my rooms/devices/scenes/etc.

I’m trying to use the SDK for Node JS so this is in Javascript.
I wish there were an SDK for Python as I’d rather be using that.
If I can’t get the SDK for Node JS to accomplish my task, I may switch to Python and use the native API, which I assume is what you’re doing?

Just as a reference, using the Personal Access Token doesn’t allow you to create subscriptions, that’s only available for SmartApp tokens (SmartApp, OAuth).
For a successful refresh of the Access Token, you need to add these properties to your SmartApp definition:

.appId("xxxx-xxxx-xxxx-xxxx")
.clientId("xxxx-xxxx-xxxx-xxxx")
.clientSecret("xxxx-xxxx-xxxx-xxxx")

These values are the ones provided in the Developer Workspace when you register the Webhook. If you didn’t save the clientSecret, you can generate a new one by tapping on “regenerate”.

Please, let me know your results.

Nayely,

I had .clientId and .clientSecret on the SmartApp definition. I was missing .appId.
I’ve added .appId and will let you know whether my token successfully refreshes.
Thanks so much for your help.

David

You’re not trying to re-subscribe every time your server restarts, right? If so, that’s not necessary.

Since I have the context in the FileContextStore, no I’m not re-subscribing each time the app starts, just setting the context.

adding .appId to the SmartApp definition (.clientID and .clientSecret were already part of the definition) appears to have resolved my issue with the refreshtoken.
Thanks so much for your help.
David

1 Like

Happy to help! Please, remember to mark the solution of this thread so other developers can take reference from it.
Thanks!