Code Monkey home page Code Monkey logo

clubhouse-api's Introduction

Seia-Soto/Clubhouse-API

The API wrapper for Clubhouse application (drop-in audio chat) based on online private API documentation and pwned sources by myself.

Warning

This API client comes without any warrenty. Also, using master branch is not recommended.

Table of Contents


Installation

To install this repository as your dependency, use following command with authorized git client:

yarn add git+https://github.com/Seia-Soto/clubhouse-api#[TAG]

Usage

For working example, you can refer /example folder of this repository. Also, about parameters for each API call functions, you need to inspect functions manually with notes that included with functions.

Scripts

yarn example

Runs example code.

yarn profile

Create new prorfile JSON data by authenticating manually on command line shell.

Reverse Engineering

To reverse engineer Clubhouse audio chat application, only thing we need is jailbroken device. Because there is nothing else except for SSL certificate pinning and we can bypass it even on iOS 14 which is the latest release of iOS by installing some tweaks.

Jailbreaking

Use Odyssey, if you're on iOS 13.6 or higher.

To jailbreak, I recommend you to use Unc0ver instead of others due to stability. Setup AltServer on your PC or Mac and then install Unc0ver

iOS 14

You're not able to use checkm8 exploit if you're on iPhone 11 or higher (higher than A11).

If you're on iOS 14 or higher version, use Checkra1n version 0.12.1 to jailbreak. This this time, you need to disable your iPhone's passcode manually before jailbreaking. Also, DO NOT USE LATEST RELEASE of checkra1n to avoid issue on A11.

Post installation

If you install OpenSSH server to debug on remote PC, you need to CHANGE BOTH root AND mobile USER'S PASSWORD.

passwd root
passwd mobile

Setting up MITM proxy

You can set up MITM proxy with following tools:

Install toolchains and follow steps to decrypt HTTPS traffics:

Fiddler

You need to configure fiddler via the official guide.

MITM Proxy

If you've setup MITM proxy, open http://mitm.it on your iPhone, then install certificate.

Bypassing SSL Pinning

To inspect HTTP packet, there are ways to bypass it easily.

ssl-kill-switch

Install required updates from Cydia for security reasons and install Filza File Manager or terminal emulator to install package file manually. Open following repo and download latest release from it. If you touch share button and then share the file to filza, you can directly install package file.

After installation, turn it on in settings app.

frida-ios-hook

Install iTunes and Python3 on your PC and open iTunes after install. Connect to your iPhone shell via methods described in Wireshark remote debugging section. Clone following repository to some directory:

After, all things are ready, run script via following command:

python3 hook.py -n clubhouse -s frida-scripts\bypass-ssl-ios13.js
  • The script also works on iOS 14.

Wireshark remote debugging

By piping stream over SSH, you can also debug your iPhone's traffic with wireshark installed on PC. Before doing this, install OpenSSH and tcpdump tweak on your iPhone and install Wireshark on your PC.

You may add following paths to system wide environment variable:

  • C:\Program Files\Wireshark

After setting up itunnel-mux or 3uTools from below, open new command line window and start debugging with built-in ssh on Windows 10.

ssh root@localhost -p 2222 -l root tcpdump -s 0 -U -n -w - -i any not port 22 | wireshark -k -i -

itunnel-mux

Download itunnel_mux_rev71.zip from following webpage and add it to path. At this time, you should install iTunes and Apple Mobile Support before continuing.

Open it and start proxy after connecting iPhone.

itunnel_mux --iport 22 --lport 22

3uTools

Also, you can do this easier with 3uTools which only available on Windows. Download and install it to your PC and connect iPhone via USB. Then you can go to Toolbox tab and click Open SSH Tunnel to open SSH port locally.

API

About the API implemented in this project. Only special things will be typed.

Browser support

The code is also available for common web browser as this project doesn't contain any code that requires additional C code build. However, there are many ban reports from web browser use, so if you want to use this on web browser, you should build proxy server.

Voice support

Update 2021/02/21

Voice-related support will not present after today because it is PART OF AGORA, not CLUBHOUSE.

