[HOW TO] Relatively simple interface to TimeTrex for FreePBX/PIAF users

How would I be able to do that? I am a complete noob for running things on the CLI for freepbx or anything like it. I am still learning how to work all types of linux systems, but I only know so much.

Log into the console and type the following:

Let me know if it errors out. It should (if I remember correctly) give you a usage error and tell you what the arguments are supposed to be.

Looks like it did

 /var/lib/asterisk/agi-bin/timetrex
PHP Notice:  Undefined offset: 1 in /var/lib/asterisk/agi-bin/timetrex on line 3 
3
PHP Notice:  Undefined offset: 2 in /var/lib/asterisk/agi-bin/timetrex on line 3 
4
PHP Notice:  Undefined offset: 3 in /var/lib/asterisk/agi-bin/timetrex on line 3 
5
PHP Notice:  Undefined index: _agi_extension in /var/lib/asterisk/agi-bin/timetr
ex on line 36
PHP Notice:  SOAP Fault: (Code: HTTP, String: Could not connect to host) - Reque
st:  Response:  in /var/www/html/timetrex/classes/modules/api/client/TimeTrexCli
entAPI.class.php on line 158
    Login Failed!

It does not tell me what the arguments are supposed to be.

Your admin username/password are not correct for the AGI to run. You need to edit the program to set up the defaults for your TimeTrex Asterisk User and Password. This is so that the program can get some information about the current dial session.

To retest the program, run it with three arguments

/var/lib/asterisk/agi-bin/timetrex EMP_ID EMP_PASS AST_USER

> PHP Notice:  Undefined index: _agi_extension in /var/lib/asterisk/agi-bin/timetrex on line 36
> Punch save failed.
> =====================================<br>
> Function: setPunch()<br>
> Args: 1<br>
> -------------------------------------<br>
> Returned:<br>
> IsValid: NO<br>
> Code: VALIDATION<br>
> Description: INVALID DATA<br>
> Details: <br>
> Row: 0<br>
> --Field: status<br>
> ----Message: Incorrect Status<br>
> ----Message: Status not specified<br>
> =====================================<br>

I had changed a few things in the script, it was not reaching the “host” when it was on the same server as the asterisk server. But I have this now, I did test it out, and it still does not let me punch in. How strange.

Not really - it’s telling you right there on the screen that your punch information is no good.

Log into the server and go to /var/lib/asterisk/agi-bin and edit “timetrex”. I use ‘vi’ for this type of work.

Go down about three pages and you’ll see a huge debug block. The first line “print Punch Information”

