Skip to content

Instantly share code, notes, and snippets.

@henrik
Last active August 24, 2022 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henrik/014d8fe0c59125f72a7812775f60c704 to your computer and use it in GitHub Desktop.
Save henrik/014d8fe0c59125f72a7812775f60c704 to your computer and use it in GitHub Desktop.
AWS Lambda Ruby script to get cat status from the SureFlap cat flap. Very rough-and-ready. Intended to be used with an iOS shortcut to get cat status.

AWS Lambda Ruby script to get cat status from the SureFlap cat flap. Very rough-and-ready.

Intended to be used with an iOS shortcut to get cat status – see https://twitter.com/henrik/status/1321201656822943745 for a screenshot of the shortcut.

This is not a tutorial, just some public notes for my own future use.

Setup hints

Create this as a AWS Lambda running on Ruby.

The script is self-contained with no Gem dependencies, so it can be added via the web UI editor.

Add ENVs – see the top of the script.

Set up a public Lambda Function URL.

Would be nice but will probably never happen

  • Better kind of auth
  • Better docs
KEY = ENV.fetch("KEY")
LOGIN = ENV.fetch("LOGIN")
PW = ENV.fetch("PW")
PET_ID = ENV.fetch("PET_ID") # I got this via my https://github.com/matryer/bitbar-plugins/blob/master/Lifestyle/sureflap.15s.rb.
PET_NAME = ENV.fetch("PET_NAME")
TZ = ENV.fetch("TZ") # Your preferred timezone – try `require "time"; Time.now.zone` to see its name in a format that Ruby recognises.
require "net/http"
require "json"
require "time"
def lambda_handler(event:, context:)
key = event.dig("queryStringParameters", "key")
return { statusCode: 403, body: "Denied! Wrong 'key'." } unless key == KEY
# Get token.
uri = URI.parse("https://app.api.surehub.io/api/auth/login")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req.body = { email_address: LOGIN, password: PW, device_id: "0" }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
token = JSON.parse(res.body).dig("data", "token")
# Use token to get status.
uri = URI.parse("https://app.api.surehub.io/api/pet/#{PET_ID}/position")
req = Net::HTTP::Get.new(uri, "Content-Type" => "application/json", "Authorization" => "Bearer #{token}")
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body).fetch("data")
since = Time.at(Time.parse(data.fetch("since")) + Time.zone_offset(TZ)).strftime("%H:%M") # Convert from UTC to desired timezone.
output = "#{PET_NAME} is #{data.fetch("where") == 1 ? "home" : "out and about"} since #{since}."
{ statusCode: 200, body: output }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment