├── .gitignore ├── .travis.yml ├── Gemfile ├── README.md ├── Rakefile ├── asianodds.gemspec ├── bin ├── console └── setup ├── lib ├── asianodds.rb └── asianodds │ ├── login.rb │ └── version.rb └── test ├── login └── login_test.rb ├── spec.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | 11 | # Ignore application configuration 12 | /config/application.yml 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.3 4 | 5 | cache: bundler 6 | script: ruby test/spec.rb 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Specify your gem's dependencies in asianodds.gemspec 4 | gemspec 5 | 6 | group :test do 7 | gem "rubocop" 8 | end 9 | 10 | group :development do 11 | gem "bundler", "~> 1.13" 12 | gem "rake", "~> 10.0" 13 | gem "minitest-rails" 14 | gem "byebug" 15 | end 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :soccer: Asianodds - Automated Sports Trading 2 | 3 | [![Gem Version](https://badge.fury.io/rb/asianodds.svg)](https://badge.fury.io/rb/asianodds) [![Code Climate](https://codeclimate.com/github/Jan17392/asianodds/badges/gpa.svg)](https://codeclimate.com/github/Jan17392/asianodds) 4 | 5 | This gem is a wrapper for the Asianodds Web API. 6 | In order to use this gem you need to apply for a Web API account with Asianodds (api@asianodds88.com). Please keep in mind that your regular Asianodds user (for the Web Interface) does not work for your API account and vice versa. 7 | 8 | The purpose of the gem is to pre-configure all API calls to make your life as easy as just calling one method. You won't need to MD5 hash your password (as Asianodds requests) and the gem assumes smart pre-configs for your calls, so they will work even without passing in required parameters. Still, it has the same flexibility as the original API without limitations. 9 | 10 | With just three lines of code you will be able to start placing real-time bets with multiple bookmakers and automate your trading strategies. 11 | 12 | For any bugs, ideas or feature requests don't hesitate to open an issue. 13 | 14 | *Disclaimer: This gem is not officially developed by Asianodds and does not belong in any way to the Asianodds service, nor is it supported by their development team and all rights to accept or deny bets made with this gem remain with Asianodds.* 15 | 16 | 17 | ## Installation 18 | 19 | Add this line to your application's Gemfile: 20 | 21 | ```ruby 22 | gem 'asianodds' 23 | ``` 24 | 25 | And then execute: 26 | 27 | $ bundle install 28 | 29 | Or install it yourself as: 30 | 31 | $ gem install asianodds 32 | 33 | ## Usage 34 | 35 | All returned objects from the gem are in the form of Ruby Hashes (or plain booleans if specified) with all Keys converted to Symbols. 36 | 37 | 38 | 39 | ### Login 40 | 41 | Create a new user instance and provide your username and raw password (not hashed): 42 | 43 | ```ruby 44 | asianodds = Asianodds::Login.new('dagobert_duck', 'secure_password') 45 | # 46 | ``` 47 | The returned response / initiated user will contain the following keys: 48 | 49 | |Key|Value|Description| 50 | |---|-----|-----------| 51 | |@user|dagobert_duck|This is your username| 52 | |@password|secure_password|This is your password| 53 | |@password_md5|hashed MD5 password|The password actually used to login| 54 | |@ao_token|random string ('2220749911057835565404619834') or ('')|Token passed to execute all methods| 55 | |@ao_key|random string ('3c81574f865d1d892d52d7cbc78a18dd') or (nil)|Key used once to register - only valid for 60s| 56 | |@base_url|https://webapi.asianodds88.com/AsianOddsService|Used url base to access the Asianodds service| 57 | |@code|0 or -1|Indicator whether current action was successful: 0 = true, -1 = false| 58 | |@successful_login|boolean|Shows whether user is logged in successfully| 59 | |@message|string ('Successfully Registered.')|Verbose description of the current user status| 60 | 61 | 62 | ### Register 63 | 64 | With the instantiation of the login call, you will automatically get registered to the app. There is no need to call the register method separately. The registration message can be read from the current users @message. 65 | 66 | 67 | ### Login Check 68 | 69 | You can check whether you are logged in to the service with the isloggedin? method. It returns either true if logged in or false if not. 70 | 71 | ```ruby 72 | asianodds.isloggedin? 73 | # returns true or false 74 | ``` 75 | 76 | This method is automatically called on each subsequent method to ensure you will be re-registered in case you are not logged in anymore. No need to manually check the logged in status. 77 | 78 | 79 | 80 | ### Logout 81 | 82 | After finishing all transactions and business logic, it is wise to logout and unregister (happens automatically after 30 min of inactivity) with the logout method 83 | 84 | ```ruby 85 | asianodds.logout 86 | # { Code: -1, Message: null, Result: "Failed Logout. Have you logged in before ?" } 87 | ``` 88 | |Key|Value|Description| 89 | |---|-----|-----------| 90 | |@code|0 or -1|Indicator whether current action was successful: 0 = true, -1 = false| 91 | |@message|-|Can be omitted| 92 | |@result|string ('Failed Logout. Have you logged in before ?')|Verbose description of the action result| 93 | 94 | 95 | ### Get Match Feeds 96 | 97 | The get_feeds method returns all matches with their respective feed information, (such as running minute, home team, away team etc.) filtered by optional parameters. Parameters have to communicated via a hash. Accepted parameters are: 98 | 99 | |Key|Value|Description| 100 | |---|-----|-----------| 101 | |sports_type|see get_sports|Which sports to show (default 1 - football)| 102 | |market_type|0 - Live, 1 - Today, 2 - Early|What betting market to receive (default 1 - Today)| 103 | |bookies|see get_bookies|From which bookies to show odds (default ALL)| 104 | |leagues|see get_leagues|From which leagues to receive matches (default ALL)| 105 | |odds_format|MY - Malaysian, 00 - European, HK - Hong Kong|What oddsformat to show (default 00 - European)| 106 | |since|tbd|Show only match feeds since the timestamp (default none)| 107 | 108 | ```ruby 109 | asianodds.get_feeds({ sports_type: 1, market_type: 1, bookies: "ALL", leagues: "ALL", odds_format: "00" }) 110 | # Works as well and returns the same result (due to auto-filters): 111 | asianodds.get_feeds({}) 112 | 113 | =begin 114 | Response: 115 | { 116 | Code: 0, 117 | Message: "", 118 | Result: { 119 | Since: 1493301694214, 120 | Sports: [ 121 | { 122 | MatchGames: [ 123 | { 124 | AwayTeam: { 125 | Name: "Qaradag Lokbatan", 126 | RedCards: 0, 127 | Score: 1 128 | }, 129 | ExpectedLength: 45, 130 | Favoured: 1, 131 | FullTimeHdp: { 132 | BookieOdds: "IBC=0.530,-0.730;BEST=IBC 0.530,IBC -0.730", 133 | Handicap: "0.0" 134 | }, 135 | FullTimeOneXTwo: { 136 | BookieOdds: "" 137 | }, 138 | FullTimeOu: { 139 | BookieOdds: "IBC=-0.310,0.090;BEST=IBC -0.310,IBC 0.090", 140 | Goal: "3.5" 141 | }, 142 | GameId: -1895622898, 143 | HalfTimeHdp: { 144 | BookieOdds: "", 145 | Handicap: "" 146 | }, 147 | HalfTimeOneXTwo: { 148 | BookieOdds: "" 149 | }, 150 | HalfTimeOu: { 151 | BookieOdds: "", 152 | Goal: "" 153 | }, 154 | HomeTeam: { 155 | Name: "PFC Turan Tovuz", 156 | RedCards: 0, 157 | Score: 2 158 | }, 159 | InGameMinutes: 168, 160 | IsActive: false, 161 | IsLive: 1, 162 | LeagueId: 922171774, 163 | LeagueName: "AZERBAIJAN DIVISION 1", 164 | MarketType: "Live", 165 | MarketTypeId: 0, 166 | MatchId: -1898629925, 167 | StartTime: 1493294400000, 168 | StartsOn: "04/27/2017 12:00:00.000 PM", 169 | ToBeRemovedOn: 1493301984351, 170 | UpdatedDateTime: 1493301684351, 171 | WillBeRemoved: true 172 | } 173 | ], 174 | SportsType: 1 175 | } 176 | ] 177 | } 178 | } 179 | =end 180 | ``` 181 | 182 | ### Get Bets 183 | 184 | With the get_bets method all (max. 150) outstanding bets of the instantiated user are retrieved 185 | 186 | ```ruby 187 | asianodds.get_bets 188 | ``` 189 | 190 | 191 | 192 | ### Get a Single Bet by its Reference 193 | 194 | This method is very useful and should be used to validate that a bet has been accepted by the bookmaker after the place_bet method. It can be called with a single parameter which is provided by the place_bet method 195 | 196 | ```ruby 197 | asianodds.get_bet_by_reference("WA-1493188766490") 198 | ``` 199 | 200 | 201 | ### Get Running Bets 202 | 203 | This is a subset of the get_bets method which returns only the currently running bets 204 | 205 | ```ruby 206 | asianodds.get_running_bets 207 | ``` 208 | 209 | 210 | ### Get Non-Running Bets 211 | 212 | This is a subset of the get_bets method which returns only the currently not running bets 213 | 214 | ```ruby 215 | asianodds.get_non_running_bets 216 | ``` 217 | 218 | 219 | ### Get Account Summary 220 | 221 | Getting the account summary of the current user helps to see the current credit, currency and P&L. No additional parameters need to be passed in if logged in. 222 | 223 | ```ruby 224 | asianodds.get_account_summary 225 | 226 | =begin 227 | { 228 | Code: 0, 229 | Message: null, 230 | Result: { 231 | Credit: 344.69, 232 | CreditCurrency: 'EUR', 233 | Message: 'Showing Account Summary for User WEBAPIUSER13', 234 | Outstanding: 0, 235 | OutstandingCurrency: 'EUR', 236 | TodayPnL: 0, 237 | TodayPnLCurrency: 'EUR', 238 | YesterdayPnL: 44.69, 239 | YesterdayPnLCurrency: 'EUR' 240 | } 241 | } 242 | =end 243 | ``` 244 | 245 | 246 | ### Get History Statement 247 | 248 | ```ruby 249 | asianodds.get_history_statement 250 | ``` 251 | 252 | 253 | ### Get Bookies 254 | 255 | This method returns all bookies offered on the Asianodds books with their name and shortname/id. In all other methods a bookie is only referenced by its shortname (such as IBC). 256 | 257 | ```ruby 258 | asianodds.get_bookies 259 | # { Code: 0, Data: [{ Id: IBC, IsFeedAvailable: true, Name: "IBCBET"}, {...}], Message: "" } 260 | ``` 261 | 262 | 263 | ### Get Leagues 264 | 265 | The get_leagues method returns all leagues offered on the Asianodds books, including the corresponding sports_type as well as an array of bookies offering bets in this league. 266 | 267 | ```ruby 268 | asianodds.get_leagues 269 | 270 | =begin 271 | { 272 | Code: 0, 273 | Message: "", 274 | Result: { 275 | Sports: [ 276 | { 277 | League: [ 278 | { 279 | Bookies: [ 280 | "IBC", 281 | "PIN", 282 | "ISN", 283 | "SIN", 284 | "SBO" 285 | ], 286 | LeagueId: 350374160, 287 | LeagueName: "EGYPT PREMIER LEAGUE", 288 | MarketTypeId: 0, 289 | Since: 1493305406042 290 | } 291 | ], 292 | SportsType: 1 293 | } 294 | ] 295 | } 296 | } 297 | =end 298 | ``` 299 | 300 | 301 | ### Get Sports 302 | 303 | This method returns all the sports offered on the Asianodds books. Currently Football (Soccer) and Basketball are offered. All sports are stored as hashes in the data array. 304 | 305 | ```ruby 306 | asianodds.get_sports 307 | # { Code: 0, Data: [{ Id: 1, Name: "Football" }, { Id: 2, Name: "Basketball" }], Message: "" } 308 | ``` 309 | 310 | 311 | ### Get User Information 312 | 313 | ```ruby 314 | asianodds.get_user_information 315 | 316 | =begin 317 | { 318 | Code: 0, 319 | Message: "", 320 | Result: { 321 | ActiveBookies: [ 322 | "IBC", 323 | "SBO", 324 | "SIN", 325 | "ISN", 326 | "PIN", 327 | "GA" 328 | ], 329 | BaseCurrency: null, 330 | CreationDate: 1472636844000, 331 | DefaultStake: 0, 332 | ExpiryDate: 4102444800000, 333 | ExternalIp: "88.72.3.57", 334 | OddsType: "MY", 335 | Status: "Active", 336 | UserId: "WEBAPIUSER13" 337 | } 338 | } 339 | =end 340 | ``` 341 | 342 | 343 | ### Get Bet History Summary 344 | 345 | ```ruby 346 | asianodds.get_bet_history_summary 347 | ``` 348 | 349 | 350 | ### Get Matches 351 | 352 | ```ruby 353 | asianodds.get_matches 354 | ``` 355 | 356 | 357 | ### Get Placement Info 358 | 359 | ```ruby 360 | asianodds.get_placement_info 361 | 362 | =begin 363 | { 364 | Code: 0, 365 | Message: "", 366 | Result: { 367 | OddsPlacementData: [ 368 | { 369 | AwayName: "Manchester United", 370 | AwayScore: 0, 371 | Bookie: "IBC", 372 | Code: 0, 373 | Currency: "EUR", 374 | GameType: "X", 375 | HDPorGoal: "", 376 | HomeName: "Manchester City", 377 | HomeOrAwayOrDraw: "H", 378 | HomeScore: 0, 379 | IsFullTime: true, 380 | LeagueName: "*ENGLISH PREMIER LEAGUE", 381 | MarketTypeId: 1, 382 | MaximumAmount: 5491, 383 | Message: null, 384 | MinimumAmount: 4, 385 | OddPlacementId: "1297190352", 386 | Odds: 1.92, 387 | OddsFormat: "00", 388 | Rejected: false, 389 | SportsType: 1 390 | }, 391 | {...} 392 | ] 393 | } 394 | } 395 | =end 396 | ``` 397 | 398 | 399 | ### Place a New Bet 400 | 401 | ```ruby 402 | asianodds.place_bet 403 | ``` 404 | 405 | 406 | 407 | ## Original API Documentation 408 | 409 | For more information on the original API, please refer to the full documentation: https://asianodds88.com/documentation/ 410 | 411 | 412 | ## Examples 413 | 414 | Please get in contact to showcase your examples here. 415 | 416 | 417 | ## TODOS 418 | 419 | - [ ] Develop logic to re-signin automatically if logout is discovered 420 | - [ ] Write proper mini-tests to ensure test coverage & error-handling 421 | - [ ] Enable custom IDs for easier get_bet_by_reference lookup 422 | - [ ] Improving get_feeds response to format odds and providers nicely (currently string) 423 | - [ ] Improve the get and place bet workflow 424 | - [ ] Enable full date hand-overs for the "since" parameter and convert into milliseconds 425 | - [x] Wait for more feature requests 426 | 427 | 428 | ## Contributing 429 | 430 | Bug reports and pull requests are welcome on GitHub at https://github.com/Jan17392/asianodds. 431 | 432 | 433 | ## Copyright 434 | 435 | MIT License 436 | 437 | Copyright (c) 2017 Jan Runo 438 | 439 | Permission is hereby granted, free of charge, to any person obtaining a copy 440 | of this software and associated documentation files (the "Software"), to deal 441 | in the Software without restriction, including without limitation the rights 442 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 443 | copies of the Software, and to permit persons to whom the Software is 444 | furnished to do so, subject to the following conditions: 445 | 446 | The above copyright notice and this permission notice shall be included in all 447 | copies or substantial portions of the Software. 448 | 449 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 450 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 451 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 452 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 453 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 454 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 455 | SOFTWARE. 456 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | task :default => :spec 3 | -------------------------------------------------------------------------------- /asianodds.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path("../lib", __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require "asianodds/version" 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "asianodds" 8 | spec.version = Asianodds::VERSION 9 | spec.authors = ["Jan Runo"] 10 | spec.email = ["jan.runo@whu.edu"] 11 | 12 | spec.summary = %q{A wrapper for the Asianodds web API for automated sports trading} 13 | spec.description = %q{Asianodds Disclaimer: This gem is not officially developed by Asianodds and does not belong in any way to the Asianodds service, nor is it supported by their development team and all rights to accept or deny bets made with this gem remain with Asianodds. 14 | This gem is a wrapper for the Asianodds Web API. In order to use this gem you need to apply for a Web API account with Asianodds (api@asianodds88.com). Please keep in mind that your regular Asianodds user (for the Web Interface) does not work for your API account and vice versa. 15 | The purpose of the gem is to preconfigure all API calls to make your life as easy as just calling one method. You won"t need to MD5 hash your password (as Asianodds requests) and the gem assumes smart preconfigs for your calls, so they will work even without passing in required parameters. Still, it has the same flexibility as the original API without limitations. 16 | With just three lines of code you will be able to start placing real-time bets with multiple bookmakers and automate your trading strategies. 17 | For more information on the usage of the gem, please visit the github page 18 | } 19 | spec.homepage = "https://github.com/Jan17392/asianodds" 20 | spec.license = "MIT" 21 | 22 | # Prevent pushing this gem to RubyGems.org. To allow pushes either set the "allowed_push_host" 23 | # to allow pushing to a single host or delete this section to allow pushing to any host. 24 | if spec.respond_to?(:metadata) 25 | spec.metadata["allowed_push_host"] = "https://rubygems.org" 26 | else 27 | raise "RubyGems 2.0 or newer is required to protect against " \ 28 | "public gem pushes." 29 | end 30 | 31 | spec.files = `git ls-files -z`.split("\x0").reject do |f| 32 | f.match(%r{^(test|spec|features)/}) 33 | end 34 | spec.bindir = "exe" 35 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 36 | spec.require_paths = ["lib"] 37 | 38 | spec.add_dependency "faraday" 39 | spec.add_dependency "json" 40 | end 41 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "asianodds" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start 15 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /lib/asianodds.rb: -------------------------------------------------------------------------------- 1 | require_relative "asianodds/version" 2 | require_relative "asianodds/login" 3 | -------------------------------------------------------------------------------- /lib/asianodds/login.rb: -------------------------------------------------------------------------------- 1 | require 'faraday' 2 | require 'json' 3 | require 'digest/md5' 4 | 5 | BASE_API_URL = 'https://webapi.asianodds88.com/AsianOddsService' 6 | 7 | module Asianodds 8 | class Login 9 | 10 | attr_reader :code, :ao_token, :ao_key, :base_url, :successful_login, :message 11 | 12 | # The API has a very standard request format for get requests - Use this one to stay DRY 13 | def get_request(route) 14 | response = Faraday.get "#{@base_url}/#{route}", {}, { 15 | 'Accept': 'application/json', 16 | 'AOToken': @ao_token, 17 | 'AOKey': @ao_key 18 | } 19 | return JSON.parse(response.body, :symbolize_names => true) 20 | end 21 | 22 | # The API has a very standard request format for post requests - Use this one to stay DRY 23 | def post_request(route, body) 24 | response = Faraday.post "#{@base_url}/#{route}", 25 | body, 26 | { 27 | 'Accept': 'application/json', 28 | 'Content-Type': 'application/json', 29 | 'AOToken': @ao_token 30 | } 31 | 32 | return JSON.parse(response.body, :symbolize_names => true) 33 | end 34 | 35 | # Initialize the user with a username and password, as well as hashed password as requested from AO 36 | def initialize(user, password) 37 | @user = user 38 | @password = password 39 | @password_md5 = Digest::MD5.hexdigest(@password) 40 | @ao_token = 'default' 41 | @ao_key = 'default' 42 | @base_url = BASE_API_URL 43 | login 44 | end 45 | 46 | # Log the user in to receive a token and key 47 | def login 48 | response = get_request("Login?username=#{@user}&password=#{@password_md5}") 49 | @code = response[:Code] 50 | @ao_token = response[:Result][:Token] 51 | @ao_key = response[:Result][:Key] 52 | @base_url = response[:Result][:Url] 53 | @successful_login = response[:Result][:SuccessfulLogin] 54 | 55 | # All logged in users need to be registered with a token and key 56 | if @successful_login 57 | @message = "You successfully logged in - registering..." 58 | register 59 | else 60 | @message = response[:Result][:TextMessage] 61 | end 62 | end 63 | 64 | # With the token and key the user has to be registered 65 | def register 66 | response = get_request("Register?username=#{@user}") 67 | response[:Result][:Success] == true ? @message = response[:Result][:TextMessage] : @message = "Registration failed" 68 | end 69 | 70 | # Before executing any request which requires a logged in user (all), check for login 71 | # Check for all following requests whether user is logged in and if not, log her in 72 | def loggedin? 73 | if @ao_token 74 | response = get_request('IsLoggedIn') 75 | return response[:Result][:CurrentlyLoggedIn] ? true : false 76 | else 77 | return false 78 | end 79 | end 80 | 81 | # Log the user out. In order for this to work, the user must be logged in 82 | def logout 83 | response = get_request('Logout') 84 | return response[:Result] 85 | end 86 | 87 | # Get all the Match Feeds (odds, status, etc.) based on the settings provided 88 | def get_feeds(attributes) 89 | attributes[:sports_type].nil? ? sports_type = 1 : sports_type = attributes[:sports_type] 90 | attributes[:market_type].nil? ? market_type = 1 : market_type = attributes[:market_type] 91 | attributes[:bookies].nil? ? bookies = 'ALL' : bookies = attributes[:bookies] 92 | attributes[:leagues].nil? ? leagues = 'ALL' : leagues = attributes[:leagues] 93 | attributes[:odds_format].nil? ? odds_format = '00' : odds_format = attributes[:odds_format] 94 | attributes[:since].nil? ? since = '0' : since = attributes[:since] 95 | 96 | if loggedin? 97 | return get_request("GetFeeds?sportsType=#{sports_type}&marketTypeId=#{market_type}&bookies=#{bookies}&leagues=#{leagues}&oddsFormat=#{odds_format}&since=#{since}") 98 | else 99 | #raise NotLoggedIn 100 | end 101 | end 102 | 103 | # Get all active bets (= running, outstanding, finished) of the current user 104 | def get_bets 105 | if loggedin? 106 | return get_request('GetBets') 107 | else 108 | #raise NotLoggedIn 109 | end 110 | end 111 | 112 | # You can also request a single bet with its reference - useful to check whether the bet was accepted by the bookmaker 113 | def get_bet_by_reference(bet_reference) 114 | if loggedin? 115 | return get_request("GetBetByReference?betReference=#{bet_reference}") 116 | else 117 | #raise NotLoggedIn 118 | end 119 | end 120 | 121 | # A subset of GetBets which returns only the currently running bets 122 | def get_running_bets 123 | if loggedin? 124 | return get_request('GetRunningBets') 125 | else 126 | #raise NotLoggedIn 127 | end 128 | end 129 | 130 | # A subset of GetBets which returns only the currently not running bets 131 | def get_non_running_bets 132 | if loggedin? 133 | return get_request('GetNonRunningBets') 134 | else 135 | #raise NotLoggedIn 136 | end 137 | end 138 | 139 | # Get the users account summary (i.e. users currency, users credit, outstanding amount, P&L's etc.) 140 | def get_account_summary 141 | if loggedin? 142 | return get_request('GetAccountSummary') 143 | else 144 | #raise NotLoggedIn 145 | end 146 | end 147 | 148 | # Get a transaction history of a certain time-frame - defaults to the last 7 days 149 | def get_history_statement(attributes) 150 | attributes[:from_date].nil? ? from_date = (Date.today - 7).strftime('%m/%d/%Y') : from_date = attributes[:from_date] 151 | attributes[:to_date].nil? ? to_date = Date.today.strftime('%m/%d/%Y') : to_date = attributes[:to_date] 152 | attributes[:bookies].nil? ? bookies = 'ALL' : bookies = attributes[:bookies] 153 | if loggedin? 154 | return get_request("GetHistoryStatement?from=#{from_date}&to=#{to_date}&bookies=#{bookies}&shouldHideTransactionData=false") 155 | else 156 | #raise NotLoggedIn 157 | end 158 | end 159 | 160 | # Get the list of bookmakers available on the Asianodds platform 161 | def get_bookies 162 | if loggedin? 163 | return get_request('GetBookies') 164 | else 165 | #raise NotLoggedIn 166 | end 167 | end 168 | 169 | # Get user setting, such as account status, ip address, username etc. 170 | def get_user_information 171 | if loggedin? 172 | return get_request('GetUserInformation') 173 | else 174 | #raise NotLoggedIn 175 | end 176 | end 177 | 178 | # Get all the transactions of a specific day (defaults to yesterday) including win and loss values 179 | def get_bet_history_summary(attributes) 180 | attributes[:date].nil? ? date = (Date.today - 1).strftime('%m/%d/%Y') : date = attributes[:date] 181 | attributes[:bookies].nil? ? bookies = 'ALL' : bookies = attributes[:bookies] 182 | if loggedin? 183 | return get_request("GetBetHistorySummary?date=#{date}&bookies=#{bookies}") 184 | else 185 | #raise NotLoggedIn 186 | end 187 | end 188 | 189 | # Get the ids for all leagues for a certain sport (football as default) 190 | def get_leagues(attributes) 191 | attributes[:sports_type].nil? ? sports_type = 1 : sports_type = attributes[:sports_type] 192 | attributes[:market_type].nil? ? market_type = 1 : market_type = attributes[:market_type] 193 | attributes[:bookies].nil? ? bookies = 'ALL' : bookies = attributes[:bookies] 194 | attributes[:since].nil? ? since = '0' : since = attributes[:since] 195 | if loggedin? 196 | return get_request("GetLeagues?sportsType=#{sports_type}&marketTypeId=#{market_type}&bookies=#{bookies}&since=#{since}") 197 | else 198 | #raise NotLoggedIn 199 | end 200 | end 201 | 202 | # Get the ids for the sports offered by Asianodds (football and basketball as of today) 203 | def get_sports 204 | if loggedin? 205 | return get_request('GetSports') 206 | else 207 | #raise NotLoggedIn 208 | end 209 | end 210 | 211 | # Get all the Matches (!= feeds) based on the settings provided 212 | def get_matches(attributes) 213 | attributes[:sports_type].nil? ? sports_type = 1 : sports_type = attributes[:sports_type] 214 | attributes[:market_type].nil? ? market_type = 1 : market_type = attributes[:market_type] 215 | attributes[:bookies].nil? ? bookies = 'ALL' : bookies = attributes[:bookies] 216 | attributes[:leagues].nil? ? leagues = 'ALL' : leagues = attributes[:leagues] 217 | attributes[:since].nil? ? since = '0' : since = attributes[:since] 218 | 219 | if loggedin? 220 | return get_request("GetMatches?sportsType=#{sports_type}&marketTypeId=#{market_type}&bookies=#{bookies}&leagues=#{leagues}&since=#{since}") 221 | else 222 | #raise NotLoggedIn 223 | end 224 | end 225 | 226 | # Get information about the odds, minimum and maximum amounts to bet etc. for a certain match 227 | # THIS IS A POST REQUEST 228 | def get_placement_info(attributes) 229 | body = { 230 | "GameId": attributes[:game_id], 231 | "GameType": attributes[:game_type], 232 | "IsFullTime": attributes[:is_full_time], 233 | "Bookies": attributes[:bookies], 234 | "MarketTypeId": attributes[:market_type], 235 | "OddsFormat": attributes[:odds_format], 236 | "OddsName": attributes[:odds_name], 237 | "SportsType": attributes[:sports_type] 238 | }.to_json 239 | 240 | if loggedin? 241 | return post_request('GetPlacementInfo', body) 242 | else 243 | #raise NotLoggedIn 244 | end 245 | end 246 | 247 | # Get information about the odds, minimum and maximum amounts to bet etc. for a certain match 248 | # THIS IS A POST REQUEST 249 | def place_bet(attributes) 250 | body = { 251 | "GameId": attributes[:game_id], 252 | "GameType": attributes[:game_type], 253 | "IsFullTime": attributes[:is_full_time], 254 | "Bookies": attributes[:bookies], 255 | "MarketTypeId": attributes[:market_type], 256 | "OddsFormat": attributes[:odds_format], 257 | "OddsName": attributes[:odds_name], 258 | "SportsType": attributes[:sports_type], 259 | "BookieOdds": attributes[:bookie_odds], 260 | "Amount": attributes[:amount] 261 | }.to_json 262 | 263 | if loggedin? 264 | # Always needs to be called before placing the bet 265 | get_placement_info(attributes) 266 | return post_request('PlaceBet', body) 267 | else 268 | #raise NotLoggedIn 269 | end 270 | end 271 | 272 | 273 | end 274 | end 275 | -------------------------------------------------------------------------------- /lib/asianodds/version.rb: -------------------------------------------------------------------------------- 1 | module Asianodds 2 | VERSION = "1.0.0" 3 | end 4 | -------------------------------------------------------------------------------- /test/login/login_test.rb: -------------------------------------------------------------------------------- 1 | require './test/test_helper' 2 | 3 | USER = "webapiuser13" 4 | PASSWORD = "G,'{3M+U[$uwcf4+" 5 | 6 | class AsianoddsLoginTest < Minitest::Test 7 | def test_exists 8 | assert Asianodds::Login 9 | end 10 | 11 | 12 | # Check that the fields are accessible and the login was successful 13 | def test_login 14 | @user = Asianodds::Login.new(USER, PASSWORD) 15 | 16 | assert @user.code == 0 17 | assert_equal 0, @user.code 18 | 19 | 20 | p @user.loggedin? 21 | 22 | end 23 | 24 | # TODO: Write a test to check that user is logged in and registered if no error occurs 25 | def test_loggedin 26 | 27 | end 28 | 29 | # TODO: Check the current budget method to return the right value 30 | 31 | # TODO: Check that running bets return the right length of running bets 32 | 33 | # TODO: Place bet should successfully register a new bet with the system 34 | end 35 | -------------------------------------------------------------------------------- /test/spec.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require './lib/asianodds/login' 3 | 4 | describe "Login" do 5 | before do 6 | @user = Asianodds::Login.new("webapiuser13", "G,'{3M+U[$uwcf4+") 7 | p @user 8 | @invalid_user = Asianodds::Login.new("XXXXX", "XXXXX") 9 | p @invalid_user 10 | end 11 | 12 | it "A valid User returns the valid login code 0" do 13 | @user.code.must_equal 0 14 | end 15 | 16 | #it "An invalid User returns the invalid login code -1" do 17 | # @invalid_user.code.must_equal -1 18 | #end 19 | 20 | #it "a logged in and registered user must return true for logged in" do 21 | # @user.loggedin?.must_equal true 22 | #end 23 | 24 | #it "an invalid user cannot be registered and must return false for logged in" do 25 | # @invalid_user.loggedin?.must_equal false 26 | #end 27 | 28 | # it "Calling GetFeeds without being logged in should raise an error" do 29 | # @invalid_user.get_feeds.must_raise RuntimeError 30 | # end 31 | 32 | # it "Sending a valid GetFeeds request should return a list of feeds" do 33 | # x = @user.get_feeds({}) 34 | # end 35 | 36 | #it "get_bet_by_reference should return a bet result for a valid reference" do 37 | # x = @user.get_bet_by_reference("WA-1493188766490") 38 | # p x 39 | #end 40 | 41 | #it "calling get_sports should return a list of sports" do 42 | # x = @user.get_sports 43 | # p x 44 | #end 45 | 46 | # it "A valid get placement info post request returns a valid object" do 47 | # x = @user.get_placement_info({ 48 | # game_id: -377682094, 49 | # game_type: "X", 50 | # is_full_time: 1, 51 | # market_type: 1, 52 | # odds_format: "00", 53 | # odds_name: "HomeOdds", 54 | # sports_type: 1 55 | # }) 56 | 57 | # p x 58 | # end 59 | 60 | it "A valid place bet post request returns a valid object" do 61 | x = @user.place_bet({ 62 | game_id: -377682094, 63 | game_type: "X", 64 | is_full_time: 1, 65 | market_type: 1, 66 | odds_format: "00", 67 | odds_name: "HomeOdds", 68 | sports_type: 1, 69 | amount: 50, 70 | bookie_odds: "PIN: 2.57,PIN: 3.06,PIN: 3.23" 71 | }) 72 | 73 | p x 74 | end 75 | end 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require './lib/asianodds' 2 | require 'minitest/autorun' 3 | 4 | 5 | --------------------------------------------------------------------------------