module Server using Markdown using Mux using ..Markov using ..Bot # Middlewares function extract_chatid(app, req) @debug "Looking for chan ID" req req[:params][:chatid] = req[:message][:chat][:id] app(req) end function ignore_if_not_allowed(app, req) if req[:params][:chatid] == Bot.CHAT_ID return app(req) else @debug "Ignoring request" return nothing end end function extract_command(command, parameters...; botname="") if command[1] == '/' command = command[2:end] end function middleware(app, req) if !(:entities in keys(req[:message])) return app(req) end @debug "Looking for commands" command_entities_id = findall(e->e[:type] == "bot_command", req[:message][:entities]) @debug "There are commands" command_entities_id @debug "Looking for commands names" commands = map( e->( req[:message][:text][ (req[:message][:entities][e][:offset]+1):(req[:message][:entities][e][:offset]+req[:message][:entities][e][:length]) ], req[:message][:entities][e]), command_entities_id ) @debug "Commands found" commands first_command_id = findfirst( c->c[1] == ("/" * command) || c[1] .== ("/" * command * "@" * botname), commands ) if isnothing(first_command_id) return app(req) end parameters_values = [] command_offset = commands[first_command_id][2][:offset] command_length = commands[first_command_id][2][:length] end_of_text = split(req[:message][:text][command_offset+command_length+1:end]) req[:command] = Dict() req[:command][:name] = command req[:command][:parameters] = Dict{Symbol, Union{Nothing, String}}(p=>nothing for p in parameters) for (i,param) in enumerate(parameters) if i > length(end_of_text) break end @debug "Parameter attributed" param end_of_text[i] req[:command][:parameters][param] = end_of_text[i] end app(req) end end function branch_to_callback(calback, command) branching_f(req) = if :command in keys(req) @debug "branching" req[:command][:name] command req[:command][:name] == command else @debug "branching" req false end branch(branching_f, calback) end command(command, callback, parameters...; botname="") = stack(extract_command(command, parameters...; botname=botname), branch_to_callback(callback, command)) # Endpoints function show_help(req) """ Hi ! I'm the Markovian bot. Here is what I can do : * /help Prints this list of commands ! * /talk [username [word]] Creates a Markov chain for the given `user` (chosen at random if not set) containing `word` (chosen at random if not set) * /list Lists registered usernames. 🐺 """ end function list_usernames(req) users = join(" * " .* sort(Markov.list_usernames()), "\n") """ Here are the users I know of : """ * users end function talk(req) user = req[:command][:parameters][:user] word = req[:command][:parameters][:word] @debug "Time to talk" user word Markov.make_sentence(user, word) end authentication() = stack(extract_chatid, ignore_if_not_allowed) commands() = stack(command("help", show_help), command("list", list_usernames), command("talk", talk, :user, :word)) application() = mux(stack(authentication(), commands()), _->nothing) end