AppleScript desktop dialer for Asterisk


Asterisk Desktop Dialer

This is an incredibly simple idea – but incredibly useful: a desktop application (written in applescript) where you copy/paste the number you wish to dial, it connects to your local asterisk server via its management interface, and dials the number on your phone.

You’ll need a mac (obviously), a desktop phone (even more obviously), and an asterisk server (most obviously), preferably on your lan, which you can configure to allow network access to the AMI (Asterisk Manager Interface).

First, the script (also available on github):

set clipnumber to (the clipboard as text)
set thenumber to truncateString(clipnumber, 50)
set answer to "OK"

repeat while answer = "OK"
	
	set question to display dialog "Number to Dial:" buttons {"Cancel", "OK"} default button 2 default answer thenumber with icon 1
	set answer to button returned of question
	set thenumber to text returned of question
	
	if answer is equal to "OK" then
		DialOut(thenumber)
		(display dialog "Dialing: " & thenumber buttons {"OK"} giving up after 2)
	end if
	
end repeat

on truncateString(txt, max)
	set txtLength to (length of txt)
	if txtLength > max then
		set txt to (text 1 thru (max - 1) of txt) as string
	end if
	return txt
end truncateString

on cleanString(str, chars)
	set tid to AppleScript's text item delimiters
	repeat with c in chars
		set AppleScript's text item delimiters to {c}
		set chunks to text items of str
		set AppleScript's text item delimiters to ""
		set str to chunks as Unicode text
	end repeat
	set AppleScript's text item delimiters to tid
	return str
end cleanString

-- find : Text (or list of text) to be found
-- replace : Text (or list of text) to replace with
-- subject : Text (or list of text) to be searched
on str_replace(find, replace, subject)
	set prevTIDs to text item delimiters of AppleScript
	set returnList to true
	
	-- This wouldn't make sense (you could have it raise an error instead)
	if class of find is not list and class of replace is list then return subject
	
	if class of find is not list then set find to {find}
	if class of subject is not list then ¬
		set {subject, returnList} to {{subject}, false}
	
	set findCount to count find
	set usingReplaceList to class of replace is list
	
	try
		repeat with i from 1 to (count subject)
			set thisSubject to item i of subject
			
			repeat with n from 1 to findCount
				set text item delimiters of AppleScript to item n of find
				set thisSubject to text items of thisSubject
				
				if usingReplaceList then
					try
						item n of replace
					on error
						"" -- `replace` ran out of items
					end try
				else
					replace
				end if
				
				set text item delimiters of AppleScript to result
				set thisSubject to "" & thisSubject
			end repeat
			
			set item i of subject to thisSubject
		end repeat
	end try
	
	set text item delimiters of AppleScript to prevTIDs
	if not returnList then return beginning of subject
	return subject
end str_replace

on DialOut(telephone)
	set mynumber to "SCCP/53" -- your asterisk extension number, change to SIP or IAX as appropriate
	set username to "admin" -- asterisk manager username
	set passwd to "amp111" -- asterisk manager password
	set remotehost to "192.168.1.101" -- asterisk server ip address
	set context to "from-internal" -- context for outgoing calls
	set numbertocall to my cleanString(telephone, {" ", "-", ")", "(", "."})
	set numbertocall to my str_replace("+", "00", numbertocall)
	set callerid to numbertocall 
	set expectscript to "set timeout 20;
spawn telnet " & remotehost & " 5038;
expect \"Asterisk Call Manager/1.1\";
send \"Action: login
username: " & username & "
secret: " & passwd & "

\";
expect \"Message: Authentication accepted\";
sleep 1;
send \"Action: originate
Exten: " & numbertocall & "
Context: " & context & "
Channel: " & mynumber & "
Priority: 1
Callerid: Outgoing Call <" & callerid & ">

\";
sleep 1;
send \"Action: logoff

\";
"
	-- display dialog expectscript
	set results to do shell script "/usr/bin/expect -c  '" & expectscript & "'"
	-- if (results is not equal to "") then display dialog results
end DialOut

Change the various values to match your configuration (the values I have are mostly defaults for FreePBX). Note that if you’re using Asterisk 1.4, you’ll need to change the expect script from “Asterisk Call Manager/1.1″ to “Asterisk Call Manager/1.0″. Also note that the above is a direct copy/paste of what I use, so it has some other (probably unnecessary) tweaks in there – the most notable being that it pre-populates the number field from the clipboard text.

Next you’ll need to configure asterisk to allow AMI connections from your lan. Open the file /etc/asterisk/manager.conf and change as appropriate. The following is mine:

[general]
enabled = yes
port = 5038
bindaddr = 0.0.0.0
displayconnects=yes ;only effects 1.6+

[admin]
secret = amp111
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
permit=192.168.1.0/255.255.255.0 ; this is important - won't be present by default
read = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate
write = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate

Restart asterisk, save your applescript as an application, and bob is your relative.

Actually, I guess you could do this without a desktop phone and have it trigger a call to your mobile or something …

What’s that they say? Ah yes: This is left as an exercise for the reader. :)

Note: this is adapted from Zed’s script here.

, , , ,

  1. #1 by Jackson on January 18, 2013 - 12:25 am

    Cool idea. I’d like to see this implemented with a url handler, so phone numbers on web pages could be clicked and passed into this dialer application. I might toy with it to try to do that.

    Cheers

(will not be published)


css.php