This article will be more about concepts than code. I’m not sure how ebay, and indirectly Impact the affiliate network, feel about programmatic website interaction. I’m also writing this well after I had created a working version of the program, so I’m working off of what information I gather after the fact.
At one point, ebay was converting their affiliate linking system to a new format. The issue I had was hundreds of old links I had to re-create. Some aspects aren’t easily automatable like going through YouTube’s video descriptions. I don’t trust 3rd party tools linking to my YouTube account and I haven’t tried to roll my own. Though, I had wanted to make the process as fast as possible.
Maybe ebay had a webservice to generate new links? Not that I could find. I even tried contacting support… nope.
I set out with the goal of automating as much of the link generation process as possible through their affiliate website.
My tool of choice was Visual Studio, C#, and WinForms. As I started with WinForms back in the 1990s with Visual Basic… I find it much more enjoyable to use than WPF or whatever other GUI types they’ve come up with since then. I have at least tried tried them, but my goal here was development speed. Go with what you know.
After an initial round of experimentations, I ended up using a different web browser control called “webview2” that allowed me to do interactions with what appeared to be React based Javascript. From what I can remember the default browser tool was too old to render ebay’s site properly.
The finished interface. |
Some steps in the website flow couldn’t be fully automated like login, at least with a realistic amount of development time. I can’t recall the details.
The process goes like this:
- Click the login button to bring the user to the login page.
- User gets into the site and is brought to the default affiliate page.
- Automatically jumps to the link generation page, but I have a button incase it doesn’t work.
- On the link generation page the user needs to select a campaign once. I had issues automating that so it ended up not being worth the time to figure it out.
- User inputs a search term.
- User clicks the “Generate Link Text” button.
- The related webpage link field is filled with a properly constructed ebay site link.
- The webpage “Generate Link” button is executed.
- Once the link is generated the system attempts to click the shorten link checkbox.
- The shorten link checkbox itself is an asynchronous operation so it takes some time to happen.
- I ended up going the simple route by sleeping the processing thread, so it’s not 100% perfect timing. Not worth the time and effort getting it perfect because I can toggle the shorten link checkbox myself when that happens. At least that’s how I remember it. I might have fixed the timing, but I haven’t used the tool lately.
- When it does work the short link is pushed into the clipboard automatically.
At that point it was good enough to mostly give me a process of: type in a search term and then click one button to make a short link. Otherwise it would be more clicking and constructing ebay links by hand that I would have to paste into their affiliate link generation page.
I find it odd that ebay doesn’t offer a process flow of easily making short affiliate links for search terms because products on ebay are changing constantly. Very rarely would I link a single listing.
The application after it’s gone through one link being generated. |
The major time in development was trying to manipulate React based Javascript and objects on these pages. Not talked about here is all of my examining of the live pages in an attempt to find the right elements that I could actually manipulate.
A few important aspects to the code you might find helpful:
txtEbayCreatedLink.Text = txtEbayBaseURL.Text
+ System.Web.HttpUtility.UrlEncode(txtEbaySearchTerm.Text);
Once the link is generated I make sure there are not any special characters in the search term. Those get cleaned up with UrlEncode.await browserControl.CoreWebView2.ExecuteScriptAsync("...");
The ExecuteScriptAsync function is the best way to interact with the DOM of the current webpage. I used it with await for simplicity and would space the timing a bit with Thread.Sleep(). Keep in mind all of this was running in it’s own process so it doesn’t lag out the UI.
You can basically push Javascript code into the page and execute it with another Javascript call. I chose to write functions and then run them with the proper element IDs or classes.
function changeValue(input, value) {
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype, 'value'
).set;
nativeInputValueSetter.call(input, value);
var inputEvent = new Event('input', { bubbles: true });
input.dispatchEvent(inputEvent);
}
To change a textbox value on the page I pushed in this function and then executed it on the proper element using changeValue(document.getElementById(‘element-name’), ‘value’);.
await wvEbay.CoreWebView2.ExecuteScriptAsync(
"document.getElementsByClassName('class-name')[0].click();");
To click the Generate Link button the the page I used that bit of Javascript code.
To click the checkbox and actually get it to work was a challenge. My Javascript function was this:
function changeCheckValue(e) {
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
nativeInputValueSetter.call(e, !e.checked);
var inputEvent = new Event('input', { bubbles: true });
e.dispatchEvent(inputEvent);
e.click();
}
Again, you get the element id and push it into the function.
await wvEbay.CoreWebView2.ExecuteScriptAsync("document.getElementsByClassName('class-name')[0].click();");
The last bit of Javascript does the clipboard push.
There is of course more going on with the program, but that’s the gist of it. Like I said, trying to get proper browser control interactions with Javascript that React generated was a pain, but I managed. I’d say that it ultimately did save me time and has continued to work. Though if they ever change or a URL or some of the page code it could break.