background

The company has a business, hope to arouse the third party customer service, automatically send a message, similar to Taobao return or exchange, arouse customer service will have information about the return or exchange process.

The road to solve

1. Ask a third party

Of course, the first step is to ask third-party customer service if they support this feature. Unfortunately, they don’t. The technical documentation has a preliminary evocation feature that automatically sends a greeting message, but this is only for the first time, and then no longer automatically sends.

This road is blocked, find another way.

2. Simulate user input

Since there is no ready – made method, only the curve to save the country.

Send automatically, of course, by letting the program simulate the user sending a message. I think this should be very simple, after calling up the client window, locate the input field, and then simulate the return on the line. The situation is as follows:

But never thought, unknowingly into a huge pit.

A. Simulate input attempts

Customer service chat box in an IFrame, input box has ID, positioning is not a problem. Happy to set a value for him, and then simulate a carriage return, run! Then, the car rolled over, and the input box had an input message, but it didn’t go out.

// Set the message to be sent
var inpEle = window.frames['chat'].document.getElementById('_MEIQIA_INPUT')
inpEle.value = 'Test information'
// Simulate enter
var event = document.createEvent('Event')
event.initEvent('keydown'.true.false)
event = Object.assign(event, {
  ctrlKey: false.metaKey: false.altKey: false.which: 13.keyCode: 13.key: 'Enter'.code: 'Enter'
})
inpEle.focus()
inpEle.dispatchEvent(event)
Copy the code

B. Is it because the carriage return event was unsuccessful?

Listen for the KeyDown event, print out the content, and see if the carriage return works.

inp.onkeydown = function(event) {
  console.log(event.keyCode)
}
Copy the code

It turns out that it works, printing keyCode 13.

C. Test the input and carriage return separately

  • Remove the carriage return simulation and try manually pressing the keyboard when the input box is in focus. KeyCode was printed on the console, but the message didn’t go out…

  • Set a delay for the analog carriage return, and then enter the text in the input box, such as the delay to let the analog carriage return to submit send. The results were found to be feasible.

    … (The above process involves experimenting with various methods of simulating input and carriage returns, as well as a melancholy cigarette)…

The value entered in the simulation is invalid. The carriage return sends a null value, which does not have any action. But why the analog input is invalid is a mystery.

D. Stumbled upon some clues during initialization

There are several times to refresh the page, suddenly automatic send success! Just refresh the page and run it the first time, it works, and then it doesn’t work again. Why does it automatically send success after refreshing? It was already evening, and I went home to think about it all night. Suddenly enlightened, is this chat control in the local value, so as long as the value is found, will send? And this value is dynamically generated on input, so I can’t fire the input event with mock input, so I didn’t save this value, okay? I want to test and look forward to the next day.

Rushed to the company, can’t wait to see the next localStorage, sure! Inside the input box has entered the value! That’s amazing, so should I just change this value and simulate a carriage return commit? Victory seems to be ahead!

After a few attempts (which took me most of the morning), it turns out that the localStorage cache value only serves to automatically fill in the input box for the next initialization, remembering the last message the user didn’t send. Therefore, it is not used as an egg.

At this time, I told the product little sister that it could only be sent automatically in the first time because of difficulties at present, and not after that. Let’s see if it can be sent automatically when the conversation is over. If so, it doesn’t matter.

Unfortunately, ending a conversation, but not sending a message again, restarting a conversation is not reinitialized and will not be automatically sent. So I re-invested in research, I refuse to accept, can find a way to achieve automatic send!

E. Calmly analyze why the analog input is invalid

Back to the way I was before, I knew that the root cause was that the simulation input was invalid, but why was that invalid? I set both the value and innerText of the textarea, but it was always null in the control.

inpEle.innerText = 'Test message'
inpEle.value = 'Test message'
Copy the code

Even weirder, when the simulation is finished and focused on the input field, as soon as I click somewhere else, the input field is empty! I think you should have values stored in a variable when you input. Since analog inputs in Sandbox Browsers cannot trigger input events, natural variables get no values. This is a dead end. I didn’t give up. I wanted to try to see what functions they bound to the input event, so I went to the browser’s EventListener to get the function definition.

The definition is in a compressed JS, I have mentally prepared, I tried to unpack it out.

F. Dawn

Just as I was about to decompress, I saw a dazzling keyword, React! What does that mean? The react-dom.product.min.js file is a react-dom.product.min.js file. The react-dom.product.min.js file is a react-dom.product.min.js file. I don’t know React, but I know Vue. There are some similarities between Vue and React DOM.

However, I did not rush to find the source file. Instead, I searched for “React Input simulation”. I was so touched by this problem that I didn’t even think to find the problem directly.

Then, on the first page of the search list, came an article:

It gave me the answer I was looking for, thanks to the “wild man with the laser cannon.” It describes a situation that is almost identical to the one I encountered, where the simulated input is reset to null. I didn’t study React, but it was something like bidirectional binding that blocked analog input.

At this point, the problem was solved.

I excitedly told the product sister, the problem broke through! Automatic sending, unlimited time, unlimited content.

conclusion

The solution of this problem is one of the many problem-solving experiences, but it is very interesting and also has a sense of accomplishment, including frustration, depression, excitement, expectation, curiosity, disobedience, hard work, and finally excited complex feelings, recorded for later nothing to review.

In addition, I accidentally saw a lot of knowledge of JS DOM operation, and found that this is very lack of knowledge. The more I know, the more I feel ignorant.

Oh, also, baidu find those JS answers, 80% are jQuery, few native JS, almost to die, fortunately, also can go up Google. Gratitude!