Actually, the capacity of voice support is already present in my repository since src/api/joinChannel.js method implemented. However, there is not enough information to keep users safe from unexpected bans, and I couldn't say You can use this to do Clubhouse!. Other unofficial repositories are already doing voice stuff with Agora SDK built for their language, but I couldn't say that is safe to use. Because, commonly for who operating production service can see every users connecting to specific gateway and it is easy to detect what users are using if user didn't change any thing on official SDK. In future, I am planning to port iOS's Agora voice SDK into Node.JS to reduce ban rate. However, limitation of my iOS ecosystem knowledge, currently only official JavaScript SDK is available to use and there is a huge limitation, which requires web browser context.

For additional information about SDK, please refer:

NG is Next Generation in Agora Ecosystem.*

Electron applications

For Electron based applications, you can easily integrate Agora with my clubhouse-api package. You can see the example that describes how to get RTM token stuff in src/structures/voice.js.

For additional information about Electron SDK, please refer:

client.getStatic(url)

client.getStatic method will return a cross-fetch agent which having essential headers to query static files. For example, you can download profile picture safely by using this method.

const download = url => {
  const fs = require('fs')

  const response = await app.getStatic(url)
  const stream = fs.createWriteStream('./avatar.png')

  return new Promise((resolve, reject) => {
    response.body.pipe(stream)
    response.body.on('error', reject)

    stream.on('finish', resolve)
  })
}

fetch option overrides

To override cross-fetch option object, you need to provide re-usable object to profile.fetchOptions.

const profile = {
  ...profiles.application.a304,
  ...profiles.locales.Korean,
  fetchOptions: {
    agent: ... // NOTE: For proxy stuff;
  }
}

LICENSE

This repository is distributed with MIT License.

clubhouse-api's People

Contributors

dvlkv avatar jnvb avatar joshfindit avatar kwabang avatar seia-soto avatar solojungle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clubhouse-api's Issues

Phone country code may have 1..3 digits

Currently scripts/profile.js assumes phone number has 2 only digit country code.
This is not always true. For example, Russia has +7 country code.
I suggest to add space to phone number format. That will allow to mark country code explicitly:

console.log('For example, let me assume that you have one Korean number: +82 10-1234-5678')
-  console.log('Then put: +821012345678')
+  console.log('Then put: +82 1012345678')

- const phoneNumberMatch = /\+(\d{2})(\d+)/.exec(phoneNumberInput)
+ const phoneNumberMatch = /\+(\d+)\s+(\d+)/.exec(phoneNumberInput)

App flows - start screen, search and calendar

