1. Models
1.1. Conversation
1.1.1. Inherits from db.Expando
1.1.2. Properties
1.1.2.1. user
1.1.2.2. init time
1.1.2.3. last_updated
1.1.2.4. messages (all, including most current)
1.1.2.5. steps_so_far (list)
1.1.2.6. status (either complete, ongoing, or aborted)
1.1.2.7. next_step (the name of the next step)
1.1.2.8. list_shortcut
1.1.2.8.1. the name of the method to call if the user says /list without args
1.1.3. conversation protocol
1.1.3.1. The idea is that you use your conversation object as a long-running transaction, storing whatever intermediate or state data you need as expando properties
1.1.3.2. On your own models, you might provide a "from_conversation" @staticmethod that constructs one of your model objects from a conversation
2. Base handler
2.1. Overrides text_message
2.1.1. On new text_message, looks up conversations to see if the user has an active one
2.1.1.1. if there's no active conversation, falls through to self.unhandled_command
2.1.2. Appends current message to conversation
2.1.3. On function exit, commits conversation
2.1.4. Runs function for next_step
2.1.5. Adds next_step to steps_so_far
2.1.6. Updates last_updated
2.2. Adds a few command
2.2.1. /abort
2.2.1.1. manually ends the current conversation
2.2.2. /replay
2.2.2.1. replays the conversation up to where you are (useful if you accidentally quit your IM client or your browser crashes and you don't feel like hunting through your logs)
2.2.3. maybe /new
2.2.3.1. First steps are called whatever_new
2.2.3.2. /new would then call whatever
2.2.3.3. /new would be smart and mark any existing conversation as aborted (maybe with a setable warn time)
2.2.3.4. Could support partial command names
2.2.4. maybe /help
2.2.4.1. Calls the help_message @staticmethod on all registered responders and passes them the message
2.2.4.2. Can optionally take a responder name for detailed help from just that resonder
2.2.4.3. Can optionally take a command name, so /help list or /help new
2.2.5. maybe /list
2.2.5.1. /list is for functions that give the user a list of available options
2.2.5.2. generically, /list would take the name of some property to list
2.2.5.3. Could support partial list names
2.2.5.4. /list lists would give you all the things you can list
2.2.5.5. In a smart world, /list with no arguments will see if the current conversation has a list_shortcut and then run that
2.3. steps protocol
2.3.1. A step is the step name, followed by _step
2.3.2. A step takes self and the conversation, and a reply_only flag (for /replay)
2.3.3. first step is something followed by _new
2.4. list protocol
2.4.1. it's not uncommon to have something you want to list that you wouldn't necessarily want to list by default
2.4.2. functions that just generate a list of something are whatever_list
2.4.2.1. receives self and the message
2.4.3. Could be conversation aware and check to see if there's a current conversation with list_shortcut set if /list is called with no args. If so, will call the correct list
3. Ideas
3.1. Let classes be registered to handler to handle different /new commands
3.1.1. for example, /new shake or /new task
3.1.2. Have registered classes provide a message for /help
3.1.3. These handlers are called responders
4. Tasks
4.1. Sweeper for complete and aborted tasks
4.2. Sweeper to mark stale tasks as aborted
5. Config
5.1. Conversation timeout
5.1.1. General timeout
5.1.2. Timeout after user signout
5.1.2.1. On user timeout, a task it set to mark all of that user's tasks as aborted if the user doesn't sign back in in the allotted time