/* bot/handlers.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <glib.h>
#include "handlers.h"
#include "../expenses/task.h"
int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
xmpp_stanza_t *reply, *query, *name, *version, *text;
const char *ns;
xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
printf("Received version request from %s\n", xmpp_stanza_get_attribute(stanza, "from"));
reply = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(reply, "iq");
xmpp_stanza_set_type(reply, "result");
xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from"));
query = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(query, "query");
ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza));
if (ns) {
xmpp_stanza_set_ns(query, ns);
}
name = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(name, "name");
xmpp_stanza_add_child(query, name);
text = xmpp_stanza_new(ctx);
xmpp_stanza_set_text(text, "libstrophe example bot");
xmpp_stanza_add_child(name, text);
version = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(version, "version");
xmpp_stanza_add_child(query, version);
text = xmpp_stanza_new(ctx);
xmpp_stanza_set_text(text, "1.0");
xmpp_stanza_add_child(version, text);
xmpp_stanza_add_child(reply, query);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
return 1;
}
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
unsigned int lastId;
xmpp_stanza_t *reply, *body, *text;
xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
GString *intext;
GString *replytext;
BotReminder *reminder;
const gchar * from = xmpp_stanza_get_attribute(stanza, "from");
if(!xmpp_stanza_get_child_by_name(stanza, "body")) return 1;
if(!strcmp(xmpp_stanza_get_attribute(stanza, "type"), "error")) return 1;
intext = g_string_new(xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")));
printf("Incoming message from %s: %s\n", from, intext->str);
reply = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(reply, "message");
xmpp_stanza_set_type(reply, xmpp_stanza_get_type(stanza)?xmpp_stanza_get_type(stanza):"chat");
xmpp_stanza_set_attribute(reply, "to", from);
body = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(body, "body");
replytext = g_string_new(NULL);
/* parse and store the message */
if(grammar_parse_string(intext) == 0) {
switch(bot_get_last_command()) {
case BOT_CMD_IN:
case BOT_CMD_OUT:
lastId = (bot_get_last_expense())->id;
g_string_printf(replytext, "OK! Ho salvato l'ultima spesa, id: %u\n", lastId);
break;
case BOT_CMD_REMINDER:
reminder = bot_get_last_reminder();
g_string_append(reminder->from, from);
if(reminder->minutes > 0) {
if(bot_start_task(reminder) != 0) {
g_string_printf(replytext, "Mi dispiace %s ma non posso mandarti un messaggio tra %d minuti, qualcosa non va.\n", strtok(strdup(reminder->from->str), "@"), reminder->minutes);
} else {
g_string_printf(replytext, "Va bene %s, ti mando un messaggio tra %d minuti.\n", strtok(strdup(reminder->from->str), "@"), reminder->minutes);
}
} else {
/* cancel reminder */
bot_cancel_task(from);
g_string_printf(replytext, "Ho cancellato il reminder, %s.\n", strtok(strdup(reminder->from->str), "@"));
}
break;
default:
g_string_printf(replytext, "Non ho riconosciuto il comando: %s", intext->str);
break;
}
} else {
g_string_printf(replytext, "Stavo rosicchiando una ghianda e non ho capito. Che vuol dire \"%s\"?\n%s\n", intext->str, HELPTEXT);
}
text = xmpp_stanza_new(ctx);
xmpp_stanza_set_text(text, replytext->str);
xmpp_stanza_add_child(body, text);
xmpp_stanza_add_child(reply, body);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
g_string_free(replytext, true);
g_string_free(intext, true);
return 1;
}
/* define a handler for connection events */
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
const int error, xmpp_stream_error_t * const stream_error,
void * const userdata)
{
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
if (status == XMPP_CONN_CONNECT) {
xmpp_stanza_t* pres;
fprintf(stderr, "DEBUG: connected\n");
xmpp_handler_add(conn,version_handler, "jabber:iq:version", "iq", NULL, ctx);
xmpp_handler_add(conn,message_handler, NULL, "message", NULL, ctx);
/* Send initial <presence/> so that we appear online to contacts */
pres = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(pres, "presence");
xmpp_send(conn, pres);
xmpp_stanza_release(pres);
}
else {
fprintf(stderr, "DEBUG: disconnected\n");
xmpp_stop(ctx);
}
}
void send_message(xmpp_conn_t * const conn, GString * const from, xmpp_ctx_t * const ctx, const GString *msg)
{
xmpp_stanza_t *reply, *body, *text;
reply = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(reply, "message");
xmpp_stanza_set_type(reply, "chat");
xmpp_stanza_set_attribute(reply, "to", from->str);
body = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(body, "body");
text = xmpp_stanza_new(ctx);
xmpp_stanza_set_text(text, msg->str);
xmpp_stanza_add_child(body, text);
xmpp_stanza_add_child(reply, body);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
}