Skip to content

Instantly share code, notes, and snippets.

@nucular
Last active January 10, 2025 16:58
Show Gist options
  • Save nucular/e19264af8d7fc8a26ece to your computer and use it in GitHub Desktop.
Save nucular/e19264af8d7fc8a26ece to your computer and use it in GitHub Desktop.

Revisions

  1. nucular revised this gist Jun 3, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -76,7 +76,7 @@ __Query String__
    * `rcs = 1`
    * `firstevents = 1` (if 0 or not given, the response will not contain a statusInfo)
    * `m = 1` (imitate a mobile connection, shouldn't really matter)
    * `randid = CHPZGFFW` (this is really just a random string containing 2-9 and A-Z)
    * `randid = CHPZGFFW` (this is really just a random string containing 2-9 and A-Z, but excluding I and O)
    * `spid =` (some kind of ID from Adobe Stratus, never used though)
    * `group = unmon` (optional, join the unmonitored section instead)
    * `lang = en` (optional, two-char language code)
  2. nucular revised this gist Apr 17, 2016. 1 changed file with 23 additions and 22 deletions.
    45 changes: 23 additions & 22 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,11 @@
    Let's reverse-engineer Omegle. PROPERLY!
    ========================================
    I couldn't find a proper, detailed (and up-to-date) reverse-engineerment
    I could not find a proper, detailed (and up-to-date) reverse-engineerment
    of Omegle's text chat protocol on the internet, so here, have one made by analyzing the web app (web requests and source code).
    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 POST body which don't have to be URI-encoded.
    "form data" to parameters in the POST body which do not have to be URI-encoded.

    TODO:
    * Find out how college authorization works
    @@ -33,8 +33,8 @@ from requests by the JavaScript.
    Status
    ------
    Pro-Tip: Fetch this first and then use one of the servers/subs listed for future
    connections (you can just connect to the main server here). Also, you should
    switch to another one if the current isn't listed anymore.
    connections (you can just connect to the main server here). You should
    switch to another one if your current one is not listed anymore.

    `GET http://[server].omegle.com/status`

    @@ -67,25 +67,25 @@ __Response__
    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.
    a question/spy chat, send `wantsspy = 1` for spyee mode (answer a question) and `ask = blah` for
    spyer mode (ask a question).

    `POST http://[server].omegle.com/start`

    __Query String__
    * `rcs = 1`
    * `firstevents = 1`
    * `firstevents = 1` (if 0 or not given, the response will not contain a statusInfo)
    * `m = 1` (imitate a mobile connection, shouldn't really matter)
    * `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)
    * `group = unmon` (optional, join the unmonitored section instead)
    * `lang = en` (optional, two-char language code)
    * `topics = ["asdf", "test", ...]` (in default mode only)
    * `topics = ["foo", "bar", ...]` (in default mode only)

    Spyer/Spyee
    * `wantsspy = 1` (for spyee mode)
    * `ask = blah?` (for spyer mode)
    * `cansavequestion = 1` (optional, in spyer mode only, Omegle may reuse your question)
    * `cansavequestion = 1` (optional, in spyer mode only, allow Omegle to reuse your question)

    Camera Chat
    * `webrtc = 1` (for camera chat)
    @@ -100,9 +100,10 @@ __Response__
    ```javascript
    {
    "events": [
    // ...see section "Events"...
    // see section "Events"
    ],
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" // needed for all subsequent requests
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh", // needed for all subsequent requests
    "statusInfo": {...} // see section "Status"
    }
    ```

    @@ -122,8 +123,8 @@ __Response__
    ```javascript
    [
    // see below
    ["method", "arg"],
    ["method", "arg", "arg"],
    ["event", "argument 1", ...],
    ["event", "argument 1", "argument 2", ...],
    // ...
    ]
    ```
    @@ -135,8 +136,8 @@ __Response__
    * `["count", 20900]` (update the connection/online count, never encountered this one but it's in the source)

    ### Notifications
    * `["commonLikes", ["a", "b", ...]]` (the shared topics from the ones you've passed)
    * `["partnerCollege", "blah"]` (chat partner goes to this college)
    * `["commonLikes", ["foo", "bar", ...]]` (the shared topics from the ones you've passed)
    * `["partnerCollege", "Foobar College"]` (chat partner goes to this college)
    * `["serverMessage", "blah"]` (most likely `You both speak the same language.`)
    * `["recaptchaRequired", "ChALlEnGe"]` (see section "ReCAPTCHAs")
    * `["recaptchaRejected", "ChALlEnGe"]`
    @@ -188,7 +189,7 @@ win

    Set your "typing" status
    ------------------------
    The server may detect clients that don't send these.
    The server might detect clients that do not send these.

    `POST http://[server].omegle.com/typing`
    `POST http://[server].omegle.com/stoppedtyping`
    @@ -222,8 +223,8 @@ win

    Disconnect from the current chat
    --------------------------------
    Simple as that. Always use this to end sessions gracefully, unless noted beneath
    events. This can also be used to disconnect both strangers in the spyer mode.
    Simple as that. Always use this to end sessions gracefully, unless another event already
    ended the session. This can also be used to disconnect both strangers in the spyer mode.

    `POST http://[server].omegle.com/disconnect`

    @@ -269,7 +270,7 @@ TODO

    ReCAPTCHAS
    ----------
    If you run into an `recaptchaRequired` event, you must prove that you're a
    If you run into an `recaptchaRequired` event, you must prove that you are 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.
    @@ -288,7 +289,7 @@ If you got an `antinudeBanned` event, the modarating system banned you from the
    monitored section for "bad behaviour". From now on, the server status object
    (see section "Status") will have `force_unmon` set to `true`. You can switch to
    the unmonitored section by passing `group = unmon` to `/start`. They won't give
    you this mercy if you got your IP banned because of too rapid connecting or
    you this mercy if you got your IP banned by connecting too rapidly or
    advertising, but bans don't last forever anyway.


    @@ -312,9 +313,9 @@ These are the triggers that add some formatting:
    `POST http://logs.omegle.com/generate`

    __Form Data__
    * `logs = [["You:", "blah"], ...]` (JSON table of the plaintext chat, split in lines)
    * `log = [["You:", "blah"], ...]` (JSON table of the plaintext chat, split in lines)
    * `randid = CHPZGFFW` (Your random ID)
    * `topics = ["asdf", "test", ...]` (optional, the shared topics)
    * `topics = ["foo", "bar", ...]` (optional, the shared topics)
    * `identdigests = blah,blah,blah` (the most recent data from the `identDigests` event)
    * `host = 1`

  3. nucular revised this gist May 13, 2015. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -116,7 +116,7 @@ long timeouts.
    `POST http://[server].omegle.com/events`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`

    __Response__
    ```javascript
    @@ -178,7 +178,7 @@ I'm not sure about the Unicode support, but it should work in most cases.

    __Form Data__
    * `msg = lol`
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`

    __Response__
    ```
    @@ -194,7 +194,7 @@ The server may detect clients that don't send these.
    `POST http://[server].omegle.com/stoppedtyping`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`

    __Response__
    ```
    @@ -212,7 +212,7 @@ continue with connecting.
    `POST http://[server].omegle.com/stoplookingforcommonlikes`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`

    __Response__
    ```
    @@ -228,7 +228,7 @@ events. This can also be used to disconnect both strangers in the spyer mode.
    `POST http://[server].omegle.com/disconnect`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`

    __Response__
    ```
    @@ -251,7 +251,7 @@ which it sends the list to the server and clears it.
    `POST http://[server].omegle.com/icecandidate`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`
    * `candidate = %7B...%7D` (url-encoded JSON representation of a candidate)
    * `candidate = ...` (multiple times)

    @@ -277,7 +277,7 @@ like this. Note that I haven't tried this yet.
    `POST http://[server].omegle.com/recaptcha`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `id = [clientID]`
    * `challenge = [challenge]`
    * `response = [answer]`

  4. nucular revised this gist Dec 22, 2014. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    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!
    I couldn't find a proper, detailed (and up-to-date) reverse-engineerment
    of Omegle's text chat protocol on the internet, so here, have one made by analyzing the web app (web requests and source code).
    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
    @@ -12,6 +12,8 @@ TODO:
    * Find out how WebRTC video streaming works
    * Generally phrase things better

    I hereby declare this document Public Domain. If you find it helpful for a project of yours, I only ask you to provide a link to it in your source so others interested can learn from it too.

    __Used Request Headers__
    ```
    Accept: application/json
  5. nucular revised this gist Dec 21, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -87,7 +87,7 @@ Spyer/Spyee

    Camera Chat
    * `webrtc = 1` (for camera chat)
    * `camera = ?` (optional, in camera mode only, TODO)
    * `camera = ` (probably just a flag, was " " for me in camera chat)

    College Chat
    * `college = ?` (optional, TODO)
  6. nucular revised this gist Dec 20, 2014. 1 changed file with 71 additions and 22 deletions.
    93 changes: 71 additions & 22 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ TODO:
    * Find out how WebRTC video streaming works
    * Generally phrase things better

    Used Request Headers:
    __Used Request Headers__
    ```
    Accept: application/json
    Accept-Encoding: gzip,deflate
    @@ -36,11 +36,11 @@ switch to another one if the current isn't listed anymore.

    `GET http://[server].omegle.com/status`

    Query String:
    __Query String__
    * `nocache = 0.4695589093025774` (optional, random nonce to prevent cached responses from being sent)
    * `randid = CHPZGFFW` (optional, see section "Start")

    Response:
    __Response__
    ```javascript
    {
    "count": 20840, // connection count, people say it's faked
    @@ -70,20 +70,31 @@ spyer mode.

    `POST http://[server].omegle.com/start`

    Query String:
    __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)
    * `group = unmon` (optional, join the unmonitored section instead)
    * `lang = en` (optional, two-char language code)
    * `topics = ["asdf", "test", ...]` (in default mode only)

    Spyer/Spyee
    * `wantsspy = 1` (for spyee mode)
    * `ask = blah?` (for spyer mode)
    * `cansavequestion = 1` (Omegle may reuse your question)
    * `group = unmon` (join the unmonitored section instead)
    * `cansavequestion = 1` (optional, in spyer mode only, Omegle may reuse your question)

    Camera Chat
    * `webrtc = 1` (for camera chat)
    * `camera = ?` (optional, in camera mode only, TODO)

    College Chat
    * `college = ?` (optional, TODO)
    * `college_auth = ?` (optional, TODO)
    * `any_college = 1` (optional, TODO)

    Response:
    __Response__
    ```javascript
    {
    "events": [
    @@ -102,10 +113,10 @@ long timeouts.

    `POST http://[server].omegle.com/events`

    Form Data:
    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    __Response__
    ```javascript
    [
    // see below
    @@ -123,10 +134,11 @@ Response:

    ### Notifications
    * `["commonLikes", ["a", "b", ...]]` (the shared topics from the ones you've passed)
    * `["partnerCollege", "blah"]` (chat partner goes to this college)
    * `["serverMessage", "blah"]` (most likely `You both speak the same language.`)
    * `["recaptchaRequired", "ChALlEnGe"]` (see section "ReCAPTCHAs")
    * `["recaptchaRejected", "ChALlEnGe"]`
    * `["identDigests", "a,b,c"]` (probably just used for sharing logs)
    * `["identDigests", "a,b,c"]` (probably only used for sharing logs)

    ### Error events (disconnects you)
    * `["error", "blah!"]` (general error message)
    @@ -149,18 +161,24 @@ Response:
    * `["spyMessage", "Stranger <1/2>", "blah"]` (...sent a message)
    * `["spyDisconnected", "Stranger <1/2>"]` (...decided to disconnect)

    ### In camera chat
    * `["icecandidate", "blah"]` (see section "Connecting to the WebRTC peer")
    * `["rtccall", "blah"]` (TODO)
    * `["rtcpeerdescription"]` (see section "Send WebRTC Peer description")



    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:
    __Form Data__
    * `msg = lol`
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    __Response__
    ```
    win
    ```
    @@ -173,10 +191,10 @@ The server may detect clients that don't send these.
    `POST http://[server].omegle.com/typing`
    `POST http://[server].omegle.com/stoppedtyping`

    Form Data:
    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    __Response__
    ```
    win
    ```
    @@ -191,10 +209,10 @@ continue with connecting.

    `POST http://[server].omegle.com/stoplookingforcommonlikes`

    Form Data:
    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    __Response__
    ```
    win
    ```
    @@ -207,15 +225,46 @@ events. This can also be used to disconnect both strangers in the spyer mode.

    `POST http://[server].omegle.com/disconnect`

    Form Data:
    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    __Response__
    ```
    win
    ```


    Send WebRTC Peer description
    ----------------------------
    TODO


    Send WebRTC ICE candidates
    --------------------------
    This is what you should do when your RTCPeerConnection fires the `onicecandidate`
    event. Basically, the Omegle client stores all received candidates in a list and
    then sets a 300ms timeout for more candidates to get pushed onto the list after
    which it sends the list to the server and clears it.

    `POST http://[server].omegle.com/icecandidate`

    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `candidate = %7B...%7D` (url-encoded JSON representation of a candidate)
    * `candidate = ...` (multiple times)

    __Response__
    ```
    win
    ```


    Connecting to the WebRTC peer
    -----------------------------
    TODO



    ReCAPTCHAS
    ----------
    If you run into an `recaptchaRequired` event, you must prove that you're a
    @@ -225,7 +274,7 @@ like this. Note that I haven't tried this yet.

    `POST http://[server].omegle.com/recaptcha`

    Form Data:
    __Form Data__
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`
    * `challenge = [challenge]`
    * `response = [answer]`
    @@ -260,7 +309,7 @@ These are the triggers that add some formatting:

    `POST http://logs.omegle.com/generate`

    Form Data:
    __Form Data__
    * `logs = [["You:", "blah"], ...]` (JSON table of the plaintext chat, split in lines)
    * `randid = CHPZGFFW` (Your random ID)
    * `topics = ["asdf", "test", ...]` (optional, the shared topics)
  7. nucular revised this gist Dec 20, 2014. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -30,8 +30,9 @@ from requests by the JavaScript.

    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.
    Pro-Tip: Fetch this first and then use one of the servers/subs listed for future
    connections (you can just connect to the main server here). Also, you should
    switch to another one if the current isn't listed anymore.

    `GET http://[server].omegle.com/status`

  8. nucular revised this gist Dec 20, 2014. 1 changed file with 8 additions and 7 deletions.
    15 changes: 8 additions & 7 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -43,7 +43,7 @@ Response:
    ```javascript
    {
    "count": 20840, // connection count, people say it's faked
    "force_unmon": true, // see section "Getting b&"
    "force_unmon": true, // your IP was banned, see "Getting b&"
    "antinudeservers": [
    "waw3.omegle.com", "waw2.omegle.com", "waw1.omegle.com"
    ],
    @@ -88,7 +88,7 @@ Response:
    "events": [
    // ...see section "Events"...
    ],
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" // (needed for all subsequent requests)
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" // needed for all subsequent requests
    }
    ```

    @@ -232,11 +232,12 @@ Form Data:

    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.
    If you got an `antinudeBanned` event, the modarating system banned you from the
    monitored section for "bad behaviour". From now on, the server status object
    (see section "Status") will have `force_unmon` set to `true`. You can switch to
    the unmonitored section by passing `group = unmon` to `/start`. They won't give
    you this mercy if you got your IP banned because of too rapid connecting or
    advertising, but bans don't last forever anyway.


    Sharing logs
  9. nucular revised this gist Dec 20, 2014. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -184,8 +184,9 @@ 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.
    and then search for people with the same topics until the client sends this.
    Use it after some time to stop the running search, ignore the topics and
    continue with connecting.

    `POST http://[server].omegle.com/stoplookingforcommonlikes`

  10. nucular revised this gist Dec 20, 2014. 1 changed file with 23 additions and 19 deletions.
    42 changes: 23 additions & 19 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,9 @@ 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. E.g the real JSON queries don't have whitespaces between items.
    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 URI-encoded.
    "form data" to parameters in the POST body which don't have to be URI-encoded.

    TODO:
    * Find out how college authorization works
    @@ -40,15 +40,16 @@ Query String:
    * `randid = CHPZGFFW` (optional, see section "Start")

    Response:
    ```
    ```javascript
    {
    "count": 20840, (connection count, people say it's faked)
    "force_unmon": true, (see section "Getting b&")
    "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)
    "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": [
    @@ -77,17 +78,17 @@ Query String:
    * `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)
    * `ask = blah?` (for spyer mode)
    * `cansavequestion = 1` (Omegle may reuse your question)
    * `group = unmon` (join the unmonitored section instead)

    Response:
    ```
    ```javascript
    {
    "events": [
    ...see section "Events"...
    // ...see section "Events"...
    ],
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" (needed for all subsequent requests)
    "clientID": "central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh" // (needed for all subsequent requests)
    }
    ```

    @@ -104,27 +105,30 @@ Form Data:
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
    ```
    ```javascript
    [
    [...see below...], ...
    // see below
    ["method", "arg"],
    ["method", "arg", "arg"],
    // ...
    ]
    ```

    ### Status events
    * `["waiting"]` (the server is searching for strangers)
    * `["connected"]` (you can start sending messages now)
    * `["statusInfo", {...stripped...}]` (see section "Status")
    * `["statusInfo", {...}]` (see section "Status")
    * `["count", 20900]` (update the connection/online count, never encountered this one but it's in the source)

    ### Notifications
    * `["commonLikes", ["asdf", "test", ...]]` (the shared topics from the ones you've passed)
    * `["commonLikes", ["a", "b", ...]]` (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)
    * `["recaptchaRequired", "ChALlEnGe"]` (see section "ReCAPTCHAs")
    * `["recaptchaRejected", "ChALlEnGe"]`
    * `["identDigests", "a,b,c"]` (probably just used for sharing logs)

    ### Error events (disconnects you)
    * `["error", "blah blah error text!"]` (general error message)
    * `["error", "blah!"]` (general error message)
    * `["connectionDied"]` (some technical error)
    * `["antinudeBanned"]` (see section "Getting b8")

    @@ -138,7 +142,7 @@ Response:
    * `["question", "blah?"]` (the question you'll discuss with the stranger)

    ### In spyer mode
    * `["question", "blah question?"]` (your question)
    * `["question", "blah?"]` (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)
  11. nucular revised this gist Sep 8, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -24,6 +24,8 @@ 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
    ```
    Note that the headers `X-Requested-With` and `X-Request` are deliberately removed
    from requests by the JavaScript.


    Status
  12. nucular revised this gist Sep 8, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -195,7 +195,7 @@ win
    Disconnect from the current chat
    --------------------------------
    Simple as that. Always use this to end sessions gracefully, unless noted beneath
    events.
    events. This can also be used to disconnect both strangers in the spyer mode.

    `POST http://[server].omegle.com/disconnect`

  13. nucular revised this gist Sep 8, 2014. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -258,4 +258,6 @@ Form Data:
    * `identdigests = blah,blah,blah` (the most recent data from the `identDigests` event)
    * `host = 1`

    Response: 302 Found, the `Location` header contains the log link.
    Response: 302 Found, the `Location` header contains the log link in the format
    `http://logs.omegle.com/[id]`. The log image can be fetched from
    `http://l.omegle.com/[id].png`.
  14. nucular revised this gist Sep 8, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -252,7 +252,7 @@ These are the triggers that add some formatting:
    `POST http://logs.omegle.com/generate`

    Form Data:
    * `logs = [["blah", ...]]` (JSON table of the plaintext chat, split in lines)
    * `logs = [["You:", "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)
  15. nucular revised this gist Sep 8, 2014. 1 changed file with 14 additions and 7 deletions.
    21 changes: 14 additions & 7 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -235,17 +235,24 @@ 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.
    Pro-Tip: You can actually pass any arbitrary text as the log. It's a
    JSON-encoded list containing lists that contain the strings. Oh, and HTML
    injection doesn't work, I tried.

    These are the triggers that add some formatting:
    * `["*"]` (smaller, bold font, gray)
    * `["* disconnected"]` (as above)
    * `["Question to discuss:", "*"]` (blue question box)
    * `["Stranger:", "*"]` (large font, first item is red)
    * `["Stranger 1:", "*"]` (as above)
    * `["Stranger 2:", "*"]` (large font, first item is blue)
    * `["You:", "*"]` (as above)
    * `["*", "*"]` (normal font, first item is bold)

    `POST http://logs.omegle.com/generate`

    Form Data:
    * `logs = [["blah",...]]` (JSON table of the plaintext chat, split in lines)
    * `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)
  16. nucular revised this gist Sep 8, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -112,6 +112,7 @@ Response:
    * `["waiting"]` (the server is searching for strangers)
    * `["connected"]` (you can start sending messages now)
    * `["statusInfo", {...stripped...}]` (see section "Status")
    * `["count", 20900]` (update the connection/online count, never encountered this one but it's in the source)

    ### Notifications
    * `["commonLikes", ["asdf", "test", ...]]` (the shared topics from the ones you've passed)
  17. nucular revised this gist Sep 8, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,9 @@ 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.
    readability. E.g the real JSON queries don't have whitespaces between items.
    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.
    "form data" to parameters in the request body which don't have to be URI-encoded.

    TODO:
    * Find out how college authorization works
  18. nucular revised this gist Aug 30, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -162,7 +162,7 @@ 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/typing`
    `POST http://[server].omegle.com/stoppedtyping`

    Form Data:
  19. nucular revised this gist Aug 30, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -162,7 +162,7 @@ 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/typing`
    `POST http://[server].omegle.com/stoppedtyping`

    Form Data:
  20. nucular revised this gist Aug 29, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion omegle.md
    Original file line number Diff line number Diff line change
    @@ -98,7 +98,7 @@ long timeouts.

    `POST http://[server].omegle.com/events`

    Query String:
    Form Data:
    * `id = central2:k0m4akq5ry4ytvklsrs2jmtsjkpbkh`

    Response:
  21. nucular revised this gist Aug 29, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ 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.
    "form data" to parameters in the request body, which don't have to be encoded.

    TODO:
    * Find out how college authorization works
    @@ -144,7 +144,7 @@ Response:

    Send messages
    -------------
    Proper URI-encoding is important here.
    I'm not sure about the Unicode support, but it should work in most cases.

    `POST http://[server].omegle.com/send`

  22. nucular created this gist Aug 29, 2014.
    253 changes: 253 additions & 0 deletions omegle.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,253 @@
    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.

    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`

    Query String:
    * `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
    -------------
    Proper URI-encoding is important here.

    `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.