Updated July 18th 2011
This is the first of a series of tutorials designed to help you get started with writing bots and applications using the Betfair API. These tutorials use the php programming language and make heavy use of the bflib Betfair API library. Before you get started, you will need to download the bflib source code from it's home on github. The project page is here and the 'download source' link is in the top-right, just under the 'search' box.
Extract the source code onto your local filesystem. If your bot/app will have a web front-end, you will need to put the source code into a directory which is accessible from your web docroot. Your bot can run headless - in which case, you can extract the bflib source code into any convenient location.
chris@osx-lx-vm:/export$ tar -zxvf planetguru-bflib-c2b3a8f.tar.gz
chris@osx-lx-vm:/export$ mv planetguru-bflib-c2b3a8f bflib
Now you need to make sure that you update the vendorConstants class file with your own username and password. In the example above, this would be under /export/bflib/classes/vendorConstants.class.php. If you are doing this for the first time, move the vendorConstants.class.php.sample to vendorConstants.class.php and then edit the file so that your username and password are correct and include your vendorId if you have one. If you don't have a vendorId, use the productID 82 and the vendorid 0, as shown below.
class vendorConstants {
/**
* bdp developer credentials. You should change the USERNAME and
* PASSWORD to match your own username and password on betfair.
* Remember that your account will need to be active, with recent transactions and
* cleared funds in order for the SOAP APIs to allow you to authenticate
*
*/
const USERNAME = 'yourusernamehere';
const PASSWORD = 'yourpasswordhere';
const PRODUCTID = 82;
const VENDORID = 0;
const LOCATIONID = 0;
const IPADDRESS = 0;
public function __construct(){}
}
Great - now we're all set up to try a very simple app - just to check that your account works. This application is headless, so has no web page or UI. All it does is return all of the top-level event types offered on betfair.
Here is a walkthrough of how I get this app working. First I create a new directory to house my application. I'm going to call it betfair-test:
chris@osx-lx-vm:/export$ mkdir betfair-test
chris@osx-lx-vm:/export$ cd betfair-test/
chris@osx-lx-vm:/export/betfair-test$ mkdir classes
chris@osx-lx-vm:/export/betfair-test$ mkdir cli
Now I am going to create two files. One will be a simple class file for my demo application class. The second will be the executable which I run to actually use the application. The class file should live in the 'classes' directory (created above) under the name testApp.class.php and the executable should live in the 'cli' directory - it doesn't matter what this one is called. First, this is what the source code for the testApp.class.php application class should look like:
<?php
/**
* Test use of the 'bflib' Betfair API connection library. This just requests a list of
* top-level event types and displays their names. This is the simplest of requests which
* can be made against the Betfair API and demonstrates that you have a working connection
*/
class testApp {
private $context = '';
/**
* construct testApp object
*
* @param none
* @return none
*/
public function __construct(){
/* directly set the 'context' since this mini app isn't going to do anything else */
$this->context = 'getAllEventTypes';
}
/**
* Instantiate a betfairController object, passing through the 'context'
* and then grab the soapresponse after the API call is made.
*
* @param none
* @return none
*/
public function run(){
/* some methods are just page displays and don't need to talk to betfair */
$this->bflib = new betfairController();
$soapResult = array();
$soapResult = $this->scheduleRequest();
foreach($soapResult->Result->eventTypeItems->EventType as $eventType){
print("n".$eventType->name);
}
}
/**
* Tell the betfairController class which API verb/method we are going to use and ask it to set up the request object
* Then run the controller and capture the soapResponse object that comes back
*
* @param none
* @return none
*/
public function scheduleRequest(){
/* set the bflib context as this context */
$this->bflib->setContext($this->context);
/* call the bflib->constructRequestData method to set up the soap data */
$this->bflib->constructRequestData($this->context);
/* run the bflib->execute and bflib->prepareResponseData requests and capture the soapResult which comes back */
$soapResponse = $this->bflib->run();
return($soapResponse);
}
}
?>
This file needs to be saved in your 'cli' directory with the name betfair-test.
What you see here is really a helicopter view of the basic request cycle which occurs every time a message is sent to Betfair. The betfairController class handles the incoming request from this application class. Based on the context, it constructs arrays of request data, which are then passed into the low-level betfairDialogue class. The controller can also exposes an itemId member variable, which is used to pass in the ID of whatever the thing is you want to perform an action upon.
Some Design considerations
The next version of the bflib library will move away from the itemId principal within the controller, introducing a 'subjects' class, which can represent either an integer ID, or an array of IDs, or a collection of objects. This will allow one/many-to-many type operations to occur (eg bulk bet placement). It's always worth knowing that the itemId/subjects object at the betfairController level is a facade to and object of the same name within the betfairDialogue class. The former provides a home for any business logic around request data preparation and perhaps bubbling back into helper classes within the application framework before passing the assembled request down to the dialogue handler to be sent over the wire.
Now all I need is an executable to instantiate the application class which I have created. It looks like this:
<?php
/**
* Define autoload classpath and require it in.
*
* @param $class The class to be loaded
* @return none
*/
function __autoload( $class ){
$classpath = '../classes/'.$class.'.class.php';
if (file_exists( $classpath )){
require_once($classpath);
return;
}
$classpath = '/export/bflib/classes/'.$class.'.class.php';
if (file_exists( $classpath )){
require_once($classpath);
return;
}
}
$testApp = new testApp();
$testApp->run();
?>
I included a specific autoload method to point down the two class paths which I'm using for this application. In doing so, I have enforced a convention whereby a class is always found within a file which bears it's name in the format <classname>.class.php. This arguably put a bit more structure around php's potentially shappy management of classnames. It will also feel more familier to folks with a java background.
Something else which is worth knowing is the location of the betfairLogger's log destination. Currently this is set to /tmp/betfair-api-log within the vendorConstants.class.php configuration file. If you are having trouble getting this thing to work, then your log file is a good place to check for error codes returned from betfair. The logger functionality is new and does not yet have a toggle - The platform also doesn't yet watch for specific error codes within an exception handling framework. This is in-plan.
Okay - so now let's run the app and see what we get:
chris@osx-lx-vm:/export/betfair-test/cli$ php -e betfair-test
PHP Warning: Xdebug MUST be loaded as a Zend extension in Unknown on line 0
Poker Room
Yahoo Racing
Soccer
Tennis
Golf
Cricket
Rugby Union
Boxing
Horse Racing
Motor Sport
Soccer Euro 2000
Special Bets
Cycling
Rowing
Rugby League
Darts
Athletics
Greyhound Racing
Financial Bets
Snooker
American Football
Olympics - Sydney 2000
Baseball
Basketball
Hockey
Ice Hockey
Sumo Wrestling
Australian Rules
Gaelic Football
Hurling
Pool
Test Only
Chess
2002 Winter Olympics
Trotting
Commonwealth Games
Poker
Winter Sports
Handball
Volleyball
Politics
Bridge
Exchange Poker
International Rules
Table Tennis
Floorball
Netball
Yachting
Swimming
Gaelic Games
Internal Markets
Olympics 2004
Bowls
Bandy
Badminton
GAA Sports
Backgammon
Soccer - Euro 2004
Exchange Roulette
Exchange Blackjack
Fishing
Exchange Casino
Tradefair Test
Cross Sport Accumulators
Featured Markets
Ten Pin Bowling
Exchange Card Racing
Surfing
Canoeing
Equestrian
Water Polo
Fussball
Exchange Omaha Hi
Combat Sports
Olympics 2008
Roller Hockey
Polo
Harness Racing
Pelota
Horse Racing - Virtual
Squash
Futsal
Beach Volleyball
Exchange Hi Lo
Exchange Baccarat
Tradefair
Casino
Mixed Martial Arts
Exchange Gameschris@osx-lx-vm:/export/betfair-test/cli$
And bingo! we have a working connection to betfair's soap endpoint and our first request has worked.
In future articles I will dive into some more complex examples and demonstrations, including price monitoring, bet placement and UI development. I'll come back and link those articles in when they emerge :) Meanwhile, why not check out the Second Tutorial in this series, which focusses on coding a betfair application with market navigation and a simple user interface - Second betfair tutorial here
Follow me on Twitter: http://twitter.com/planet_guru
christo






