From 84e5289d2f9d088442f548d67b462892ccc2f0bf Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Sun, 13 Sep 2020 18:19:42 -0700
Subject: [PATCH] Add system.notify() method for notifying user/operator of an
 important event.

---
 src/sbbs3/js_system.c | 61 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c
index e0e5620aa7..fe45f2c99e 100644
--- a/src/sbbs3/js_system.c
+++ b/src/sbbs3/js_system.c
@@ -1589,6 +1589,59 @@ js_put_telegram(JSContext *cx, uintN argc, jsval *arglist)
 	return(JS_TRUE);
 }
 
+static JSBool
+js_notify(JSContext *cx, uintN argc, jsval *arglist)
+{
+	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
+	jsval *argv=JS_ARGV(cx, arglist);
+	int32		usernumber=1;
+	JSString*	js_subj;
+	JSString*	js_msg;
+	char*		subj;
+	char*		msg = NULL;
+	jsrefcount	rc;
+	BOOL		ret;
+
+	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
+
+	js_system_private_t* sys;
+	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
+		return JS_FALSE;
+
+	JS_ValueToInt32(cx,argv[0],&usernumber);
+	if(usernumber<1)
+		usernumber=1;
+
+	if((js_subj=JS_ValueToString(cx, argv[1]))==NULL) 
+		return JS_FALSE;
+
+	if(argc > 2) {
+		if((js_msg=JS_ValueToString(cx, argv[2]))==NULL) 
+			return JS_FALSE;
+
+		JSSTRING_TO_MSTRING(cx, js_msg, msg, NULL);
+		HANDLE_PENDING(cx, msg);
+		if(msg==NULL)
+			return JS_TRUE;
+	}
+
+	JSSTRING_TO_MSTRING(cx, js_subj, subj, NULL);
+	HANDLE_PENDING(cx,subj);
+	if(subj==NULL) {
+		free(msg);
+		return JS_TRUE;
+	}
+
+	rc=JS_SUSPENDREQUEST(cx);
+	ret=notify(sys->cfg, usernumber, subj, msg)==0;
+	free(subj);
+	free(msg);
+	JS_RESUMEREQUEST(cx, rc);
+	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
+
+	return JS_TRUE;
+}
+
 static JSBool
 js_new_user(JSContext *cx, uintN argc, jsval *arglist)
 {
@@ -1905,7 +1958,7 @@ js_killpid(JSContext *cx, uintN argc, jsval *arglist)
 
 static jsSyncMethodSpec js_system_functions[] = {
 #ifndef JSDOOR
-	{"username",		js_username,		1,	JSTYPE_STRING,	JSDOCSTR("number")
+	{"username",		js_username,		1,	JSTYPE_STRING,	JSDOCSTR("user_number")
 	,JSDOCSTR("returns name of user in specified user record <i>number</i>, or empty string if not found")
 	,311
 	},
@@ -1986,6 +2039,10 @@ static jsSyncMethodSpec js_system_functions[] = {
 	,JSDOCSTR("sends a user a short text message, delivered immediately or during next logon")
 	,310
 	},		
+	{"notify",			js_notify,			2,	JSTYPE_BOOLEAN,	JSDOCSTR("user_number, subject [,message_text]")
+	,JSDOCSTR("notify a user or operator via both email and a short text message about an important event")
+	,31801
+	},
 	{"newuser",			js_new_user,		1,	JSTYPE_ALIAS },
 	{"new_user",		js_new_user,		1,	JSTYPE_OBJECT,	JSDOCSTR("name/alias [,client object]")
 	,JSDOCSTR("creates a new user record, returns a new <a href=#User>User</a> object representing the new user account, on success.<br>"
@@ -1993,7 +2050,7 @@ static jsSyncMethodSpec js_system_functions[] = {
 	"client object is used if the argument is omitted)")
 	,310
 	},
-	{"del_user",		js_del_user,		1,	JSTYPE_BOOLEAN,	JSDOCSTR("number")
+	{"del_user",		js_del_user,		1,	JSTYPE_BOOLEAN,	JSDOCSTR("user_number")
 	,JSDOCSTR("delete the specified user account")
 	,316
 	},
-- 
GitLab