TL;DR
ErrBot
自作プラグインを作るときにはBotPluginクラスを継承するのですが、このクラスを追いかけていくとBotPluginBase < StoreMixin < MutableMapping  という継承関係にあります。
で、このうちの、StoreMixinで実装されている部分になるのですが、__getitem__()と__setitem__()をオーバーライドしていて、辞書的なアクセスをされた際にはerrbot起動時に参照しているストレージに対して永続データをやり取りできるようになっています。
# -*- coding:utf8 -*-
from errbot import BotPlugin, botcmd
class TodoPlugin(BotPlugin):
    @botcmd
    def set_todo(self, msg, args):
        from_id = str(msg.frm)
        self[from_id] = args
    @botcmd
    def show_todo(self, msg, args):
        from_id = str(msg.frm)
        return self[from_id]
こんな感じで、書くと
set_todo で投げた文字をtodoとして保持してくれ、show_todoと投げると、保持しているtodoを返してくれます。
別のユーザーから同じコマンドを投げられても、別のキーになるので別の値として保持され、ユーザーごとのtodoを持てるようになります。
永続データ管理の注意点
こう書いても動きません。
# -*- coding:utf8 -*-
from errbot import BotPlugin, botcmd
class TodoPlugin(BotPlugin):
    @botcmd
    def set_todo(self, msg, args):
        from_id = str(msg.frm)
        todolist = self[from_id]
        todolist.append(args)
あくまで、BotPluginの実装として動くのみのため、取り出したものに対して何かやっても無意味になります。
# -*- coding:utf8 -*-
from errbot import BotPlugin, botcmd
class TodoPlugin(BotPlugin):
    @botcmd
    def set_todo(self, msg, args):
        from_id = str(msg.frm)
        todolist = self[from_id]
        todolist.append(args)
こんな感じで、一度値を丸ごと取り出して、編集した内容を丸ごとセットする必要があります。 1
使ってみた例
- 
作ってみたtodoデモ
- 一番ストレートに保持したい内容をそのまま保持するケース
 
- 
JpWeatherプラグイン
- あまり大元のAPIに迷惑をかけないように、マスターデータをキャッシュする用(起動時にのみ取り込み直す)
 
- 
Teratail質問監視プラグイン
- 多重通知防止のために、最新の質問IDを保持しているケース
 
- 
コンテキストマネージャーはあって、もうちょっと楽な書き方はあるのですが、今回は割愛 ↩ 

