Sending Asterisk 1.8 voicemails to multiple emails

Here is the difficult way to send Asterisk 1.8 voicemail notifications to more than one address. The easy way is to define a sendmail alias on your system. However, if you want to allow management of emails through a GUI like FreePBX, that won’t do much good for you.

Disclaimer: I am not a C programmer by trade, I usually work with PHP. But I’m able to pick these things up well enough that we’re using this in production where I work.

With that out of the way, here are the steps. This will recompile only the voicemail module, not the entire Asterisk codebase. This will save the diff file in ~/app_voicemail.diff, apply it, and then recompile and copy the new version over. Some tweaks may be necessary to the compiler arguments, for example if you’re not on an i686 architecture. Asterisk does have a tendency to crash if you start overwriting modules, so make sure you stop your server before copying the file over.

cd ~
wget http://mike.eire.ca/wp-content/uploads/2012/02/app_voicemail.txt
cd /usr/src/asterisk
patch -bp0 < ~/app_voicemail.txt
gcc -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -Wno-missing-prototypes -Wno-missing-declarations -DCRYPTO -fPIC -c -o apps/app_voicemail.o apps/app_voicemail.c
gcc -shared -Xlinker -x -o apps/app_voicemail.so apps/app_voicemail.o
cp /usr/lib/asterisk/modules/app_voicemail.so /usr/lib/asterisk/modules/app_voicemail.so.orig
cp /usr/src/asterisk/apps/app_voicemail.so /usr/lib/asterisk/modules/app_voicemail.so

cd ~ wget http://mike.eire.ca/wp-content/uploads/2012/02/app_voicemail.txt cd /usr/src/asterisk patch -bp0 < ~/app_voicemail.txt gcc -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -Wno-missing-prototypes -Wno-missing-declarations -DCRYPTO -fPIC -c -o apps/app_voicemail.o apps/app_voicemail.c gcc -shared -Xlinker -x -o apps/app_voicemail.so apps/app_voicemail.o cp /usr/lib/asterisk/modules/app_voicemail.so /usr/lib/asterisk/modules/app_voicemail.so.orig cp /usr/src/asterisk/apps/app_voicemail.so /usr/lib/asterisk/modules/app_voicemail.so

That’s all! You should be able to specify multiple email addresses using the pipe character, like the example below.

202 => 1234,Gina Smart,gina@widgets-inc.biz|gina@ginas.home,,attachfmt=wav|delete=yes

For the record, here’s the diff file, against Asterisk 1.8.7.2:

--- apps/app_voicemail.c	2011-09-06 09:48:03.000000000 -0400
+++ apps/app_voicemail.c	2012-02-03 17:42:47.000000000 -0500
@@ -100,6 +100,10 @@
 #include <sys/wait.h>
 #endif
 
+#ifndef AST_MODULE
+#define AST_MODULE "app_voicemail"
+#endif
+
 #include "asterisk/logger.h"
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
@@ -636,7 +640,7 @@
 	char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox id, unique within vm context */
 	char password[80];               /*!< Secret pin code, numbers only */
 	char fullname[80];               /*!< Full name, for directory app */
-	char email[80];                  /*!< E-mail address */
+	char email[256];                 /*!< E-mail address */
 	char *emailsubject;              /*!< E-mail subject */
 	char *emailbody;                 /*!< E-mail body */
 	char pager[80];                  /*!< E-mail address to pager (no attachment) */
@@ -756,12 +760,12 @@
 static int pwdchange = PWDCHANGE_INTERNAL;
 
 #ifdef ODBC_STORAGE
-#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage"
+#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage - multimail patch"
 #else
 # ifdef IMAP_STORAGE
-# define tdesc "Comedian Mail (Voicemail System) with IMAP Storage"
+# define tdesc "Comedian Mail (Voicemail System) with IMAP Storage - multimail patch"
 # else
-# define tdesc "Comedian Mail (Voicemail System)"
+# define tdesc "Comedian Mail (Voicemail System) - multimail patch"
 # endif
 #endif
 
@@ -4527,6 +4531,8 @@
 	struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
 	char *greeting_attachment; 
 	char filename[256];
+	char *tmp;
+	char *email;
 
 	if (!str1 || !str2) {
 		ast_free(str1);
@@ -4589,20 +4595,29 @@
 		fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
 	}
 
-	if (check_mime(vmu->fullname)) {
-		int first_line = 1;
-		char *ptr;
-		ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3);
-		while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
-			*ptr = '\0';
-			fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
-			first_line = 0;
-			/* Substring is smaller, so this will never grow */
-			ast_str_set(&str2, 0, "%s", ptr + 1);
+	if (strchr(vmu->email, '|')) {
+		fprintf(p, "To: ");
+		tmp = ast_strdupa(vmu->email);
+		while ((email = strsep(&tmp, "|"))) {
+			fprintf(p, "%s, ", email);
+ 		}
+		fprintf(p, ENDL);
+ 	} else {
+		if (check_mime(vmu->fullname)) {
+			int first_line = 1;
+			char *ptr;
+			ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3);
+			while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
+				*ptr = '\0';
+				fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
+				first_line = 0;
+				/* Substring is smaller, so this will never grow */
+				ast_str_set(&str2, 0, "%s", ptr + 1);
+			}
+			fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email);
+		} else {
+			fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email);
 		}
-		fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email);
-	} else {
-		fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email);
 	}
 
 	if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {

--- apps/app_voicemail.c 2011-09-06 09:48:03.000000000 -0400 +++ apps/app_voicemail.c 2012-02-03 17:42:47.000000000 -0500 @@ -100,6 +100,10 @@ #include <sys/wait.h> #endif +#ifndef AST_MODULE +#define AST_MODULE "app_voicemail" +#endif + #include "asterisk/logger.h" #include "asterisk/lock.h" #include "asterisk/file.h" @@ -636,7 +640,7 @@ char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox id, unique within vm context */ char password[80]; /*!< Secret pin code, numbers only */ char fullname[80]; /*!< Full name, for directory app */ - char email[80]; /*!< E-mail address */ + char email[256]; /*!< E-mail address */ char *emailsubject; /*!< E-mail subject */ char *emailbody; /*!< E-mail body */ char pager[80]; /*!< E-mail address to pager (no attachment) */ @@ -756,12 +760,12 @@ static int pwdchange = PWDCHANGE_INTERNAL; #ifdef ODBC_STORAGE -#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage" +#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage - multimail patch" #else # ifdef IMAP_STORAGE -# define tdesc "Comedian Mail (Voicemail System) with IMAP Storage" +# define tdesc "Comedian Mail (Voicemail System) with IMAP Storage - multimail patch" # else -# define tdesc "Comedian Mail (Voicemail System)" +# define tdesc "Comedian Mail (Voicemail System) - multimail patch" # endif #endif @@ -4527,6 +4531,8 @@ struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); char *greeting_attachment; char filename[256]; + char *tmp; + char *email; if (!str1 || !str2) { ast_free(str1); @@ -4589,20 +4595,29 @@ fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); } - if (check_mime(vmu->fullname)) { - int first_line = 1; - char *ptr; - ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); - while ((ptr = strchr(ast_str_buffer(str2), ' '))) { - *ptr = '\0'; - fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); - first_line = 0; - /* Substring is smaller, so this will never grow */ - ast_str_set(&str2, 0, "%s", ptr + 1); + if (strchr(vmu->email, '|')) { + fprintf(p, "To: "); + tmp = ast_strdupa(vmu->email); + while ((email = strsep(&tmp, "|"))) { + fprintf(p, "%s, ", email); + } + fprintf(p, ENDL); + } else { + if (check_mime(vmu->fullname)) { + int first_line = 1; + char *ptr; + ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); + while ((ptr = strchr(ast_str_buffer(str2), ' '))) { + *ptr = '\0'; + fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); + first_line = 0; + /* Substring is smaller, so this will never grow */ + ast_str_set(&str2, 0, "%s", ptr + 1); + } + fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); + } else { + fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); } - fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); - } else { - fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); } if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) {

4 Replies to “Sending Asterisk 1.8 voicemails to multiple emails”

Comments are closed.