summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--activitypub.c241
1 files changed, 124 insertions, 117 deletions
diff --git a/activitypub.c b/activitypub.c
index 9951f39..d35a909 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -486,6 +486,109 @@ void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list *
486} 486}
487 487
488 488
489void notify(snac *snac, const char *type, const char *utype, const char *actor, const xs_dict *msg)
490/* notifies the user of relevant events */
491{
492 if (strcmp(type, "Create") == 0) {
493 /* only notify of notes specifically for us */
494 xs *rcpts = recipient_list(snac, msg, 0);
495
496 if (xs_list_in(rcpts, snac->actor) == -1)
497 return;
498 }
499
500 if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") != 0)
501 return;
502
503 /* get the object id */
504 const char *objid = xs_dict_get(msg, "object");
505
506 if (xs_type(objid) == XSTYPE_DICT)
507 objid = xs_dict_get(objid, "id");
508 else
509 objid = xs_dict_get(msg, "id");
510
511 if (strcmp(type, "Like") == 0 || strcmp(type, "Announce") == 0) {
512 /* if it's not an admiration about something by us, done */
513 if (xs_is_null(objid) || !xs_startswith(objid, snac->actor))
514 return;
515 }
516
517 /* user will love to know about this! */
518
519 /* prepare message body */
520 xs *body = xs_fmt("User : @%s@%s\n",
521 xs_dict_get(snac->config, "uid"),
522 xs_dict_get(srv_config, "host")
523 );
524
525 if (strcmp(utype, "(null)") != 0) {
526 xs *s1 = xs_fmt("Type : %s + %s\n", type, utype);
527 body = xs_str_cat(body, s1);
528 }
529 else {
530 xs *s1 = xs_fmt("Type : %s\n", type);
531 body = xs_str_cat(body, s1);
532 }
533
534 {
535 xs *s1 = xs_fmt("Actor : %s\n", actor);
536 body = xs_str_cat(body, s1);
537 }
538
539 if (objid != NULL) {
540 xs *s1 = xs_fmt("Object: %s\n", objid);
541 body = xs_str_cat(body, s1);
542 }
543
544 /* email */
545
546 const char *email = "[disabled by admin]";
547
548 if (xs_type(xs_dict_get(srv_config, "disable_email_notifications")) != XSTYPE_TRUE) {
549 email = xs_dict_get(snac->config_o, "email");
550 if (xs_is_null(email)) {
551 email = xs_dict_get(snac->config, "email");
552
553 if (xs_is_null(email))
554 email = "[empty]";
555 }
556 }
557
558 if (*email != '\0' && *email != '[') {
559 snac_debug(snac, 1, xs_fmt("email notify %s %s %s", type, utype, actor));
560
561 xs *subject = xs_fmt("snac notify for @%s@%s",
562 xs_dict_get(snac->config, "uid"), xs_dict_get(srv_config, "host"));
563 xs *from = xs_fmt("snac-daemon <snac-daemon@%s>", xs_dict_get(srv_config, "host"));
564 xs *header = xs_fmt(
565 "From: %s\n"
566 "To: %s\n"
567 "Subject: %s\n"
568 "\n",
569 from, email, subject);
570
571 xs *email_body = xs_fmt("%s%s", header, body);
572
573 enqueue_email(email_body, 0);
574 }
575
576 /* telegram */
577
578 char *bot = xs_dict_get(snac->config, "telegram_bot");
579 char *chat_id = xs_dict_get(snac->config, "telegram_chat_id");
580
581 if (!xs_is_null(bot) && !xs_is_null(chat_id) && *bot && *chat_id)
582 enqueue_telegram(body, bot, chat_id);
583
584 /* finally, store it in the notification folder */
585 if (strcmp(type, "Follow") == 0)
586 objid = xs_dict_get(msg, "id");
587
588 notify_add(snac, type, utype, actor, objid);
589}
590
591
489/** messages **/ 592/** messages **/
490 593
491xs_dict *msg_base(snac *snac, const char *type, const char *id, 594xs_dict *msg_base(snac *snac, const char *type, const char *id,
@@ -1070,6 +1173,8 @@ int update_question(snac *user, const char *id)
1070 if (strcmp(now, end_time) >= 0) { 1173 if (strcmp(now, end_time) >= 0) {
1071 xs *et = xs_dup(end_time); 1174 xs *et = xs_dup(end_time);
1072 msg = xs_dict_set(msg, "closed", et); 1175 msg = xs_dict_set(msg, "closed", et);
1176
1177 notify(user, "Update", "Question", user->actor, msg);
1073 } 1178 }
1074 } 1179 }
1075 1180
@@ -1093,107 +1198,6 @@ int update_question(snac *user, const char *id)
1093} 1198}
1094 1199
1095 1200
1096void notify(snac *snac, xs_str *type, xs_str *utype, xs_str *actor, xs_dict *msg)
1097/* notifies the user of relevant events */
1098{
1099 if (strcmp(type, "Create") == 0) {
1100 /* only notify of notes specifically for us */
1101 xs *rcpts = recipient_list(snac, msg, 0);
1102
1103 if (xs_list_in(rcpts, snac->actor) == -1)
1104 return;
1105 }
1106
1107 if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") != 0)
1108 return;
1109
1110 /* get the object id */
1111 const char *objid = xs_dict_get(msg, "object");
1112
1113 if (xs_type(objid) == XSTYPE_DICT)
1114 objid = xs_dict_get(objid, "id");
1115
1116 if (strcmp(type, "Like") == 0 || strcmp(type, "Announce") == 0) {
1117 /* if it's not an admiration about something by us, done */
1118 if (xs_is_null(objid) || !xs_startswith(objid, snac->actor))
1119 return;
1120 }
1121
1122 /* user will love to know about this! */
1123
1124 /* prepare message body */
1125 xs *body = xs_fmt("User : @%s@%s\n",
1126 xs_dict_get(snac->config, "uid"),
1127 xs_dict_get(srv_config, "host")
1128 );
1129
1130 if (strcmp(utype, "(null)") != 0) {
1131 xs *s1 = xs_fmt("Type : %s + %s\n", type, utype);
1132 body = xs_str_cat(body, s1);
1133 }
1134 else {
1135 xs *s1 = xs_fmt("Type : %s\n", type);
1136 body = xs_str_cat(body, s1);
1137 }
1138
1139 {
1140 xs *s1 = xs_fmt("Actor : %s\n", actor);
1141 body = xs_str_cat(body, s1);
1142 }
1143
1144 if (objid != NULL) {
1145 xs *s1 = xs_fmt("Object: %s\n", objid);
1146 body = xs_str_cat(body, s1);
1147 }
1148
1149 /* email */
1150
1151 const char *email = "[disabled by admin]";
1152
1153 if (xs_type(xs_dict_get(srv_config, "disable_email_notifications")) != XSTYPE_TRUE) {
1154 email = xs_dict_get(snac->config_o, "email");
1155 if (xs_is_null(email)) {
1156 email = xs_dict_get(snac->config, "email");
1157
1158 if (xs_is_null(email))
1159 email = "[empty]";
1160 }
1161 }
1162
1163 if (*email != '\0' && *email != '[') {
1164 snac_debug(snac, 1, xs_fmt("email notify %s %s %s", type, utype, actor));
1165
1166 xs *subject = xs_fmt("snac notify for @%s@%s",
1167 xs_dict_get(snac->config, "uid"), xs_dict_get(srv_config, "host"));
1168 xs *from = xs_fmt("snac-daemon <snac-daemon@%s>", xs_dict_get(srv_config, "host"));
1169 xs *header = xs_fmt(
1170 "From: %s\n"
1171 "To: %s\n"
1172 "Subject: %s\n"
1173 "\n",
1174 from, email, subject);
1175
1176 xs *email_body = xs_fmt("%s%s", header, body);
1177
1178 enqueue_email(email_body, 0);
1179 }
1180
1181 /* telegram */
1182
1183 char *bot = xs_dict_get(snac->config, "telegram_bot");
1184 char *chat_id = xs_dict_get(snac->config, "telegram_chat_id");
1185
1186 if (!xs_is_null(bot) && !xs_is_null(chat_id) && *bot && *chat_id)
1187 enqueue_telegram(body, bot, chat_id);
1188
1189 /* finally, store it in the notification folder */
1190 if (strcmp(type, "Follow") == 0)
1191 objid = xs_dict_get(msg, "id");
1192
1193 notify_add(snac, type, utype, actor, objid);
1194}
1195
1196
1197/** queues **/ 1201/** queues **/
1198 1202
1199int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) 1203int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
@@ -1270,7 +1274,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1270 return 1; 1274 return 1;
1271 } 1275 }
1272 1276
1273 if (strcmp(type, "Follow") == 0) { 1277 if (strcmp(type, "Follow") == 0) { /** **/
1274 if (!follower_check(snac, actor)) { 1278 if (!follower_check(snac, actor)) {
1275 xs *f_msg = xs_dup(msg); 1279 xs *f_msg = xs_dup(msg);
1276 xs *reply = msg_accept(snac, f_msg, actor); 1280 xs *reply = msg_accept(snac, f_msg, actor);
@@ -1294,8 +1298,8 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1294 snac_log(snac, xs_fmt("repeated 'Follow' from %s", actor)); 1298 snac_log(snac, xs_fmt("repeated 'Follow' from %s", actor));
1295 } 1299 }
1296 else 1300 else
1297 if (strcmp(type, "Undo") == 0) { 1301 if (strcmp(type, "Undo") == 0) { /** **/
1298 if (strcmp(utype, "Follow") == 0) { 1302 if (strcmp(utype, "Follow") == 0) { /** **/
1299 if (valid_status(follower_del(snac, actor))) { 1303 if (valid_status(follower_del(snac, actor))) {
1300 snac_log(snac, xs_fmt("no longer following us %s", actor)); 1304 snac_log(snac, xs_fmt("no longer following us %s", actor));
1301 do_notify = 1; 1305 do_notify = 1;
@@ -1307,11 +1311,11 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1307 snac_debug(snac, 1, xs_fmt("ignored 'Undo' for object type '%s'", utype)); 1311 snac_debug(snac, 1, xs_fmt("ignored 'Undo' for object type '%s'", utype));
1308 } 1312 }
1309 else 1313 else
1310 if (strcmp(type, "Create") == 0) { 1314 if (strcmp(type, "Create") == 0) { /** **/
1311 if (is_muted(snac, actor)) 1315 if (is_muted(snac, actor))
1312 snac_log(snac, xs_fmt("ignored 'Create' + '%s' from muted actor %s", utype, actor)); 1316 snac_log(snac, xs_fmt("ignored 'Create' + '%s' from muted actor %s", utype, actor));
1313 1317
1314 if (strcmp(utype, "Note") == 0) { 1318 if (strcmp(utype, "Note") == 0) { /** **/
1315 char *id = xs_dict_get(object, "id"); 1319 char *id = xs_dict_get(object, "id");
1316 char *in_reply_to = xs_dict_get(object, "inReplyTo"); 1320 char *in_reply_to = xs_dict_get(object, "inReplyTo");
1317 xs *wrk = NULL; 1321 xs *wrk = NULL;
@@ -1330,7 +1334,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1330 update_question(snac, in_reply_to); 1334 update_question(snac, in_reply_to);
1331 } 1335 }
1332 else 1336 else
1333 if (strcmp(utype, "Question") == 0) { 1337 if (strcmp(utype, "Question") == 0) { /** **/
1334 char *id = xs_dict_get(object, "id"); 1338 char *id = xs_dict_get(object, "id");
1335 1339
1336 if (timeline_add(snac, id, object)) 1340 if (timeline_add(snac, id, object))
@@ -1340,8 +1344,8 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1340 snac_debug(snac, 1, xs_fmt("ignored 'Create' for object type '%s'", utype)); 1344 snac_debug(snac, 1, xs_fmt("ignored 'Create' for object type '%s'", utype));
1341 } 1345 }
1342 else 1346 else
1343 if (strcmp(type, "Accept") == 0) { 1347 if (strcmp(type, "Accept") == 0) { /** **/
1344 if (strcmp(utype, "Follow") == 0) { 1348 if (strcmp(utype, "Follow") == 0) { /** **/
1345 if (following_check(snac, actor)) { 1349 if (following_check(snac, actor)) {
1346 following_add(snac, actor, msg); 1350 following_add(snac, actor, msg);
1347 snac_log(snac, xs_fmt("confirmed follow from %s", actor)); 1351 snac_log(snac, xs_fmt("confirmed follow from %s", actor));
@@ -1353,7 +1357,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1353 snac_debug(snac, 1, xs_fmt("ignored 'Accept' for object type '%s'", utype)); 1357 snac_debug(snac, 1, xs_fmt("ignored 'Accept' for object type '%s'", utype));
1354 } 1358 }
1355 else 1359 else
1356 if (strcmp(type, "Like") == 0) { 1360 if (strcmp(type, "Like") == 0) { /** **/
1357 if (xs_type(object) == XSTYPE_DICT) 1361 if (xs_type(object) == XSTYPE_DICT)
1358 object = xs_dict_get(object, "id"); 1362 object = xs_dict_get(object, "id");
1359 1363
@@ -1362,7 +1366,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1362 do_notify = 1; 1366 do_notify = 1;
1363 } 1367 }
1364 else 1368 else
1365 if (strcmp(type, "Announce") == 0) { 1369 if (strcmp(type, "Announce") == 0) { /** **/
1366 xs *a_msg = NULL; 1370 xs *a_msg = NULL;
1367 xs *wrk = NULL; 1371 xs *wrk = NULL;
1368 1372
@@ -1393,7 +1397,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1393 snac_log(snac, xs_fmt("error requesting 'Announce' object %s", object)); 1397 snac_log(snac, xs_fmt("error requesting 'Announce' object %s", object));
1394 } 1398 }
1395 else 1399 else
1396 if (strcmp(type, "Update") == 0) { 1400 if (strcmp(type, "Update") == 0) { /** **/
1397 if (strcmp(utype, "Person") == 0) { 1401 if (strcmp(utype, "Person") == 0) {
1398 actor_add(actor, xs_dict_get(msg, "object")); 1402 actor_add(actor, xs_dict_get(msg, "object"));
1399 timeline_touch(snac); 1403 timeline_touch(snac);
@@ -1401,7 +1405,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1401 snac_log(snac, xs_fmt("updated actor %s", actor)); 1405 snac_log(snac, xs_fmt("updated actor %s", actor));
1402 } 1406 }
1403 else 1407 else
1404 if (strcmp(utype, "Note") == 0) { 1408 if (strcmp(utype, "Note") == 0) { /** **/
1405 const char *id = xs_dict_get(object, "id"); 1409 const char *id = xs_dict_get(object, "id");
1406 1410
1407 object_add_ow(id, object); 1411 object_add_ow(id, object);
@@ -1410,7 +1414,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1410 snac_log(snac, xs_fmt("updated post %s", id)); 1414 snac_log(snac, xs_fmt("updated post %s", id));
1411 } 1415 }
1412 else 1416 else
1413 if (strcmp(utype, "Question") == 0) { 1417 if (strcmp(utype, "Question") == 0) { /** **/
1414 const char *id = xs_dict_get(object, "id"); 1418 const char *id = xs_dict_get(object, "id");
1415 const char *closed = xs_dict_get(object, "closed"); 1419 const char *closed = xs_dict_get(object, "closed");
1416 1420
@@ -1418,12 +1422,15 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1418 timeline_touch(snac); 1422 timeline_touch(snac);
1419 1423
1420 snac_log(snac, xs_fmt("%s poll %s", closed == NULL ? "updated" : "closed", id)); 1424 snac_log(snac, xs_fmt("%s poll %s", closed == NULL ? "updated" : "closed", id));
1425
1426 if (closed != NULL)
1427 do_notify = 1;
1421 } 1428 }
1422 else 1429 else
1423 snac_log(snac, xs_fmt("ignored 'Update' for object type '%s'", utype)); 1430 snac_log(snac, xs_fmt("ignored 'Update' for object type '%s'", utype));
1424 } 1431 }
1425 else 1432 else
1426 if (strcmp(type, "Delete") == 0) { 1433 if (strcmp(type, "Delete") == 0) { /** **/
1427 if (xs_type(object) == XSTYPE_DICT) 1434 if (xs_type(object) == XSTYPE_DICT)
1428 object = xs_dict_get(object, "id"); 1435 object = xs_dict_get(object, "id");
1429 1436
@@ -1433,11 +1440,11 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1433 snac_debug(snac, 1, xs_fmt("ignored 'Delete' for unknown object %s", object)); 1440 snac_debug(snac, 1, xs_fmt("ignored 'Delete' for unknown object %s", object));
1434 } 1441 }
1435 else 1442 else
1436 if (strcmp(type, "Pong") == 0) { 1443 if (strcmp(type, "Pong") == 0) { /** **/
1437 snac_log(snac, xs_fmt("'Pong' received from %s", actor)); 1444 snac_log(snac, xs_fmt("'Pong' received from %s", actor));
1438 } 1445 }
1439 else 1446 else
1440 if (strcmp(type, "Ping") == 0) { 1447 if (strcmp(type, "Ping") == 0) { /** **/
1441 snac_log(snac, xs_fmt("'Ping' requested from %s", actor)); 1448 snac_log(snac, xs_fmt("'Ping' requested from %s", actor));
1442 1449
1443 xs *rsp = msg_pong(snac, actor, xs_dict_get(msg, "id")); 1450 xs *rsp = msg_pong(snac, actor, xs_dict_get(msg, "id"));