Let's reverse-engineer Omegle. PROPERLY! ======================================== I didn't manage to find a proper, detailed (and up-to-date) reverse-engineerment of Omegle's text chat protocol on the interwebs, so here, have one! The responses are beautified and the query strings split up and URI-decoded for readability. Note that "query string" refers to parameters encoded into the URL and "form data" to parameters in the request body, which don't have to be encoded. TODO: * Find out how college authorization works * Find out how WebRTC video streaming works * Generally phrase things better Used Request Headers: ``` Accept: application/json Accept-Encoding: gzip,deflate Accept-Language: en-US;q=0.6,en;q=0.4 Connection: keep-alive DNT: 1 Host: front9.omegle.com Origin: http://www.omegle.com Referer: http://www.omegle.com/ User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36 ``` Status ------ Pro-Tip: Fetch this first and then use one of the servers listed for future connections. You can just connect to the main server here. `GET http://[server].omegle.com/status` Query String: * `nocache = 0.4695589093025774` (optional, random nonce to prevent cached responses from being sent) * `randid = CHPZGFFW` (optional, see section "Start") Response: ``` { "count": 20840, (connection count, people say it's faked) "force_unmon": true, (see section "Getting b&") "antinudeservers": [ "waw3.omegle.com", "waw2.omegle.com", "waw1.omegle.com" ], "antinudepercent": 1.0, "spyQueueTime": 0.0, (if spyQueueTime is larger, there are more spies than spyees online, which the client uses to suggest a mode) "spyeeQueueTime": 2.173300027847, "timestamp": 1409233880.7561221, "servers": [ "front5.omegle.com", "front1.omegle.com", "front2.omegle.com", "front9.omegle.com", "front6.omegle.com", "front7.omegle.com", "front8.omegle.com", "front4.omegle.com", "front3.omegle.com" ] } ``` Start ----- This actually starts the chat and gets us our client ID. If you want to start a question/spy chat, send `wantsspy = 1` for spyee mode and `ask = blah` for spyer mode. `POST http://[server].omegle.com/start` Query String: * `rcs = 1` * `firstevents = 1` * `m = 1` (imitate a mobile connection, shouldn't really matter) * `lang = en` (two-char language code) * `randid = CHPZGFFW` (this is really just a random string containing 2-9 and A-Z) * `spid =` (some kind of ID from Adobe Stratus, never used though) * `topics = ["asdf", "test", ...]` (optional, for default mode) * `wantsspy = 1` (for spyee mode) * `ask = blah question?` (for spyer mode) * `cansavequestion = 1` (Omegle may reuse your question) * `group = unmon` (join the unmonitored section instead) Response: ``` { "events": [ ...see section "Events"... ], "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" (needed for all subsequent requests) } ``` Events ------ This one uses long polling, which means that the server will be blocking the connection until an event happens. You can handle this with some async magic and long timeouts. `POST http://[server].omegle.com/events` Form Data: * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` Response: ``` [ [...see below...], ... ] ``` ### Status events * `["waiting"]` (the server is searching for strangers) * `["connected"]` (you can start sending messages now) * `["statusInfo", {...stripped...}]` (see section "Status") ### Notifications * `["commonLikes", ["asdf", "test", ...]]` (the shared topics from the ones you've passed) * `["serverMessage", "blah"]` (most likely `You both speak the same language.`) * `["recaptchaRequired", "[challenge]"]` (see section "ReCAPTCHAs") * `["recaptchaRejected", "[challenge]"]` * `["identDigests", "blah,blah,blah"]` (probably just used for sharing logs) ### Error events (disconnects you) * `["error", "blah blah error text!"]` (general error message) * `["connectionDied"]` (some technical error) * `["antinudeBanned"]` (see section "Getting b8") ### Chat events * `["typing"]` (the stranger started typing) * `["stoppedTyping"]` (...stopped typing) * `["gotMessage", "blah"]` (...sent a message) * `["strangerDisconnected"]` (...decided to disconnect) ### In spyee mode * `["question", "blah?"]` (the question you'll discuss with the stranger) ### In spyer mode * `["question", "blah question?"]` (your question) * `["spyTyping", "Stranger <1/2>"]` (Stranger 1/2 started typing) * `["spyStoppedTyping", "Stranger <1/2>"]` (...stopped typing) * `["spyMessage", "Stranger <1/2>", "blah"]` (...sent a message) * `["spyDisconnected", "Stranger <1/2>"]` (...decided to disconnect) Send messages ------------- I'm not sure about the Unicode support, but it should work in most cases. `POST http://[server].omegle.com/send` Form Data: * `msg = lol` * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` Response: ``` win ``` Set your "typing" status ------------------------ The server may detect clients that don't send these. `POST http://[server].omegle.com/typing` `POST http://[server].omegle.com/stoppedtyping` Form Data: * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` Response: ``` win ``` Stop looking for common topics ------------------------------ If you've passed `topics` to `/start`, the server will send the `waiting` event and then search for people with the same topics until this gets posted. Use this to stop the running search, ignore the topics and continue with connecting. `POST http://[server].omegle.com/stoplookingforcommonlikes` Form Data: * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` Response: ``` win ``` Disconnect from the current chat -------------------------------- Simple as that. Always use this to end sessions gracefully, unless noted beneath events. `POST http://[server].omegle.com/disconnect` Form Data: * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` Response: ``` win ``` ReCAPTCHAS ---------- If you run into an `recaptchaRequired` event, you must prove that you're a human by fetching the captcha using the URL-encoded passed code from `http://www.google.com/recaptcha/api/image?c=[challenge]` and sending the answer like this. Note that I haven't tried this yet. `POST http://[server].omegle.com/recaptcha` Form Data: * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh` * `challenge = [challenge]` * `response = [answer]` Getting b& ---------- If you got an `antinudeBanned` event, chances are that the moderators banned you from the monitored section for "bad behaviour". This also applies if the server status object (see section "Status") has `force_unmon` set as `true`. You can retry by passing `group = unmon` to `/start`. That won't work if you got your IP banned because of too rapid connecting or advertising, though. Sharing logs ------------ To upload your logs to Omegles server, use this. Pro-Tip: You can actually pass any arbitrary text as the log (note the double brackets though). The first item is always the header, ("You're chatting with a random stranger on Omegle!") and the last the footer ("You have disconnected."). If the second item is "Question to discuss:", it will be styled with the third item to resemble the question box on the web client. Lines starting with "You:" and "Stranger:" will be coloured blue/red. `POST http://logs.omegle.com/generate` Form Data: * `logs = [["blah",...]]` (JSON table of the plaintext chat, split in lines) * `randid = CHPZGFFW` (Your random ID) * `topics = ["asdf", "test", ...]` (optional, the shared topics) * `identdigests = blah,blah,blah` (the most recent data from the `identDigests` event) * `host = 1` Response: 302 Found, the `Location` header contains the log link.