Dealing with OAUTH2 requirement with Cloud Connected Devices

If you want to move your code (like all those virtual devices you’re using) to the cloud before the Groovy/DTH/IDE shutdown, your two choices seem to be either use AWS Lambda, or set up and manage your own cloud server. (You can also go the direct-connect route, which personally I think is great to do on a Raspberry Pi, but that is another topic…)

I’ve started looking at how easy it is to implement schema connectors on Lambda, and it seems to be pretty straight-forward. However the hurdle there is the OAUTH2 requirement…

ST presumes that you are developing on your company cloud which will provide the OAUTH authentication services. But what if I’m an individual developing home automation code? AWS has no OAUTH solution, so what options are there for leveraging a third party (hopefully FREE) service for an OAUTH authentication server?

I’ve gotten the example schema connector code working on Lambda, but only by using the mock oauth server on Glitch (from their webhook example!). This seems to work for only a brief period of time, however. (I suspect the ‘fake’ token doesn’t last and can’t be refreshed)

I think we will all need a solution here, so would like to hear from anyone who has already gone down this road or is more knowledgeable.

1 Like

tagging @nayelyz @erickv

2 Likes

What do you mean it works for a brief period of time?
After the OAuth server provides the Authorization code and the Connector requests the Reciprocal Access Token, it remains valid until the integration deleted interaction is called (through a callback or deleting the device from the ST app).

By your description, I believe the SmartApp Connector seems more convenient:

  • It doesn’t require OAuth 2.0
  • You can configure the device onboarding UX, and ask for any data required
  • It can be created using the SmartApp NodeJS SDK.

Here’s an example that creates a switch device:

Let me know your thoughts.

1 Like

Hi !

When I first add the device it’s all working great (although there are some things that need to be fixed in the example code, which I documented in a feedback comment), but if I come back to the ST app a short while later (I haven’t timed it exactly), it shows the device is offline and I can’t get it to work again unless I delete and re-add the device. That’s why I thought maybe the token was expiring or the glitch mock server was no longer responding. Once it starts showing as offline in the mobile app, there are no more messages in the Lambda console log to indicate any more interaction requests coming from ST. Perhaps there is some other functionality that the example code is missing? For example there is no logic in the example code for reciprocal access token. Could this be the issue?

I’ll look at the SmartApp Connector a bit more, but it really looked much more involved (ngrok, docker, redis, etc.) and I didn’t see a Lambda implementation example. (I don’t want to have to set up and manage an internet server.)

The schema connector looked super simple except for the OAUTH requirement. If you think the Glitch mock server should work OK long term, that might be an answer… if I can only figure out why the device is going offline!

A bit more info: I’ve noticed that there is an ‘invoke’ error logged in Lambda when I first add my device:

2021-04-22T21:03:42.046Z	0ac1d5d5-fdf8-48dd-855f-b86daf48c3fe	ERROR	Invoke Error	{
    "errorType": "Error",
    "errorMessage": "[object Object]",
    "stack": [
        "Error: [object Object]",
        "    at _homogeneousError (/var/runtime/CallbackContext.js:12:12)",
        "    at postError (/var/runtime/CallbackContext.js:29:51)",
        "    at done (/var/runtime/CallbackContext.js:56:7)",
        "    at fail (/var/runtime/CallbackContext.js:68:7)",
        "    at Object.fail (/var/runtime/CallbackContext.js:104:16)",
        "    at Runtime.handler (/var/task/node_modules/st-schema/lib/lambda.js:75:24)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

This occurs as the first message after adding the device, but the device still operates OK and I then see the expected discovery, state refresh, and command interaction type requests. I don’t ever see a ‘grantCallbackAccess’ message. I’m no OAUTH expert - is that supposed to go my nodejs app or does that get sent to the OAUTH server? Your post above says ‘…the Connector requests the Reciprocal Access Token’, but this example code has no such logic in it.

The grantCallbackAccess request is sent to https://c2c-us.smartthings.com/oauth/token using the Authorization code from the OAuth Server.
You’re right, the lambda sample doesn’t include this sorry for the confusion. It is only mandatory if the third-party cloud will send updates to SmartThings when the device state changes from that side.

I think Glitch has a sleep timer for inactivity, this is why you could be experiencing the offline status.

The error can be related to the handler name, check this post where I listed the things you need to verify for the Lambda Schema Connectors:

I’ve done some searching around on the internet and I’m not finding any easy solution to the OAUTH service requirement. Seems the only option is to set up your own authentication server, and I don’t want to do that. So my conclusion is that the schema connector is out of scope for the individual community developer.

It’s really a shame because the schema + Lambda option could have been a real simple solution for self-hosting custom and virtual devices. Using a cloud-connected smart app might give more flexibility as you point out, but for simple device needs it makes things a bit over-complicated.

Using the direct-connect approach on a Raspberry Pi seems to be a good alternative once you get passed the initial setup. And you avoid the issues with opening up your computer to the internet (which is why I was looking for an easy Lambda-based solution). ngrok is fine for testing, but not sure I’d want to use it for long term connections!

Thank you for your help.

Hi, Todd.
For SmartApp Connector, you can base on the sample of a Lambda SmartApp, the only modification would be the SmartApp definition (and of course, the serverless config to change the function name).
Here’s how I modified the smartapp.js file.

This is the resulting device:

Either way, I assure you our engineering team is constantly working to provide you the best development tools.

Thank you. I do have this working, although my JavaScript skills are quite rusty! It’s not too bad although I noticed that the zip file to upload to Lambda is quite large for such a simple app (18M vs 1.4M for schema) due to all the SDK modules. Is there a way to trim that down for production? E.g. is snyk really necessary?

Awesome!

Actually, our engineering team is taking a look at that situation. Thanks for bringing that up. I’ll let you know in case I receive any info about it.

1 Like