I need to generate a protocol number and switch to purecloud, but I can only generate the number when the chat has actually started, is there any way to do this? can I know when the "start chat" button was clicked?
That doesn't look like valid JavaScript to me; it's just a string. I would expect trying to call a function named val() on a string will throw an error as that's not a function that exists on strings. If this is a special syntax of your frontend framework, check with the provider of that framework to troubleshoot why it's not providing values.
Aside from that, I would refer to the documentation I linked above for a sample of how to start a chat with pre-populated information. It has a full example showing how to accomplish that. You can also refer to the Developer Tools Web Chat tool to test custom data. https://developer.mypurecloud.com/developer-tools/#/webchat
I think the description of startChat command parameters is inaccurate.
When using a standard Chat Registration form, I think the parameters will be inside a form structure:
CXBus.command('WebChatService.startChat', { form: {firstname: ..., lastname: ..., email: ..., subject: ...}, userData: {}}).
I don't know if it is supported to call the startChat command directly.
A former documentation here mentions that it should not be invoked manually, whereas the last doc here does not mention that constraint/limitation.
before command
I think Product Management and Engineering prefer that customizations leverage the before command.
The same approach than what is described here, but with WebChatService.startChat instead of WebChat.open (what the example shows).
You would have to modify the function parameter - options in the example. I believe the same comment I made in 1) will apply - modifying options.form.firstname, options.form.lastname, ....