| 1 | local st = require "prosody.util.stanza"; |
| 2 | local memory_ns = "http://code.matthewwild.co.uk/riddim/plugins/tell" |
| 3 | local serializer = false; |
| 4 | local tellings = {}; |
| 5 | |
| 6 | function riddim.plugins.tell(bot) |
| 7 | if bot.config.remember_tells then |
| 8 | bot.stream:add_plugin("private"); |
| 9 | serializer = require "json"; --TODO other serializer? |
| 10 | end |
| 11 | |
| 12 | local sameroom = bot.config.tell_in_same_room; |
| 13 | |
| 14 | local function remember() |
| 15 | if serializer then |
| 16 | bot.stream:private_set("tellings", memory_ns, serializer.encode(tellings), function () end); |
| 17 | end |
| 18 | end |
| 19 | |
| 20 | bot:hook("commands/tell", function (command) |
| 21 | if not command.room then |
| 22 | return "This command is only available in groupchats."; |
| 23 | end |
| 24 | if not command.param then |
| 25 | return "If you want me to tell someone something then do so"; |
| 26 | end |
| 27 | |
| 28 | local s, e = command.param:find(" "); |
| 29 | |
| 30 | if not s then |
| 31 | return "if you have nothing to say to "..command.param..", then leave me alone, please"; |
| 32 | end |
| 33 | |
| 34 | local nick = command.param:sub(0, s - 1); |
| 35 | local msg = command.param:sub(s + 1); |
| 36 | |
| 37 | if nick == command.sender.nick then |
| 38 | return "Tell yourself."; |
| 39 | end |
| 40 | |
| 41 | for tmp,_ in pairs(command.room.occupants) do |
| 42 | if tmp == nick then |
| 43 | return "" .. nick .. " is currently online!"; |
| 44 | end |
| 45 | end |
| 46 | |
| 47 | local nick_id = sameroom and command.room.jid .. "/" .. nick or nick; |
| 48 | |
| 49 | if tellings[nick_id] == nil then |
| 50 | tellings[nick_id] = {}; |
| 51 | end |
| 52 | tellings[nick_id][#tellings[nick_id] + 1] = {from=command.sender.nick, msg=msg}; |
| 53 | remember(); |
| 54 | return "Ok!"; |
| 55 | end); |
| 56 | |
| 57 | bot:hook("commands/untell", function (command) |
| 58 | if not command.room then |
| 59 | return "This command is only available in groupchats."; |
| 60 | end |
| 61 | if not command.param then |
| 62 | return "If you changed your mind tell me for who"; |
| 63 | end |
| 64 | |
| 65 | local s, e = command.param:find(" "); |
| 66 | local nick; |
| 67 | local id; |
| 68 | |
| 69 | -- parameter parsing |
| 70 | if not s then |
| 71 | nick = command.param; |
| 72 | id = nil; |
| 73 | else |
| 74 | nick = command.param:sub(0, s - 1); |
| 75 | id = command.param:sub(s + 1); |
| 76 | end |
| 77 | |
| 78 | -- no message for that user |
| 79 | local nick_id = sameroom and command.room.jid .. "/" .. nick or nick; |
| 80 | if not tellings[nick_id] then |
| 81 | return "I have no messages for "..nick; |
| 82 | end |
| 83 | |
| 84 | -- no message id and message for that user |
| 85 | if id == nil then |
| 86 | local response = "I am supposed to relay the following message to "..nick.." :"; |
| 87 | for index,msg in ipairs(tellings[nick_id]) do |
| 88 | response = response .. "\n#"..index.." : "..msg.msg; |
| 89 | end |
| 90 | return response; |
| 91 | end |
| 92 | |
| 93 | -- check the message id is valid |
| 94 | local number = #tellings[nick_id]; |
| 95 | id = tonumber(id) |
| 96 | if id == nil or id < 1 or id > number then |
| 97 | return "I need a valid message #id .. sigh !!\n"..nick.." has "..number.." message(s)"; |
| 98 | end |
| 99 | |
| 100 | if tellings[nick_id][id].from ~= command.sender.nick then |
| 101 | return "you never said that, "..tellings[nick_id][id].from.." did !"; |
| 102 | end |
| 103 | |
| 104 | -- remove the message |
| 105 | if number > 1 then |
| 106 | tellings[nick_id][id] = tellings[nick_id][number]; |
| 107 | tellings[nick_id][number] = nil; |
| 108 | remember(); |
| 109 | return "what was I supposed to tell "..nick.." again ?"; |
| 110 | else |
| 111 | tellings[nick_id] = nil; |
| 112 | remember(); |
| 113 | return "who is "..nick.." anyway ?"; |
| 114 | end |
| 115 | end); |
| 116 | |
| 117 | if serializer then |
| 118 | bot:hook("started", function() -- restore memory |
| 119 | bot.stream:private_get("tellings", memory_ns, function (what) |
| 120 | if what then |
| 121 | local data = tostring(what:get_text()); |
| 122 | if data and #data > 0 then |
| 123 | tellings = serializer.decode(data); |
| 124 | end |
| 125 | end |
| 126 | end); |
| 127 | end); |
| 128 | end |
| 129 | |
| 130 | bot:hook("groupchat/joined", function (room) |
| 131 | room:hook("occupant-joined", function (occupant) |
| 132 | local nick_id = sameroom and room.jid .. "/" .. occupant.nick or occupant.nick; |
| 133 | if(tellings[nick_id] ~= nil) then |
| 134 | for _,msg in ipairs(tellings[nick_id]) do |
| 135 | room:send_message(occupant.nick .. ": Welcome back! " .. msg.from .. " told me to tell you:\n" .. msg.msg); |
| 136 | end |
| 137 | tellings[nick_id] = nil; |
| 138 | remember(); |
| 139 | end |
| 140 | end); |
| 141 | end); |
| 142 | end |