#!/usr/bin/env swipl /* echobot.pl Author: Gimenez, Christian. Copyright (C) 2026 Gimenez, Christian This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . 2026-05-03 */ :- module(echobot, []). /** echobot: Echo bot example. To run this script, set BOTJID and BOTPASS with the JID and password to connect to the server. @author Christian Gimenez @license GPLv3 */ :- license(gplv3). :- use_module(library(xmpp/xmpp)). :- use_module(library(xmpp/xmpp_core)). :- use_module(library(xmpp/xmpp_simple)). :- initialization(main, main). opt_type(d, debug, boolean). opt_help(debug, 'Enable debug mode'). % ---------- % Handlers %! after_connect_handler(+Args: list) % % Handler for after_connect hook. % % This handler sends the chatty presence of the bot. % % @param Args Ignored (no processing to this data). after_connect_handler(_Args) :- send_presence('Echo Bot ready!', [show('chat')]), debug(echobot, 'Echobot connected!', []). % handle_presence(+Args: list) % % The logic used when a presence is received. handle_presence(Args) :- member(from(From), Args), member(to(To), Args), member(status(Text), Args), format(show(Show), args), format('Presence from ~q to ~q: (~q) ~q', [From, To, Show, Text]), !, nl, flush. %! received_presence_handler(+Args: list) % % Handler for received_presence hook. % % Executed when a new presence update stanza is received. This handler only % prints to standard output the update presence. % % # Argument % This is a different from the echobot.pl example. In this case, elements are % already parsed and stored in Args. See xmpp_simple:presence_handler/1 for % more information. % % # Catcihng errors and exceptions % To avoid stoping the program, a catch/3 should be use to process the exception % and avoid propagating it. % % @param Args a list with `[data(XMLParsed), current_state(ClientState)]`. The % order of data and currest_state is not garanteed. received_presence_handler(Args) :- debug(echobot,'Handling presence: ~q', [Args]), catch(handle_presence(Args), Error, debug(chatbot, '!!! Error at handle_presence/1: ~q', [Error])). received_presence_handler(Args) :- !, debug(echobot, 'Failed to handle presence: ~q', [Args]). % receive_message(+Args: list) % % The logic used when recieved the message. receive_message(Args) :- member(from(From), Args), member(body(Text), Args), format(atom(NewText), 'Echo: ~q', [Text]), debug(echobot, 'Sending ~q...', [NewText]), send_message(From, NewText), format('Echo to ~q: ~q', [From, NewText]), nl, flush. %! received_message_handler(+Args: list) % % Handler for the `received_message` hook. % % This handlers is executed when the bot receives a message stanza. It extracts % the from JID and the text message, and sends it back. % % # Argument % This is a different from the echobot.pl example. In this case, elements are % already parsed and stored in Args. See xmpp_simple:message_handler/1 for % more information. % % # Catcihng errors and exceptions % To avoid stoping the program, a catch/3 should be use to process the exception % and avoid propagating it. % % @param Args a list with `[data(XMLParsed), current_state(ClientState)]`. The % order of data and currest_state is not garanteed. received_message_handler(Args) :- debug(echobot, 'Received: ~q', [Args]), catch(receive_message(Args), Error, debug(echobot, '!!! Error at receive_message/1: ~q', [Error])). received_message_handler(Args) :- !, debug(echobot, 'Message handler failed with ~q', [Args]). % ----- enable_debug(Options) :- option(debug(true), Options, false), debug(xmpp), debug(xmpp_auth), debug(xmpp_ping), debug(echobot). get_envdata(JID, Password) :- getenv('BOTJID', JID), getenv('BOTPASS', Password). get_envdata(_, _) :- throw(error(no_envvar_set, context(get_envdata/2, 'Please, set BOTJID and BOTPASS environment variables'))). main(ArgV) :- argv_options(ArgV, _Pos, Options), ignore(enable_debug(Options)), get_envdata(JID, Password), add_hook(after_connect, echobot:after_connect_handler), % The xmpp_simple hooks are set here. add_hook(received_message_simple, echobot:received_message_handler), add_hook(received_presence_simple, echobot:received_presence_handler), connect(JID, Password), write('Press ENTER to quit.'), nl, get_char(_), disconnect.