We made a tool to record the moves of a game from a video, and want to use it to broadcast tournament games on OGS. We made a system that sends clicks to the web browser to record moves, but found that it is difficult to make it reliable.
Is there any plan to add API support for editing a game? It would be really great for our use case.
We may find that you can already do this, I’m not sure off the top of my head.
But I do want to ask one point of clarification: when you say “enter moves” I think of “a game in progress, entering moves as a player”. But when you say “edit a game” I think of a demo board or a review.
This is likely a language thing - can you clarify the exact situation you have in mind?
Yes, it is a demo board. Artificial scribe for tournaments. It may navigate the game to create a variation as well, in case there was a recognition mistake.
I searched the API there: https://apidocs.online-go.com/, and could not find anything to enter moves. But if it is already possible, then it would be great.
You can certainly play moves to a demo board (or real game board) using a script. The trick is that it’s through the websocket, not the REST API. And that comes with complications I recommend you get familiar with viewing websocket messages in the Network tab of the browser if you want to learn the API - docs are sparse.
The key message is "review/append", but you’ll need to authenticate first. Here is a working script that adds one branch to the tree:
import asyncio
import json
import websockets
# change this to Prod server when your script is ready
URI = "wss://beta.online-go.com"
REVIEW_ID = 505
# Let me know if I can help find this. Getting it is a bit tricky, quick and dirty
# way is to just manually copy it out of your Browser Network inspector
AUTHENTICATION_MESSAGE = ["authenticate", { ...redacted... }]
async def get_review_response(websocket):
# while loop is used to flush messages we don't care about
while True:
message = await websocket.recv()
try:
data = json.loads(message)
if isinstance(data, list) and len(data) == 2 and isinstance(data[0], str):
# this message is sent whenever the demo is modified
if data[0] == f"review/{REVIEW_ID}/r":
return data
except json.JSONDecodeError:
pass
async def connect_to_websocket():
# Replace with Production server once your script is ready
uri = "wss://beta.online-go.com"
async with websockets.connect(uri) as websocket:
# Authenticate
await websocket.send(json.dumps(AUTHENTICATION_MESSAGE))
# Connect to review
await websocket.send(json.dumps(["review/connect", {"review_id": REVIEW_ID}]))
# Send message
await websocket.send(json.dumps([
"review/append",
# the "m" string is the important part. You can add arbitrary variations this way
# the letters are SGF coordinates so "jj" is tengen
{"f":0,"t":"","m":"pddppqddfqcnpjofjj","k":{},"review_id": REVIEW_ID}
]))
# Print the demo update message to confirm changes
response = await get_review_response(websocket)
print(f"Received from server: {response}")
# run the event loop once
asyncio.run(connect_to_websocket())
The result is I now have tengen placed in Demo Board