Thank you for such a great lib, its the best (at least for now). I have a question, regarding app flows (I don't have jailbroken phone to check it). Would be very glad, if you could answer:

  1. When user open an app and get start screen - what request are done? Seems like there are at least two? I mean that screen
    https://imgur.com/kUlRPOr

  2. When you click search icon from start screen - the app makes request: getSuggestedFollows?

  3. When you click calendar icon from start screen - the app makes request: getEvents?

[Bug] app.searchUsers always returning 0 results

Describe the bug

Results are always empty

To Reproduce
Steps to reproduce the behavior:

const app = new Client({ profile })
app.searchUsers(searchTerm).then(console.log)

Always returns { users: [], count: 0, next: 0, previous: 0, success: true }, even if the search term is short and generic (like food)

Expected behavior
Some results

profile.json:

{
  "apiRoot": "https://www.clubhouseapi.com/api",
  "userAgent": "clubhouse/304 (iPhone; iOS 14.4; Scale/2.00)",
  "userAgentStatic": "Clubhouse/304 CFNetwork/1220.1 Darwin/20.3.0",
  "appVersion": "0.1.28",
  "appBuild": "304",
  "agoraKey": "",
  "pubnubRoot": "https://clubhouse.pubnub.com",
  "pubnubPubKey": "",
  "pubnubSubKey": "",
  "pubnubSDK": "PubNFub-ObjC-iOS/4.15.11",
  "languages": "en-US",
  "locale": "en_US",
  "acceptLanguages": "en-US;q=1",
  "deviceId": "",
  "user": {
    "user_id": ,
    "name": "",
    "photo_url": "",
    "username": ""
  },
  "tokens": {
    "access": "",
    "auth": "",
    "refresh": ""
  },
  "verified": true,
  "_debug": {
    "req": {
      "update": {
        "has_update": false,
        "success": true
      },
      "auth": {
        "success": true,
        "is_blocked": false,
        "error_message": null
      },
      "login": {
        "success": true,
        "is_verified": true,
        "user_profile": {
          "user_id": ,
          "name": "",
          "photo_url": "",
          "username": ""
        },
        "auth_token": "",
        "refresh_token": "",
        "access_token": "",
        "is_waitlisted": false,
        "is_onboarding": false
      }
    }
  }
}%

HTTP proxy

Hi! Thank you for great work!

Is it possible to use HTTP proxy to make requests?

I tied adding options.agent = new HttpProxyAgent('my_proxy") to fetch - but always getting failed, reason: connect ECONNREFUSED (though the proxy works fine).

Maybe you have some suggestions how to do it ?

Upload avatar

Hello. Thanks for your great work.
How can I upload an avatar?

features request

hi, can you add an endpoint for the first registration (set username), I want to secure my username because I don't have an ios device

[Bug] Cant run profile

Install libs
yarn install or npm install

Try to run
npm run profile

Get error

clubhouse-api\node_modules\uuid\dist\esm-browser\index.js:1
export { default as v1 } from './v1.js';
^^^^^^

SyntaxError: Unexpected token 'export'

ReferenceError: window is not defined

I like your repo, good work! ๐Ÿ’ช

I ran your example code with no problem but what I have a problem with is using initiateVoiceClient() to listen voice in a room. I run the following code

app.debug(await app.initiateVoiceClient())

but it resulted to ReferenceError: window is not defined.

I modified the following line

https://github.com/Seia-Soto/clubhouse-api/blob/9b6760dc165c9317fffba9333e51939170db43b7/src/structures/voice.js#L10

but similar error occured:

(node:15885) UnhandledPromiseRejectionWarning: /clubhouse-api/.yarn/cache/agora-rtc-sdk-ng-npm-4.3.0-2056a060aa-acea6e33c9.zip/node_modules/agora-rtc-sdk-ng/AgoraRTC_N-production.js:1
ReferenceError: window is not defined
    at /clubhouse-api/.yarn/cache/agora-rtc-sdk-ng-npm-4.3.0-2056a060aa-acea6e33c9.zip/node_modules/agora-rtc-sdk-ng/AgoraRTC_N-production.js:361:253
    at /clubhouse-api/.yarn/cache/agora-rtc-sdk-ng-npm-4.3.0-2056a060aa-acea6e33c9.zip/node_modules/agora-rtc-sdk-ng/AgoraRTC_N-production.js:24:99
    at Object.<anonymous> (/clubhouse-api/.yarn/cache/agora-rtc-sdk-ng-npm-4.3.0-2056a060aa-acea6e33c9.zip/node_modules/agora-rtc-sdk-ng/AgoraRTC_N-production.js:24:223)
    at Generator.next (<anonymous>)

Am I supposed to run the code in the browser to mitigate this issue or is there any other solution?

[Bug] Cannot connect with the obtained token to Agora

Hi,

firstly thank you. I used your library to create a Clubhouse client https://github.com/tomaspavlin/clubhouse-client .

Everything worked perfectly but few days ago I got problems with connecting to Agora client. Since that, I did not manage to connect to Clubhouse audio stream. I would like to ask you if you have any suggestions what could be the reason. Queries to clubhouse server still looks to work fine, there is just the problem with connecting to Agora audio stream.

After calling joinChannel api, I try to connect to the Agora using:

const options = {
  mode: 'rtc',
  codec: 'vp8'
}
this.agoraClient = AgoraRTC.createClient(options)

this.agoraKey = '938de3e8055e42b281bb8c6f69c21f78'

await this.agoraClient.join(
   this.agoraKey, channel, token, userId
)

// ...
// Playing the audio track

The this.agoraClient.join raises the following error:

{
  code: "CAN_NOT_GET_GATEWAY_SERVER"
  data: {retry: false}
  message: "AgoraRTCError CAN_NOT_GET_GATEWAY_SERVER: no active status"
  name: "AgoraRTCException"
}

The arguments passed in this.agoraClient.join function looks correct:

0: "938de3e8055e42b281bb8c6f69c21f78"
1: "MEgBvN5k"
2: "006938de3e8055e42b281bb8c6f69c21f78IADJ8YVYb5NdcXWg+TZ9ZR2I0xMkcd+BW9Rq0sX1nF14DqxDSrp1FE6vEABP8GgACSg4YAEAAQAAAAAA"
3: 1848314487

What is weird is that it worked and it just stopped working few days ago. It is possible that this is rather agora issue than issue related to you library, but I still think that you could have some idea how to solve it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.