Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to make project work #5

Open
TiernanKennedy opened this issue Mar 27, 2019 · 2 comments
Open

Updates to make project work #5

TiernanKennedy opened this issue Mar 27, 2019 · 2 comments

Comments

@TiernanKennedy
Copy link

I've been trying to get this working as it's a pretty amazing concept. However I'm running into issues in getting this to run.

For the migrateUsers piece I get this error:

npm start migrateUsers

> [email protected] start /Users/tiernankennedy/Development/beatha/testing_stuff/jira-to-clubhouse-node
> ts-node src/cli.ts "migrateUsers"

inviting 23 users
(node:77389) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
{ message: 'The request included invalid or missing parameters.',
  errors:
   { invites: 'missing-required-key', emails: 'disallowed-key' } }
{ date: 'Wed, 27 Mar 2019 20:26:03 GMT',
  'content-type': 'application/json;charset=utf-8',
  'content-length': '135',
  connection: 'close',
  vary: 'Accept',
  'database-time': '221438839',
  'clubhouse-company': '',
  'clubhouse-organization': '5c9bd53b-ab4e-4672-8ca3-14e69742d3f0',
  'access-control-expose-headers':
   'Database-Time, CH-Paginate-Incomplete, CH-Start-Time, CH-End-Time, Clubhouse-Company, Clubhouse-Organization',
  server: 'Jetty(9.4.z-SNAPSHOT)' }
Unhandled rejection Error: Request failed with status code 400

So it looks like they want to change emails to invites, then we get:

{ message: 'The request included invalid or missing parameters.',
  errors:
   { invites: [ 'not', [ 'sequential?', 'a-java.lang.String' ] ] } }
{ date: 'Wed, 27 Mar 2019 20:28:09 GMT',
  'content-type': 'application/json;charset=utf-8',
  'content-length': '131',
  connection: 'close',
  vary: 'Accept',
  'database-time': '221440411',
  'clubhouse-company': '',
  'clubhouse-organization': '5c9bd53b-ab4e-4672-8ca3-14e69742d3f0',
  'access-control-expose-headers':
   'Database-Time, CH-Paginate-Incomplete, CH-Start-Time, CH-End-Time, Clubhouse-Company, Clubhouse-Organization',
  server: 'Jetty(9.4.z-SNAPSHOT)' }
Unhandled rejection Error: Request failed with status code 400

So whatever parameters need to be sent may have changed. This seems like a fixable issue though, just a case of finding out the new format that they're making the API calls. @geekflyer how did you originally inspect those requests?

Also when doing migrateData I get this error

creating projects if not yet exist
creating project: FO
creating project: ENG
(node:77418) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
{ message: 'The request included invalid or missing parameters.',
  errors: { team_id: 'missing-required-key' } }
{ date: 'Wed, 27 Mar 2019 20:31:01 GMT',
  'content-type': 'application/json;charset=utf-8',
  'content-length': '109',
  connection: 'close',
  vary: 'Accept',
  'database-time': '221442086',
  'clubhouse-company': '',
  'clubhouse-organization': '',
  'access-control-expose-headers':
   'Database-Time, CH-Paginate-Incomplete, CH-Start-Time, CH-End-Time, Clubhouse-Company, Clubhouse-Organization',
  server: 'Jetty(9.4.z-SNAPSHOT)' }
Unhandled rejection Error: Request failed with status code 400

It seems there are just small API issues here that can be fixed. I'd be happy to help implement if there's appetite. Let me know @geekflyer !

@geekflyer
Copy link
Owner

geekflyer commented Mar 27, 2019

Hi,

nice to see other people (trying) to leverage this tool / script :)

Regarding migrateUsers

In general clubhouse does not seem to have an official API to create users (neither 1.5 years ago when I did the migration, nor now). Because I didn't want to create users manually and I wanted migrated issues be assigned the correct user (requester and owner) I came up with some hack though nevertheless. Since there is no API documentation I found out all of this just via the Chrome Debugger (i.e. inspecting network requests when adding a user through the UI).
As far as I remember it was roughly like this:

