Skip to content

Instantly share code, notes, and snippets.

@benbeadle
Last active December 15, 2015 02:09
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 benbeadle/5185679 to your computer and use it in GitHub Desktop.
Save benbeadle/5185679 to your computer and use it in GitHub Desktop.
Google App Engine + Pusher Webhooks. Check out my blog post (http://benbeadle.com/2013/03/18/google-app-engine-pusher-webhooks) for a more information. I had a hard time figuring out what Google App Engine wanted exactly to be able to receive webhooks from Pusher using their Endpoints API. Here is a working implementation of an Endpoints API for…
# Endpoints handler
- url: /_ah/spi/.*
script: my_api.my_api_service
<html>
<head>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=jsClientLoad"></script>
</head>
<body>
</body>
</html>
function jsClientLoad() {
var ROOT = 'https://your_app_id.appspot.com/_ah/api';
gapi.client.load('my_api', 'v1', function() {
apiLoaded();
}, ROOT);
}
function apiLoaded() {
gapi.client.my_api.pusher.webhook(/*GET/POST Data*/).execute(function(resp) {
//Do something with resp which is a JSON object.
});
}
#Developed by Ben Beadle
#https://gist.github.com/benbeadle/5185679
from google.appengine.ext import endpoints
from protorpc import remote, messages
import pusher
#Personally, I would put the Response and Request classes in another file, but they are placed here for simplicity of demonstration
#The Response Class to send back to Pusher. This really isn't important since Pusher doesn't do anything with this response.
class SuccessResponse(messages.Message):
success = messages.StringField(1, required=True)
#The Event object which Pusher provides an array of
class Event(messages.Message):
name = messages.StringField(1, required=True)
channel = messages.StringField(2, required=True)
#The Request Class pusher sends to you. They send you a timestamp and a list of events.
class PusherRequest(messages.Message):
time_ms = messages.StringField(1, required=True)
events = messages.MessageField(Event, 2, repeated=True)
#Now define the api. Make sure to name the api what you want and add a description
@endpoints.api(name='myapi',version='v1', description='description')
#The class used by the endpoint
class MyApi(remote.Service):
#A method for the pusher webhook
@endpoints.method(PusherRequest, SuccessResponse, name='pusher.webhook', path='pusher/webhook', http_method='POST')
def pusher_webhook(self, request):
#Do something with request.time_ms
for event in request.events:
#Welcome the user when they connect
if event.name=="channel_occupied":
p = pusher.Pusher(app_id=config.pusher_app_id, key=config.pusher_app_key, secret=config.pusher_app_secret)
#Trigger the 'msg' event
p[token].trigger('msg',{'text': 'Thanks for connecting to Pusher!'})
return SuccessResponse(success="Thanks Pusher. Events length: " + str(len(request.events)))
#Now create the service
my_api_service = endpoints.api_server([MyApi], restricted=False)
function pusherError() { /* Do Something */ }
function pusherConnect() { /* Do Something */ }
function pusherDisconnect() { /* Do Something */ }
function pusherMessage() { /* Do Something */ }
var pusher = new Pusher('app_key', {encrypted: true});
pusher.connection.bind( 'error', pusherError);
pusher.connection.bind('state_change', function(states) {
console.log("State: " + states.current);
if(states.current == "connected")
pusherConnect();
else
pusherDisconnect();
});
var channel = pusher.subscribe(token);
channel.bind('msg', function(data) {
pusherMessage("Pusher", data.message);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment