Skip to content

Instantly share code, notes, and snippets.

@vlntnwbr
Last active December 10, 2024 21:27
Show Gist options
  • Save vlntnwbr/f0ef070c39c23d86ba6261aefb504d2e to your computer and use it in GitHub Desktop.
Save vlntnwbr/f0ef070c39c23d86ba6261aefb504d2e to your computer and use it in GitHub Desktop.
##
# Copyright (c) 2020 Valentin Weber
#
# After some minor modifications (as marked below) this EventGhost
# Python script provides a method to send requests to devices
# registered with the Join API <https://joaoapps.com/join/api/> from
# any EventGhost Python Script or Command.
#
# EventGhost usage: `eg.globals.JoinPushDevice(text="hello_world")`
##
"""Send requests to Join REST API from EventGhost."""
from inspect import getmembers, isclass
class JoinRequest:
"""Base Class for Request to Join API.
Needs personal Join API KEY to work. Besides that nothing needs
to be modified here.
Accepts all values included in the Join API documentation
<https://joaoapps.com/join/api/> but will not validate them.
Parameters not mentioned there will not cause an error before
sending the request but might return an error message from the api.
Raises `JoinApiError` if API request returns an error message.
"""
DEVICE = None # Do not replace
API_KEY = "API_KEY_PLACEHOLDER" # replace with personal API KEY
class JoinApiError(BaseException):
"""Error For Join API Requests."""
pass
import urllib
import urllib2
import json
def __init__(self, **params):
params["apikey"] = self.API_KEY
params["deviceId"] = self.DEVICE
join_request = self.urllib2.urlopen(
"https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush",
data=self.urllib.urlencode(params).encode()
)
msg = self.json.loads(
join_request.read()
).get("errorMessage", False)
if msg:
raise self.JoinApiError(msg)
class RegisterDevices:
"""Adds all nested classes to `eg.globals` using their name."""
def __init__(self):
members = [
m for m in getmembers(self, isclass) if m[0] != "__class__"
]
for name, obj in members:
try:
setattr(eg.globals, name, obj)
print("ADDED: " + name + "(**params)")
except Exception as e:
print "SKIPPED: ", name, ": " + str(e)
continue
# Device List (names may be changed for easier identification)
class JoinPushDeviceOne(JoinRequest): # optionally rename
DEVICE = "INSERT_ID_FOR_JOIN_DEVICE_ONE_HERE" # replace
class JoinPushDeviceTwo(JoinRequest): # optionally rename
DEVICE = "INSERT_ID_FOR_JOIN_DEVICE_TWO_HERE" # replace
##
# Add more devices if needed
#
# Make sure each added class is a nested class by indenting it
# with 4 spaces. Also ensure that each new class is a subclass of
# `JoinRequest` since that class contains the functionality to
# make a request to the API.
##
RegisterDevices()
@vlntnwbr
Copy link
Author

EventGhost to Join API

This EventGhost Python script provides a method to send requests to devices registered with Join from any EventGhost Python Script or Command using the REST API of the service.

Install by copying the contents of the file into a "Python Script" action located in the "Autostart" macro to ensure it is run whenever EventGhost launches. The script as is should output the following lines to the EventGhost log when run (click "Test" button in EventGhost):

ADDED: JoinPushDeviceOne(**params)
ADDED: JoinPushDeviceTwo(**params)

Since no API KEY or Device IDs were provided, these default devices will not work when accessed. In order to add personal devices some minor modifications must be made. These will be explained below. The modifications needed are also annotated within the script itself.

Adding Join API Key

Replace the value API_KEY_PLACEHOLDER in class JoinRequest with the API key found here. Make sure the replaced API key is still surrounded by ".

Important: The API key is sensitive information (like a password) so make sure you remove it before sharing your script anywhere.

Adding Personal Devices

All Devices are collected within class RegisterDevices. This class will add all of its contained classes to the eg.globals namespace using their name making them available to all EventGhost Python Script or Command actions.

Every device class, e.g. class JoinPushDeviceOne(JoinRequest), needs to inherit from class JoinRequest since that includes the functionality to make a request to the API. The device class only needs its device ID which needs to be set as the DEVICE attribute of the class. Just like with the API key previously, make sure the replaced ID is surrounded by ".

The default devices in the script provide an example for how a device class should look.

Sending Requests to Personal Devices

usage:  eg.globals.JoinPushDeviceOne(text="hello_world")

The above command will send a Join API push to the device whose ID was given to class JoinPushDeviceOne setting the text parameter to hello_world. The request class accepts any parameter, encodes each of them for use in an URL and sends those to the specified device without prior validation. This includes parameters not included in the official documentation. Sometimes the API returns an error message. In that case the script will raise an exception containing that message making it visible to the EventGhost log.

Thanks for reading!

Suggestions for improvement are welcome! When reporting a problem, please include a copy of your script (make sure to remove your API Key before doing so).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment