[Asterisk-Dev] app_queue.c patch to run macro on answer

Conrad Wood asterisk at conradwood.net
Mon Jan 3 19:24:06 MST 2005


Hi there,

I wrote a patch to make app_queue run a macro when an agent answers a
call from the queue.

Why? So that I can run an agi script with the agent's name and
pre-select the caller in the agents database in order to save him
searching by companyname/personname/postcode/whatever to find the
clients' details.

To activate it, the Queue command needs to be invoked with a new option:
'M' (similarity to the Dial app option intentional).
The macro name is specified in queues.conf as "connectmacro=<macroname>"
I run it on our small (2x bri) asterisk @ work and so far it seems to
work well.

Is anyone available to test/comment? It's my first patch to asterisk so
it's quite likely that I missed something ;( Some guidance would be
appreciated.

patch is against asterisk-1.0.1 and (also) available at
http://www.conradwood.net/patch.txt

A CC: to asterisk at conradwood.net of the reply would be most appreciated.

Kind Regards,

Conrad Wood





-------------- next part --------------
--- /tmp/asterisk-1.0.1//./apps/app_queue.c	2004-09-29 15:06:59.000000000 +0100
+++ ./apps/app_queue.c	2005-01-04 02:10:15.000000000 +0000
@@ -203,6 +203,7 @@
 	int callscompletedinsl;         /* Number of queue calls answererd with servicelevel*/
 	char monfmt[8];                 /* Format to use when recording calls */
 	int monjoin;                    /* Should we join the two files when we are done with the call */
+	char connectmacro[80]; /* the macro to execute on agent-answering-call */
 	char sound_next[80];            /* Sound file: "Your call is now first in line" (def. queue-youarenext) */
 	char sound_thereare[80];        /* Sound file: "There are currently" (def. queue-thereare) */
 	char sound_calls[80];           /* Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
@@ -1006,6 +1007,8 @@
 
 static int try_calling(struct queue_ent *qe, char *options, char *announceoverride, char *url, int *go_on)
 {
+	char macroname[256]="";
+	void *app = NULL;
 	struct member *cur;
 	struct localuser *outgoing=NULL, *tmp = NULL;
 	int to;
@@ -1030,12 +1033,17 @@
 	time_t callstart;
 	time_t now;
 	struct ast_bridge_config config;
+
 	/* Hold the lock while we setup the outgoing calls */
 	ast_mutex_lock(&qe->parent->lock);
 	if (option_debug)
 		ast_log(LOG_DEBUG, "%s is trying to call a queue member.\n", 
 							qe->chan->name);
 	strncpy(queuename, qe->parent->name, sizeof(queuename) - 1);
+	/* not entirely sure, but _I_think_ I need  to copy it because the queue struct might
+	 be freed if another thread reloads the queue configuration. So I  copy  it whilst locked, just in case
+	*/
+	strncpy(macroname, qe->parent->connectmacro, sizeof(macroname) - 1);
 	time(&now);
 	cur = qe->parent->members;
 	if (!ast_strlen_zero(qe->announce))
@@ -1138,6 +1146,25 @@
 		/* Ah ha!  Someone answered within the desired timeframe.  Of course after this
 		   we will always return with -1 so that it is hung up properly after the 
 		   conversation.  */
+
+		/* Firstly, check if the Queue App was started with M option to run a macro */
+		if ( (options) && (strchr(options,'M')) ) {
+			/* bail out if there's no macro defined in queues.conf for this queue.
+			   use the connectmacro= directive to define one - see reload  section
+			   the macroname was copied from the queue struct earlier whilst we
+			   had the lock for it.
+			*/
+			if (strlen(macroname) == 0) {
+				ast_log(LOG_WARNING,"Please define \"connectmacro\" for queue %s in queues.conf",queuename);
+			} else {
+				/* run the macro */
+				app = pbx_findapp("Macro");
+				if (app) {
+					res = pbx_exec(peer, app, macroname, 1);
+				}
+			}
+		}
+
 		qe->handled++;
 		if (!strcmp(qe->chan->type,"Zap")) {
 			if (tmp->dataquality) zapx = 0;
@@ -1783,6 +1810,7 @@
 				q->servicelevel = 0;
 				q->wrapuptime = 0;
 				free_members(q, 0);
+				q->connectmacro[0]='\0'; /* Default - connect macro is empty string */
 				q->moh[0] = '\0';
 				q->announce[0] = '\0';
 				q->context[0] = '\0';
@@ -1833,6 +1861,9 @@
 						}
 					} else if (!strcasecmp(var->name, "music")) {
 						strncpy(q->moh, var->value, sizeof(q->moh) - 1);
+					} else if (!strcasecmp(var->name, "connectmacro")) {
+						/* set connect macro for M option */
+						strncpy(q->connectmacro, var->value, sizeof(q->connectmacro) - 1);
 					} else if (!strcasecmp(var->name, "announce")) {
 						strncpy(q->announce, var->value, sizeof(q->announce) - 1);
 					} else if (!strcasecmp(var->name, "context")) {


More information about the asterisk-dev mailing list