Skip to content

Instantly share code, notes, and snippets.

@Scarygami
Last active December 17, 2015 02:58
Show Gist options
  • Save Scarygami/5539534 to your computer and use it in GitHub Desktop.
Save Scarygami/5539534 to your computer and use it in GitHub Desktop.

There are several triggers you can use for sending timeline updates:

  • Location updates
  • User actions (share/custom/reply)
  • Some "external" trigger coming from your service

But there is one use-case (that I think is rather useful) that isn't covered by those triggers: User triggers an action and you want to send them a series of timeline cards/updates on a certain schedule.

Anything timer related falls into this category ("This card will self-destroy in 10 seconds") and I can think of several examples where this can be useful.

"Egg-timers" with intermediate updates about the current time. For example you could do a Tooth-brush app that sends a quick notification every 30 seconds for 2-3 minutes (or whatever the recommend brushing time is currently) so you remember to switch brushing areas.

Flash cards/quizzes where you only have a certain time to think before the answer is displayed.

Some more ideas that were haunting my mind last night which I can't remember any more...

App Engine offers a very nice service which seems to be perfect for those use-cases, task queues: https://developers.google.com/appengine/docs/python/taskqueue/

The layout is really simple. You have your notification endpoint that is called from the Mirror API when the user triggers an action. In this endpoint you create a series of tasks to update/create/delete timeline items. In the sample code I only handle update/create but you can extend the tasks to match your specific needs.

And the TaskWorker endpoint is then called from the Task Queue with the data you provided and does the actual timeline manipulations.

#!/usr/bin/python
# Copyright (C) 2013 Gerwin Sturm, FoldedSoft e.U.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Example for how to use App Engine Taskqueues to schedule timeline updates"""
__author__ = 'scarygami@gmail.com (Gerwin Sturm)'
import json
import webapp2
from google.appengine.api import taskqueue
class NotifyHandler(webapp2.RequestHandler):
"""
This handler is the one you add as subscription in the Mirror API.
It will be called whenever the user triggers an action.
"""
def post(self):
# Get notification data
data = json.loads(self.request.body)
"""TODO:
1. Verify that data["userToken"] matches a User of our service.
2. Compare data["verifyToken"] to the value stored with our User
3. Check data["userActions"] to see if there is a custom action with our action_id as payload.
4. Get the credentials for the User from datastore
5. Retrieve card data["itemId"] from Mirror API
6. Determine which timeline cards we want to create based on this information
7. Create a new empty timeline card or use an existing one that will be updated with
the scheduled information -> cardId
"""
"""Example of timeline cards we might create:
delay is the number of seconds when the information should be updated, counted from now
contents is the full contents of the timeline card you want to send
(including all fields specified in the Mirror API)
"""
cards = []
cards.append(
{
"delay": 30,
"contents" : {"text": "30 seconds passed"}
}
)
cards.append(
{
"delay": 60,
"contents" : {"text": "1 minute passed"}
}
)
cards.append(
{
"delay": 90,
"contents" : {"text": "1.5 minutes passed"}
}
)
cards.append(
{
"delay": 120,
"contents" : {"text": "Time over!"}
}
)
#Add tasks to the task queue
for card in cards:
taskqueue.add(url="/worker", countdown=card["delay"],
params={"user": data["userToken"], "cardId": cardId, "contents": json.dumps(card["contents"])},
method="POST")
class TaskWorker(webapp2.RequestHandler):
"""
This is the handler that is called from the taskqueue for our scheduled events.
You should consider securing this endpoint from external access:
https://developers.google.com/appengine/docs/python/taskqueue/overview-push#URL_Endpoints
"""
def post(self):
user = self.request.get("user")
cardId = self.request.get("cardId")
contents = json.loads(self.request.get("contents"))
"""TODO:
1. Retrieve credentials for user
2. Call Mirror API to update/create card using the credentials
service.timeline().update(id=cardId, body=contents).execute()
or
service.timeline().insert(body=contents).execute()
"""
app = webapp2.WSGIApplication(
[
("/notify", NotifyHandler),
("/worker", TaskWorker)
],
debug=True
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment