Real time API unreliable?

Hello,

I’m struggling a lot to make my bot play on OGS… and it seems in fact that the API is randomly refusing game/move calls (I haven’t tested all the other calls, but this is the most troublesome).
To make sure, I wrote a very simple script which directly plays moves on the diagonal (aa, bb, cc, …) from an empty position. On the human side of the game I use conditional moves to make sure the moves are answered instantly.
The script fails 9 times out of 10 (plays nothing)… and 1 time out of 10 it miraculously plays all the moves at once (as expected). I was curious so I added some time between moves and after some fails (nothing played) the script eventually plays some of the moves in the diagonal (not all of them though). For example, here’s what I got for 1ms (the bot is black and the last move of the diagonal is missing):

I also tried to create infinite loops to spam the move on the server… without success (the move is either played at the first instruction or never played)
So there’s definitely a problem on the server side…
Here some sample code I used:

        self.ws = websocket.WebSocketApp("wss://online-go.com/socket.io/?transport=websocket", on_message=self.on_message, on_error=self.on_error, on_close=self.on_close)
        # self.ws = websocket.WebSocketApp("wss://echo.websocket.org", on_message=self.on_message, on_error=self.on_error, on_close=self.on_close)


        # self.ws.run_forever(ping_interval=30)
        self.wst = threading.Thread(target=self.ws.run_forever, kwargs={'ping_interval': 30})
        self.wst.daemon = True
        self.wst.start()

        printt('Connecting to socketio...')
        conn_timeout = 5
        while not self.ws.sock.connected and conn_timeout:
            time.sleep(1)
            conn_timeout -= 1
        printt('Connected...')
        for l in 'abcdefghijklmnopqrs':
            msg = '42["game/move", {"auth": "######################", "game_id": 9083405, "move": "%s%s", "player_id": 432818}]' % (l,l)
            self.ws.send(msg.encode())
            time.sleep(0.001)

have you tried gtp2ogs? this is the official script for connecting bots to OGS.

Have you tried slowing down the requests to avoid potential rate limits?

I haven’t tried gtp2ogs as I’m not using gtp on my bot. The thing is that my bot is supposed to interact with the player (teaching agent), and as far as I know the gtp protocol is not designed to chat (you can send but not receive right?). The real time API is the main reason I want to lauch my bot on OGS.

If I slow down the script, it either plays nothing or 1 move (with the same failing rate of the previous script)

I’m giving a try to gtp2ogs. Of course gtp is not enough to create a chat interaction with the bot so I will have to edit it. But at least I’m able to play the game!
That being said, the bot I’m building is more complex than a simple gtp playing-only bot, so I need the process to be run separately (not spawned from gtp2ogs). As a workaround, I have implemented a dummy gtp bot I give to gtp2ogs, which then forward all the instruction to my main process. As a consequence, I can only 1 game at the same time. If gtp2ogs
accept a new challenge and spawn another dummy bot, the connection will rejected by the main process and the second game won’t be played.
Do I have a way to refuse all challenges once the bot is connected to a game?

I’m also experiencing problems with sending moves via the real time api.
I’m connecting to the API by fetching an access token from the oauth endpoint.

fetch(`${apiPath}/oauth2/token/`, {
  method: 'POST',
  body: `client_id=${clientId}&client_secret=${clientSecret}&grant_type=password&username=${username}&password=${password}`,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})
[...]
  fetch(`${apiPath}/api/v1/games/${gameId}/`, {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  })
    .then((res) => res.json())
    .then(({auth}) => {
[...]
        socket.emit('game/connect', {
          "player_id": playerId,
          "game_id": gameId,
          "chat": false
        })
      }
    );

All of this works fine and I receive gamedata and move events for the game, however i’m unable to send moves via game/move

    socket.emit('game/move', {
      "auth": accessToken,
      "game_id": gameId,
      "player_id": playerId,
      "move": "bb"
    });

No error or anything is thrown, just nothing happens at all

I’ve got exactly the same problem, and using exactly the same setup - I’ve tried to dig through the gtp2ogs calls and inspect the frames in chrome on online-go.com

The only thing different I see is that there seems to be a socket.emit of “authenticate” at some point, but I don’t know which “auth” that refers to? :frowning:

Someone please help?

I figured it out after some snooping on the main online-go.com site…

You need to call /api/v1/ui/config/ - in there is a “chat_auth” key… then after you connect to the websocket, emit an “authenticate” event with {"auth": chat_auth, "player_id": playerid, "username": username} - and now you can submit moves without actually needing to include the “auth” key.

1 Like