= Skype for Asterisk Automation and User Interface =
[[TOC]]
[[Image(skype-asterisk.png,right)]]
This product is contributed to the Asterisk Community by [http://pbxware.ru PBXWare.ru]. It is distributed under the GNU GPL.
Asterisk Skype GUI is a lightweight product pluggable into any asterisk installation. Its purpose is to automate calls to/from Skype and provide easy to use WEB interface to manage skype callers. The product was inspired by [http://ssokol.blogspot.com/2009/09/automatic-asterisk-extensions-for-skype.html Steven Sokol], product manager at Digium.
Skype for Asterisk channel license is available directly from [http://store.digium.com/productview.php?product_code=1SFA0001 Digium] or from [mailto:request@pbxware.ru?subject=SFA%20order us].
Screenshots:[[BR]]
[[Image(accounts.png,10%)]]
[[Image(modify_account.png,10%)]]
[[Image(add_account.png,10%)]]
== Features ==
* Easy to install.
* Works with any any Asterisk version.
* Ability to call Skype users by number extension.
* Automatic generation of extensions for new skype callers.
* Lightweight WEB 2.0 interface to manage Skype callers and corresponding accounts (written in [http://en.wikipedia.org/wiki/Lua_(programming_language) Lua]).
== Installation ==
Installation is easy. The installation package comes with all dependencies included as sources. When you invoke install script it unpacks, compiles and installs all the deps to the specified directory. See below for deetails.
=== Dependencies ===
* System libs and headers: readline (readline-devel), libtool.(libtool)
* SQLite3 and SQLite3 headers (sqlite3-devel)
* unixODBC and SQLite3 ODBC driver
* Asterisk :-)
* WEB server to execure CGI: Nginx / Apache / Lighttp
=== Download Skype for Asterisk GUI ===
==== Installation of pre-compiled packages ====
* For x32 platforms (ordinary PC) you should get file called ''asterisk-chan_skype-gui-0.1-x32-bin.tar.gz'' from the [http://forge.asterisk.org/gf/project/skype_chan_gui/frs/?action=index Asterisk Forge].
* For x64 pltaforms you should get file called ''asterisk-chan_skype-gui-0.1-x64-bin.tar.gz'' from the [http://forge.asterisk.org/gf/project/skype_chan_gui/frs/?action=index Asterisk Forge].
Unpack the downloaded archive to /var/www/skype/. If you use another target directory see config.lua and adjust path variables. The default configuration file assumes that product URL is /skype/ and it's located in /var/www/skype. See WEB server configuration section for details.
===== config.lua =====
{{{
prefixUrl="/skype"
tmpDir = "/var/www/skype/cgi-bin/tmp"
sessionsDir = "/var/www/skype/cgi-bin/sessions"
dsn = "sqlite3://asterisk:df37hslkv@localhost/db/data.db"
for _, path in ipairs{"/var/www/skype/lib/";"/var/www/skype/share/"} do
package.cpath = (package.cpath or "?.so")..";"..path.."?.so"
package.path = (package.path or "?.lua")..";"..path.."?.lua;"..path.."?/init.lua"
end
}}}
==== Installation from sources ====
If by any reason you cannot or don't want to use pre-compiled packages you can compile all from sources.
Download ''asterisk-chan_skype-gui-0.1-src-tar.gz'' from the [http://forge.asterisk.org/gf/project/skype_chan_gui/frs/?action=index Asterisk Forge].
Save in temporary folder /tmp/ and unpack. Edit install.sh and change AST_USER/AST_GROUP to unix account under asterisk process runs and HTTP_GROUP to unix group HTTP server runs under (Asterisk and WEB server share database file). By default ''asterisk'' and ''apache'' are used. Next run the installation script passing the path to the WEB root folder as a parameter. Here we use /var/www/skype:
{{{
snowflake tmp #
snowflake tmp # tar zxf asterisk-chan_skype-gui-0.1-src.tar.gz
snowflake tmp # cd asterisk-chan_skype-gui-0.1-src
snowflake asterisk-chan_skype-gui-0.1-src # ./install.sh /var/www/skype
Compiling Lua...
Compiling Lua Datafilter...
Compiling Lua Socket...
Compiling Lua Posix...
Compiling Lua SQL...
Unpacking Luv...
Unpacking Skype GUI...
snowflake asterisk-chan_skype-gui-0.1 #
}}}
If everything is OK, let go to WEB server configuration. If you get any errors, please find in working directory the file called '''build.log''' and send it to us (tech(at)pbxware.ru) with subject "Skype for Asterisk GUI installation error".
=== Configure WEB server ===
==== Virtual Server Configuration ====
We use the following configuration for apache HTTP server. We use virtualhost and HTTPS. You should change domain.com to your real domain name if you do the same. But you can adjust the following configuration file to meet your requirements (use directory and not virtual host, or do not use https or password authentication. See apache docs for details. ''Note! We set urlPrefix="" in config.lua, as skype gui locate at the root of WEB server.''
{{{
ServerName skype.domain.com
DocumentRoot /var/www/skype/htdocs
CustomLog /var/log/apache2/skype.domain.com-access.log combined
ErrorLog /var/log/apache2/skype.domain.com-error.log
LogLevel warn
SSLEngine on
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateFile /etc/apache2/ssl/server.crt
ScriptAliasMatch ^/(?!(images/|js/|css/)) /var/www/skype/cgi-bin/index.lua/$1
Order deny,allow
Allow from all
Order deny,allow
Allow from all
AuthType basic
AuthName "Skype configuration"
AuthUserFile /var/www/skype/.htpasswd
require valid-user
}}}
Add this to your apache /etc/apache2/vhosts.d/99_skype.domain.com.conf or another file depending on your environment.
Now let create the password file:
{{{
snowflake ~ # htpasswd -c /var/www/skype/.htpasswd admin
New password:
Re-type new password:
Adding password for user admin
snowflake ~ #
}}}
Reload apache and visit https://skype.domain.com/. Password prompt should appear and your should get in. Please not that we use https for security reasons.
==== Directory Configuration ====
More simple configuration without password on plain text HTTP 80 port:
{{{
# We make an assumption that skype gui package is unpacked into /var/www/skype and WEB site URL is http://domain.com/skype/
ScriptAliasMatch ^/skype/(?!(images/|js/|css/)) /var/www/skype/cgi-bin/index.lua/$1
Order deny,allow
Allow from all
#AuthType basic
#AuthName "Skype configuration"
#AuthUserFile /var/www/skype/.htpasswd
#require valid-user
Alias /skype/ "/var/www/skype/htdocs/"
Order deny,allow
Allow from all
}}}
In the above example we have urlPrefix="/skype" set in cgi-bin/config.lua.
=== Asterisk ===
==== ODBC ====
We use SQLite3 as database storage via res_ODBC.
===== /etc/unixODBC/odbcinst.ini =====
{{{
[SQLite3]
Description=ODBC for SQLite3
Driver=/usr/lib/libsqlite3odbc.so
Setup=/usr/lib/libsqlite3odbc.so
Threading=2
}}}
Driver path must be changed to the real libsqlite3odbc library.
===== /etc/unixODBC/odbc.ini =====
{{{
[SQLite3-skype]
Description=SQLite3 Skype database
Trace=Off
TraceFile=stderr
Driver=SQLite3
Database=/var/www/skype/cgi-bin/db/data.db
}}}
===== /etc/asterisk/res_odbc.conf =====
{{{
[ENV]
[skype]
enabled => yes
dsn => SQLite3-skype
pre-connect => yes
}}}
===== /etc/asterisk/func_odbc.conf =====
{{{
[SKYPE_EXT]
dsn=skype
readsql=SELECT exten FROM skypecontact WHERE skypeid='${SQL_ESC(${ARG1})}'
[SKYPE_NAME]
dsn=skype
readsql=SELECT skypeid FROM skypecontact WHERE exten='${SQL_ESC(${ARG1})}'
[SKYPE_MAX_EXT]
dsn=skype
readsql=SELECT MAX(exten) FROM skypecontact
[SKYPE_ADD]
dsn=skype
writesql=INSERT INTO skypecontact (exten, skypeid, created, modified) VALUES ('${SQL_ESC(${VAL1})}', '${SQL_ESC(${VAL2})}', datetime('now','localtime'), datetime('now','localtime'))
}}}
=== Skype ===
Skype accounts are configured in chan_skype.conf. Here is an example configuration:
==== chan_skype.conf ====
{{{
[general]
engine_directory=/tmp/skype
default_user=pbxware.ru
bind_address=x.x.x.x
bind_port=0
[pbxware.ru]
secret=XXXXXXXXXXXXXXX
context=skype-in
exten=s
disallow=all
allow=ulaw
direction=both
auth_policy=accept
}}}
The most important settings are:
* context - all calls from Skype are handled in skype-in;
* exten - what extension to call in that context;
=== Dialplan ===
Add the following to your extensions.conf:
{{{
; Context for our users
[from-internal]
exten => _XXX,1,Macro(std-exten,${EXTEN})
exten => _XXXX,1,Goto(skype-out,${EXTEN},1)
; Here we define what we do with incoming calls from skype
[from-skype]
exten => s,1,Goto(menu-main,s,1)
exten => _XXX,1,Goto(from-internal,${EXTEN},1)
; Context for outgoing skype calls
[skype-out]
exten => _XXXX,1,Set(DST=${EXTEN})
exten => _XXXX,2,Goto(s,1)
exten => s,1,Set(skype_name=${ODBC_SKYPE_NAME(${DST})})
exten => s,n,ExecIf($["${skype_name}" = ""]|Hangup)
exten => s,n,Dial(Skype/${skype_name})
; Context for incoming Skype calls
[skype-in]
; Save dialed exten
exten => _X.,1,Set(DST=${EXTEN})
exten => _X.,2,Goto(s,1)
; If from skype comes start exten
;exten => s,1,ExecIf($["${DST}" = ""]|Set|DST=s); 1.4 version
exten => s,1,ExecIf($["${DST}" = ""]?Set(DST=s)); 1.6 version
; Let see if we already have this account
exten => s,n,Set(skype_name=${CALLERID(num)})
exten => s,n,Set(skype_ext=${ODBC_SKYPE_EXT(${skype_name})})
exten => s,n,GotoIf($["${skype_ext}" = ""]?not-found:found)
; Existing account found
exten => s,n(found),NoOp(Found Skype ID ${skype_name} with exten ${skype_ext})
exten => s,n,Set(CALLERID(num)=${skype_ext})
exten => s,n,Set(CALLERID(name)=${skype_name})
exten => s,n,Goto(from-skype,${DST},1)
; New Skype account calling
exten => s,n(not-found),Set(skype_ext=${ODBC_SKYPE_MAX_EXT()}); Get maximum extension number
;if database is empty we initialize 1-st exten 1000
;exten => s,n,ExecIf($["${skype_ext}" = ""]|Set|skype_ext=1000); 1.4. version
exten => s,n,ExecIf($["${skype_ext}" = ""]?Set(skype_ext=1000)); 1.6 version
; Add new record with next available exten
;exten => s,n,Set(ODBC_SKYPE_ADD()=$[${skype_ext}+1]\,${skype_name}); 1.4 version
exten => s,n,Set(ODBC_SKYPE_ADD()=$[${skype_ext}+1],${skype_name}); 1.6 version
exten => s,n,Set(CALLERID(num)=${skype_ext}+1)
exten => s,n,Set(CALLERID(name)=${skype_name})
exten => s,n,Goto(from-skype,${DST},1)
}}}
'''NOTE! This is the dialplan configuration for Asterisk 1.6. For 1.4 branch you should comment 1.6 lines and uncomment 1.4! Otherwise Asterisk will complain on dialplan reload.'''
=== Reload Asterisk ===
{{{
CLI> reload
}}}
== Enjoy! ==
Now call your skype account and see how it works all together! Enjoy! If you need assistance or would like to request a feature do not hesitate to contact us (see Contact Us section).
== Comments ==
Comments are welcome.
[[AddComment]]
== Troubleshooting ==
If anything foes wrong see build.log for details. Here we enumerate some issues we already met.
=== Filtering does not work or new skype accounts are not created ===
See folder permissions. Both asterisk and WEB server must have read/write access to database file cgi-bin/db/data.db. WEB server must also be able to read/write cgi-bin/sessions and cgi-bin/tmp folders.
=== Load res_odbc and func_odbc ===
{{{
snowflake*CLI> module load res_odbc.so
[2009-12-10 11:50:47] WARNING[25757]: loader.c:711 load_resource: Module 'res_odbc.so' already exists.
snowflake*CLI> module reload res_odbc.so
[2009-12-10 11:50:51] -- Reloading module 'res_odbc.so' (ODBC Resource)
[2009-12-10 11:50:51] == Parsing '/home/asterisk.pbxware/etc/asterisk/res_odbc.conf': [2009-12-10 11:50:51] Found
snowflake*CLI> odbc show
Name: skypeLI>
DSN: SQLite3-skype
}}}
All is ok.
If you see smth like:
{{{
snowflake*CLI> module load res_odbc.so
[2009-12-10 11:50:10] == Parsing '/home/asterisk.pbxware/etc/asterisk/res_odbc.conf': [2009-12-10 11:50:10] Found
[2009-12-10 11:50:11] WARNING[25757]: res_odbc.c:562 odbc_obj_connect: res_odbc: Error SQLConnect=-1 errno=0 [unixODBC][Driver Manager]Can't open lib '/usr/lib64/libsqlite3odbc.so' : /usr/lib64/libsqlite3odbc
[2009-12-10 11:50:11] WARNING[25757]: res_odbc.c:467 ast_odbc_request_obj: Failed to connect to skype
}}}
Then check your unixODBC SQLite3 installaiton.
{{{
snowflake*CLI> module load func_odbc.so
[2009-12-10 11:51:12] == Parsing '/home/asterisk.pbxware/etc/asterisk/func_odbc.conf': [2009-12-10 11:51:12] Found
[2009-12-10 11:51:12] == Registered custom function ODBC_SKYPE_EXT
[2009-12-10 11:51:12] == Registered custom function ODBC_SKYPE_MAX_EXT
[2009-12-10 11:51:12] == Registered custom function ODBC_SKYPE_ADD
[2009-12-10 11:51:12] == Registered custom function SQL_ESC
[2009-12-10 11:51:12] Loaded func_odbc.so => (ODBC lookups)
snowflake*CLI>
snowflake*CLI> show func
functions function
snowflake*CLI> show function ODB
ODBC_SKYPE_ADD ODBC_SKYPE_EXT ODBC_SKYPE_MAX_EXT
snowflake*CLI> show function ODBC_SKYPE_
}}}
You should check your modules.conf and see that there is no noload directived for ODBC related.
=== Skype channel ===
Check that everything is configured right:
{{{
snowflake*CLI> skype show user pbxware.ru
Skype User pbxware.ru:
secret: XXXXXXXXXXXX
context: skype-in
exten: s
accountcode:
language:
mohinterpret:
mohsuggest:
amaflags: Unknown
direction: both
buddy_autoadd: hints
buddy_presence: yes
debug: no
auth_policy:
accept
codecs: ulaw
snowflake*CLI>
pbxware.ru: Logged In
snowflake*CLI>
}}}
Our account is registered.
=== readline headers not found ===
If you get smth like:
{{{
Compiling Lua...
In file included from lua.h:16,
from lua.c:15:
luaconf.h:275:31: error: readline/readline.h: No such file or directory
luaconf.h:276:30: error: readline/history.h: No such file or directory
}}}
then you do not have readline headers installed. On RPM based linux it is readline-devel package: yum install readline-devel.
=== Missing libtool ===
If you get the following:
{{{
Compiling Lua...
Compiling Lua Datafilter...
cp: cannot stat `.libs/liblua-datafilter.so': No such file or directory
Compiling Lua Socket...
Compiling Lua Posix...
Compiling Lua SQL...
Unpacking Luv...
Unpacking Skype GUI...
}}}
that means datafilter was not compiled. See build.log for details. In our case there was:
{{{
CC> filter.lo
make: libtool: Command not found
make: * [filter.lo] Error 127
}}}
Install libtool and repeat from the very beginning.
== Contact Us ==
You can contact as by email tech(at)pbxware.ru for support of feature request.