As a clubhouse admin you go to the users UI and invite a users. This creates an "Invite" (1st API call). The api call returns an "invite" with an invite id. This also creates an invite email that is being send to the potentially new user and the link in that email also contains the invite id as url parameter. Anyways - so what I'm doing is I'm using that invite here https://github.com/geekflyer/jira-to-clubhouse-node/blob/master/src/Migration.ts#L232 to turn the invite into an actual "member" via a second API call to the /invites/create-user endpoint. This endpoint is semantically "accepting an invite" which is what new user would normally do if he clicks on the link in the invitation email (but here we're doing this programmatically). The accept invite endpoint actually does not authenticate the user (i.e. there's no login or api token required to call that endpoint, which makes sense since the user who would access that endpoint does not even exist by the time he opens that endpoint). Therefore calling this endpoint is different than the others and a regular API token doesn't work. Instead of passing an api token you have to pass a session cookie and invite id to that API endpoint - creating / getting a session cookie can be done in multiple ways but the easiest was simply to open ur chrome browser and inspect any of the network requests going to clubhouse's domain and copying the Cookie header. See also this comment: https://github.com/geekflyer/jira-to-clubhouse-node/blob/master/config.template.ts#L28 .
In summary you should manually invite one user (perhaps yourself via a second fake email and a Chrome Incognito tab) and observe some of the critical network requests in Chrome being made while going through the flow to reverse engineer the API.

As for all the other API calls

At the time (1.5 years ago) when I was doing the migration clubhouse had just a V1 API which missed a lot of functionalities and a V2 Beta API which had more features and was actually also used by the UI almost everywhere. There is an official clubhouse nodejs client lib https://github.com/clubhouse/clubhouse-lib which at that time was also using the beta endpoints but actually contained a few bugs / limitations and didn't implement certain endpoints correctly itself (or contained incorrect typings) and was missing a few critical functionalities (for example maintaining labels). Another major issue with the official clubhouse lib was that I was constantly running into ratelimit issues when attempting to run the migration script and that library didn't even expose a proper way to detect and handle that specific error.
Therefore I forked this library and made a few changes to it: https://github.com/geekflyer/clubhouse-lib . I also changed it from using FlowType to TypeScript but that was just because I like some type safety and I'm much more familiar with TypeScript. The jira-to-clubhouse-node tool now uses this forked clubhouse lib. As far as I can see it the official clubhouse lib hasn't changed thaaat much in the meantime and it still doesn't support the Labels API. So what I would suggest for you is to clone my clubhouse-lib fork, change it to use the V2 API (instead of V2 Beta), and adapt other things as needed. Also checkout the changelog of the official clubhouse lib to see if there's anything that would need to get incorporated into my fork, but from a quick glimpse I don't see any major changes in the official clubhouse lib since then. Surprisingly it also still uses the beta endpoint: https://github.com/clubhouse/clubhouse-lib/blob/master/src/index.js#L34 .
The workflow for making changes to my clubhouse lib fork would be:

  1. Clone both repos (jira-to-clubhouse-node and geekflyer/clubhouse-lib) and run npm install in each.
  2. Inside the geekflyer/clubhouse-lib project directory run npm run watch. This will run the typescript compiler in watch mode.
  3. Inside the jira-to-clubhouse-node project run npm link <...path_to_geekflyer_clubhouse_lib_on_your_machine> to use the local copy of clubhouse-lib.
  4. Inside the clubhouse-lib project make changes as needed (typescript compiler will recompile whenever it detects a change).
  5. Re-run the script (e.g. npm run migrateData) to see if it works. Again make sure you do this all against some kind of clubhouse test instance. If things go really bad you can always create a new clubhouse account or use npm run purgeClubhouse to start from scratch.

Let me know if that helps. Would appreciate if you can create an MR if you find any incompatibilities that you could fix.

@geekflyer
Copy link
Owner

One additonal note: the teams functionality didn't exist back then. I suppose in order to create a project one nowadays always has to pass in a team_id . You might have to find out programmatically the default team id (the initial team) by using the listTeams endpoint. You can incorporate it from this patch useshortcut/shortcut-client-js@252f00e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants