diff options
| author | 2024-01-12 09:54:14 +0100 | |
|---|---|---|
| committer | 2024-01-12 09:54:14 +0100 | |
| commit | 2af94818377740dad047e1f3c85ce03a3e865ffe (patch) | |
| tree | 0c6717f64f77acae046b85edae379b9e18fb78fc | |
| parent | Avoid invalid actors in mastoapi_status(). (diff) | |
| download | snac2-2af94818377740dad047e1f3c85ce03a3e865ffe.tar.gz snac2-2af94818377740dad047e1f3c85ce03a3e865ffe.tar.xz snac2-2af94818377740dad047e1f3c85ce03a3e865ffe.zip | |
Added support for ntfy notifications. You can configure either a self-hosted server or use the official ntfy.sh, and you have the option to use a private token to protect access and topics.
| -rw-r--r-- | activitypub.c | 42 | ||||
| -rw-r--r-- | data.c | 15 | ||||
| -rw-r--r-- | doc/snac.1 | 6 | ||||
| -rw-r--r-- | html.c | 26 | ||||
| -rw-r--r-- | snac.h | 1 |
5 files changed, 89 insertions, 1 deletions
diff --git a/activitypub.c b/activitypub.c index dc492ca..d937726 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -800,8 +800,23 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 800 | objid = actor; | 800 | objid = actor; |
| 801 | 801 | ||
| 802 | notify_add(snac, type, utype, actor, objid != NULL ? objid : id); | 802 | notify_add(snac, type, utype, actor, objid != NULL ? objid : id); |
| 803 | } | ||
| 804 | 803 | ||
| 804 | /* ntfy */ | ||
| 805 | char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); | ||
| 806 | char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); | ||
| 807 | |||
| 808 | if (!xs_is_null(ntfy_server) && *ntfy_server ) | ||
| 809 | enqueue_ntfy(body, ntfy_server, ntfy_token); | ||
| 810 | |||
| 811 | /* finally, store it in the notification folder */ | ||
| 812 | if (strcmp(type, "Follow") == 0) | ||
| 813 | objid = id; | ||
| 814 | else | ||
| 815 | if (strcmp(utype, "Follow") == 0) | ||
| 816 | objid = actor; | ||
| 817 | |||
| 818 | notify_add(snac, type, utype, actor, objid != NULL ? objid : id); | ||
| 819 | } | ||
| 805 | 820 | ||
| 806 | /** messages **/ | 821 | /** messages **/ |
| 807 | 822 | ||
| @@ -2133,6 +2148,31 @@ void process_queue_item(xs_dict *q_item) | |||
| 2133 | srv_debug(0, xs_fmt("telegram post %d", status)); | 2148 | srv_debug(0, xs_fmt("telegram post %d", status)); |
| 2134 | } | 2149 | } |
| 2135 | else | 2150 | else |
| 2151 | if (strcmp(type, "ntfy") == 0) { | ||
| 2152 | /* send this via ntfy */ | ||
| 2153 | char *ntfy_server = xs_dict_get(q_item, "ntfy_server"); | ||
| 2154 | char *msg = xs_dict_get(q_item, "message"); | ||
| 2155 | char *ntfy_token = xs_dict_get(q_item, "ntfy_token"); | ||
| 2156 | int status = 0; | ||
| 2157 | |||
| 2158 | xs *url = xs_fmt("%s", ntfy_server); | ||
| 2159 | //xs *body = xs_fmt("\"text\":\"%s\"}", msg); | ||
| 2160 | xs *body = xs_fmt("%s", msg); | ||
| 2161 | |||
| 2162 | xs *headers = xs_dict_new(); | ||
| 2163 | headers = xs_dict_append(headers, "content-type", "text/plain"); | ||
| 2164 | // Append the Authorization header only if ntfy_token is not NULL | ||
| 2165 | if (ntfy_token != NULL) { | ||
| 2166 | headers = xs_dict_append(headers, "Authorization", xs_fmt("Bearer %s", ntfy_token)); | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | xs *rsp = xs_http_request("POST", url, headers, | ||
| 2170 | body, strlen(body), &status, NULL, NULL, 0); | ||
| 2171 | rsp = xs_free(rsp); | ||
| 2172 | |||
| 2173 | srv_debug(0, xs_fmt("ntfy post %d", status)); | ||
| 2174 | } | ||
| 2175 | else | ||
| 2136 | if (strcmp(type, "purge") == 0) { | 2176 | if (strcmp(type, "purge") == 0) { |
| 2137 | srv_log(xs_dup("purge start")); | 2177 | srv_log(xs_dup("purge start")); |
| 2138 | 2178 | ||
| @@ -2232,6 +2232,21 @@ void enqueue_telegram(const xs_str *msg, const char *bot, const char *chat_id) | |||
| 2232 | srv_debug(1, xs_fmt("enqueue_telegram %s %s", bot, chat_id)); | 2232 | srv_debug(1, xs_fmt("enqueue_telegram %s %s", bot, chat_id)); |
| 2233 | } | 2233 | } |
| 2234 | 2234 | ||
| 2235 | void enqueue_ntfy(const xs_str *msg, const char *ntfy_server, const char *ntfy_token) | ||
| 2236 | /* enqueues a message to be sent via ntfy */ | ||
| 2237 | { | ||
| 2238 | xs *qmsg = _new_qmsg("ntfy", msg, 0); | ||
| 2239 | char *ntid = xs_dict_get(qmsg, "ntid"); | ||
| 2240 | xs *fn = xs_fmt("%s/queue/%s.json", srv_basedir, ntid); | ||
| 2241 | |||
| 2242 | qmsg = xs_dict_append(qmsg, "ntfy_server", ntfy_server); | ||
| 2243 | qmsg = xs_dict_append(qmsg, "ntfy_token", ntfy_token); | ||
| 2244 | |||
| 2245 | |||
| 2246 | qmsg = _enqueue_put(fn, qmsg); | ||
| 2247 | |||
| 2248 | srv_debug(1, xs_fmt("enqueue_ntfy %s %s", ntfy_server, ntfy_token)); | ||
| 2249 | } | ||
| 2235 | 2250 | ||
| 2236 | void enqueue_message(snac *snac, const xs_dict *msg) | 2251 | void enqueue_message(snac *snac, const xs_dict *msg) |
| 2237 | /* enqueues an output message */ | 2252 | /* enqueues an output message */ |
| @@ -93,6 +93,12 @@ a Telegram channel and a bot for this; the process is rather | |||
| 93 | cumbersome but it's documented everywhere. The Bot API key | 93 | cumbersome but it's documented everywhere. The Bot API key |
| 94 | is a long string of alphanumeric characters and the chat id | 94 | is a long string of alphanumeric characters and the chat id |
| 95 | is a big, negative number. | 95 | is a big, negative number. |
| 96 | .It ntfy notifications | ||
| 97 | To enable notifications via ntfy (both self-hosted or | ||
| 98 | standard ntfy.sh server), fill the two provided | ||
| 99 | fields (ntfy server/topic and, if protected, the token). | ||
| 100 | You need to refer to the https://ntfy.sh web site for | ||
| 101 | more information on this process. | ||
| 96 | .It Maximum days to keep posts | 102 | .It Maximum days to keep posts |
| 97 | This numeric value specifies the number of days to pass before | 103 | This numeric value specifies the number of days to pass before |
| 98 | posts (yours and others') will be purged. This value overrides | 104 | posts (yours and others') will be purged. This value overrides |
| @@ -853,6 +853,14 @@ xs_html *html_top_controls(snac *snac) | |||
| 853 | if (xs_is_null(telegram_chat_id)) | 853 | if (xs_is_null(telegram_chat_id)) |
| 854 | telegram_chat_id = ""; | 854 | telegram_chat_id = ""; |
| 855 | 855 | ||
| 856 | char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); | ||
| 857 | if (xs_is_null(ntfy_server)) | ||
| 858 | ntfy_server = ""; | ||
| 859 | |||
| 860 | char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); | ||
| 861 | if (xs_is_null(ntfy_token)) | ||
| 862 | ntfy_token = ""; | ||
| 863 | |||
| 856 | char *purge_days = xs_dict_get(snac->config, "purge_days"); | 864 | char *purge_days = xs_dict_get(snac->config, "purge_days"); |
| 857 | if (!xs_is_null(purge_days) && xs_type(purge_days) == XSTYPE_NUMBER) | 865 | if (!xs_is_null(purge_days) && xs_type(purge_days) == XSTYPE_NUMBER) |
| 858 | purge_days = (char *)xs_number_str(purge_days); | 866 | purge_days = (char *)xs_number_str(purge_days); |
| @@ -947,6 +955,20 @@ xs_html *html_top_controls(snac *snac) | |||
| 947 | xs_html_attr("value", telegram_chat_id), | 955 | xs_html_attr("value", telegram_chat_id), |
| 948 | xs_html_attr("placeholder", "Chat id"))), | 956 | xs_html_attr("placeholder", "Chat id"))), |
| 949 | xs_html_tag("p", | 957 | xs_html_tag("p", |
| 958 | xs_html_text(L("ntfy notifications (ntfy server and token):")), | ||
| 959 | xs_html_sctag("br", NULL), | ||
| 960 | xs_html_sctag("input", | ||
| 961 | xs_html_attr("type", "text"), | ||
| 962 | xs_html_attr("name", "ntfy_server"), | ||
| 963 | xs_html_attr("value", ntfy_server), | ||
| 964 | xs_html_attr("placeholder", "ntfy server - full URL (example: https://ntfy.sh/YourTopic)")), | ||
| 965 | xs_html_text(" "), | ||
| 966 | xs_html_sctag("input", | ||
| 967 | xs_html_attr("type", "text"), | ||
| 968 | xs_html_attr("name", "ntfy_token"), | ||
| 969 | xs_html_attr("value", ntfy_token), | ||
| 970 | xs_html_attr("placeholder", "ntfy token - if needed"))), | ||
| 971 | xs_html_tag("p", | ||
| 950 | xs_html_text(L("Maximum days to keep posts (0: server settings):")), | 972 | xs_html_text(L("Maximum days to keep posts (0: server settings):")), |
| 951 | xs_html_sctag("br", NULL), | 973 | xs_html_sctag("br", NULL), |
| 952 | xs_html_sctag("input", | 974 | xs_html_sctag("input", |
| @@ -2890,6 +2912,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, | |||
| 2890 | snac.config = xs_dict_set(snac.config, "telegram_bot", v); | 2912 | snac.config = xs_dict_set(snac.config, "telegram_bot", v); |
| 2891 | if ((v = xs_dict_get(p_vars, "telegram_chat_id")) != NULL) | 2913 | if ((v = xs_dict_get(p_vars, "telegram_chat_id")) != NULL) |
| 2892 | snac.config = xs_dict_set(snac.config, "telegram_chat_id", v); | 2914 | snac.config = xs_dict_set(snac.config, "telegram_chat_id", v); |
| 2915 | if ((v = xs_dict_get(p_vars, "ntfy_server")) != NULL) | ||
| 2916 | snac.config = xs_dict_set(snac.config, "ntfy_server", v); | ||
| 2917 | if ((v = xs_dict_get(p_vars, "ntfy_token")) != NULL) | ||
| 2918 | snac.config = xs_dict_set(snac.config, "ntfy_token", v); | ||
| 2893 | if ((v = xs_dict_get(p_vars, "purge_days")) != NULL) { | 2919 | if ((v = xs_dict_get(p_vars, "purge_days")) != NULL) { |
| 2894 | xs *days = xs_number_new(atof(v)); | 2920 | xs *days = xs_number_new(atof(v)); |
| 2895 | snac.config = xs_dict_set(snac.config, "purge_days", days); | 2921 | snac.config = xs_dict_set(snac.config, "purge_days", days); |
| @@ -204,6 +204,7 @@ void enqueue_output(snac *snac, xs_dict *msg, xs_str *inbox, int retries, int p_ | |||
| 204 | void enqueue_output_by_actor(snac *snac, xs_dict *msg, const xs_str *actor, int retries); | 204 | void enqueue_output_by_actor(snac *snac, xs_dict *msg, const xs_str *actor, int retries); |
| 205 | void enqueue_email(xs_str *msg, int retries); | 205 | void enqueue_email(xs_str *msg, int retries); |
| 206 | void enqueue_telegram(const xs_str *msg, const char *bot, const char *chat_id); | 206 | void enqueue_telegram(const xs_str *msg, const char *bot, const char *chat_id); |
| 207 | void enqueue_ntfy(const xs_str *msg, const char *ntfy_server, const char *ntfy_token); | ||
| 207 | void enqueue_message(snac *snac, const xs_dict *msg); | 208 | void enqueue_message(snac *snac, const xs_dict *msg); |
| 208 | void enqueue_close_question(snac *user, const char *id, int end_secs); | 209 | void enqueue_close_question(snac *user, const char *id, int end_secs); |
| 209 | void enqueue_request_replies(snac *user, const char *id); | 210 | void enqueue_request_replies(snac *user, const char *id); |