Remove the 8 hash symbols (#) on the eight lines below that. This will display what you are sending to TimeTrex and should give you a sense of where your information is going wrong. The “IsValid: NO” entry here is the response from your TimeTrex server.

It’s always fun to watch this stuff but why has no-one yet suggested

agi set debug on

to actually discover WTF you are all confused about ?

It’s not actually the AGI that’s the problem.

There are two required fields. The first is the “TimeTrex” user in the TimeTrex program. This user needs to have the rights to proxy update the time punch for the user. The other is the actual punch user code (which is different than the user number/extension) and passcode from the TimeTrex program.

My suspicion is that the TimeTrex admin account doesn’t have the right permissions set and that’s what’s causing the problem. The AGI is actually working fine - it’s a problem on the TimeTrex side.

Which is odd for me, usually when I do things and implement them they usually work. Not sure what is going on. I have not tested this just yet, I will let you know.

I believe that the agi is working, I run Timetrex by itself in the agi directory and it gives a successful punch right away with no extra commands. Now it’s the phone part that it’s not going through with it.

The “phone part” was working - it executes the AGI which terminates with an error code of “0” (which, because of the way I hacked the original program together, may be the only error code you get).

If you use @dicko’s recommendation, you can turn on AGI debugging and get a lot more information about what is getting passed to the AGI. You can also “uncomment” that AGI call information block in the program and get a lot of detail out of there.

There are a couple of TimeTrex specific things that need to be looked at. One is the “punch id”, which is a different field than the employee number. I always set them the same (because I like 4-digit employee and punch numbers) but if the punch ID isn’t set or is different than the number you are sending, the punch update will fail.

You also have to make sure that the pin you are using is the right pin. It has to match the employee pin number (not the 500 admin account) so that the logic of the AGI is managed. Note that the only point of using the PIN is to give the system a reasonable level of security. Most places that use this AGI now all use the same PIN for everybody because the bosses have decided that clocking each other in and out is “OK”.

I’ll post my scripts and stuff here in a few minutes in my next post. I’m sure I did everything right, though I’ll change a few things for security sake.

This is my timetrex agi script

#!/usr/bin/php -q
<?php
$type_id[10] = 'Regular';
$type_id[20] = 'Lunch';
$type_id[30] = 'Break';
$type_id[40] = '';
$status_id[0] = 'Auto';
$status_id[10] = 'In';
$status_id[20] = 'Out';
$status_id[30] = 'Absent';

require_once('/var/www/html/timetrex/classes/modules/api/client/TimeTrexClientAPI.class.php');

/*
 Global variables - modify these defaults to suit your system.
*/
$TIMETREX_HOST = "10.1.10.70";
$TIMETREX_URL = 'http://10.1.10.70/timetrex/api/soap/api.php';
$TIMETREX_USERNAME = 'admin';
$TIMETREX_PASSWORD = 'adminpasswordhere';

/* 
These following will be replaced when the AGI is executed by Asterisk. 
All of the following are actually information entries from TimeTrex (users) or are stored as
part of the punch.
*/

$ASTERISK = 500;                # A Asterisk extension/TimeTrex special user
$EXTENSION = 500;            # Default phone extension (in case AGI below fails)
$EMPLOYEE = 0000;           # Default User Number (should be fake)
$EMP_PASS = 0000;           # Default Connect Password (bad passcode)

$EMPLOYEE = $argv[1];
$EMP_PASS = $argv[2];
$ASTERISK = $argv[3];
$EXTENSION = $_ENV{"_agi_extension"};

$api_session = new TimeTrexClientAPI();
$api_session->Login( $TIMETREX_USERNAME, $TIMETREX_PASSWORD );
if ( $TIMETREX_SESSION_ID == FALSE ) {
   echo "Login Failed! \n";
   exit (-1);
}

$user_obj = new TimeTrexClientAPI( 'User' );
$result = $user_obj->getUser(array('filter_data' => array('employee_number' => $EMPLOYEE ) ) );

$user_data = $result->getResult();

$user_id = $user_data[0]{'id'};
$phone_password = $user_data[0]{'phone_password'};
if ( $phone_password == $EMP_PASS ) {
   echo "Login Failed! \n";
   exit (-1);
}

$punch_obj = new TimeTrexClientAPI( 'Punch' );

$punch_data = array(
        'user_id' => $user_id,
        'station_id' => $EXTENSION,
        'type_id' => 10,             //Stat type: reg is 10, lunch is 20
        'status_id' => 0,            //status id: in is 10, out is 20, 'whatever' is 0
        'created_by' => $ASTERISK, //special case for phones
        'time_stamp' => time()
);
try{
    $result = $punch_obj->setPunch( $punch_data );
    if ( $result->isValid() === TRUE ) {
       echo "Punch added successfully.\n";
       $insert_id = $result->getResult(); //Get punch new ID on success.
    } else {
       echo "Punch save failed.\n";
       print $result; //Show error messages
    }
} catch(Exception $e){
    echo $e->getMessage();
}
?>

This is at the bottom of my extensions_custom.conf file

[timetrex]
exten => s,1,Set(wait=0)
exten => s,n,Set(length=4)
exten => s,n,Set(timetrex=500)
exten => s,n,Answer
exten => s,n(begin),Playback("silence/1")
exten => s,n,Playback("custom/TimeTrex-clock")
exten => s,n,Read(usernum,"silence/1",${length})
exten => s,n,Wait(0)
exten => s,n,Playback("custom/TimeTrex-pass")
exten => s,n,Read(userpass,"silence/1",${length})
exten => s,n,AGI(timetrex,${usernum},${userpass},${timetrex})
exten => s,n,Hangup

I made the recordings and they work.
Is it okay to set the wait time at 0 because I want them to clock in relatively fast?

And I keep getting this

/var/lib/asterisk/agi-bin/timetrex 1202 1212 500
PHP Notice:  Undefined index: _agi_extension in /var/lib/asterisk/agi-bin/timetrex on line 36
Punch save failed.
=====================================<br>
Function: setPunch()<br>
Args: 1<br>
-------------------------------------<br>
Returned:<br>
IsValid: NO<br>
Code: VALIDATION<br>
Description: INVALID DATA<br>
Details: <br>
Row: 0<br>
--Field: status<br>
----Message: Incorrect Status<br>
----Message: Status not specified<br>
=====================================<br>

When I go ahead and audit my user it has me logged in as well, but logs me right out.

You’ve made a couple of changes that might effect your ability to log in:

if ( $phone_password == $EMP_PASS ) {

in the original code was:

if ( $phone_password != $EMP_PASS ) {

The employee numbers get truncated if they have leading zeros, so you lose the 4 digits if the first one is a zero.

There isn’t a ENV variable called “_agi_extension”.

Even though I had changed everything it still does not work, I am really unsure what is going on. I even went ahead and recopied the original script without changing anything but the few things that were needed to be changed. [quote=“cynjut, post:34, topic:27713”]
if ( $phone_password != $EMP_PASS ) {
[/quote]

That was not in the original code.

I am not sure what you mean by this. I have not touched it.

I’ve been playing around with the code for the last hour or so and I’ve refreshed my memory a little bit.

Here are the things that aren’t intuitively obvious:

  1. Update the dialplan that calls the program to include the following (in extensions_custom.conf)

exten => s,1,Set(wait=1)
exten => s,n,Answer
exten => s,n(begin),Playback(“silence/1”)
exten => s,n,Playback(“custom/TimeTrex-clock”)
exten => s,n,Read(usernum,“silence/1”,4)
exten => s,n,Wait(1)
exten => s,n,Playback(“custom/TimeTrex-pass”)
exten => s,n,Read(userpass,“silence/1”,4)
exten => s,n, AGI(timetrex,${usernum},${userpass},${CALLERID(num)})
exten => s,n,NoOp(${AGISTATUS})
exten => s,n,Hangup

The only change is the CALLERID(num) part. This passes the calling extension to the script instead of the script trying to skull it out.

Next, you have to do some work in TimeTrex.

  1. Set your employee numbers (for people that will be punching in with the phone) to 4-digit numbers. Match the “Quick Punch ID” to avoid the confusion I just had. The reason for the confusion is because the system used to look up the Quick Punch ID when the program ran - it doesn’t now; it uses the actual employee number.

After that, set your “Quick Punch Password” to some other 4-digit number. The system complains if you use the same numbers.

  1. There is a block of code at the top of the AGI that has the TIMETREX_USERNAME and _PASSWORD. Avoid the temptation to conflate these with the Asterisk user and password. Also, if you create an admin user for this, make sure you log in as that user (through the web interface) and clear the “must reset password” flag. The system will not let your TimeTrex admin user log in until you clear the flag (that was about 20 minutes of head scratching right there).

  2. To enhance debugging, I changed all of the “echo” and “print” commands to a new function called “log_agi()”. I snagged it off a website somewhere.

1 Like

Hi,

Thank you for that guide.

I followed it step by step but I think there is an error in the API connection.

The rror i am getting by trying in command line is:

HP Notice: Undefined index: _agi_extension in /var/lib/asterisk/agi-bin/timetrex on line 36
PHP Fatal error: Class ‘TimeTrexClientAPI’ not found in /var/lib/asterisk/agi-bin/timetrex on line 38

P

It looks like the TimeTrexClientAPI isn’t getting loaded in PHP. Did you make sure to get that installed onto the local server? Remember, if you are running TimeTrex on a different machine, you still need to API code to be available to the PHP instance on the Asterisk server.

Hi,

Thanks @cynjut that helped a little. Now when I run it, I am getting the following error.

- /var/lib/asterisk/agi-bin/timetrex 2022 6585

PHP Notice: Undefined index: _agi_extension in /var/lib/asterisk/agi-bin/timetrex on line 36
PHP Notice: SOAP Fault: (Code: HTTP, String: Could not connect to host) - Request: Response: in /var/www/html/TimeTrexClientAPI.class.php on line 203
Login Failed!

I checked and the original timetrex agi code is using the correct username and admin from the timetrex system. I gave that user all permissions.

What other steps would you advise I should take?

Thanks in advance

This thread talks about this specific error already.

I’m going to guess that your TimeTrex Admin user in FreePBX isn’t set up right. Double check your administrators in FreePBX and make sure the password, permissions, etc. are all correct.