Skip to content

feat: zoom transcript proof of concept #11484

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

Merged
merged 5 commits into from
Jun 27, 2025
Merged

Conversation

nickoferrall
Copy link
Contributor

Demo: https://www.loom.com/share/9cacc0e110b04911bcd005e5dea48128

There have been lots of updates to the Recall API since our initial implementation. This PR updates the logic so that it works with their new pay-as-you-go API.

This is a proof of concept so that we can submit a Zoom bot application.

It will be significantly improved before releasing it to customers. For instance:

  • Implement live streaming so you can see the transcription during the meeting
  • Currently, if you end the Parabol meeting before ending the Zoom meeting it won't work
  • Include the transcription in a meeting summary, ideally in a Parabol Page

To test

  • Add the zoomTranscription feature flag and apply it to your organization
  • Create a retro, go to the discuss phase, click the Transcription flag, and paste a Zoom link
  • See the Parabol Notetaker joins the Zoom meeting
  • End the Zoom meeting
  • End the Parabol meeting
  • Go back into the Parabol meeting and see the transcription shows up in the Transcription tab in the discuss phase

@github-actions github-actions bot added size/m and removed size/m labels Jun 25, 2025
@github-actions github-actions bot added size/m and removed size/m labels Jun 25, 2025
@nickoferrall nickoferrall requested a review from Dschoordsch June 25, 2025 23:46
Copy link
Contributor

@Dschoordsch Dschoordsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not work for me, maybe the recall token is outdated?
The meeting just shows
image
while the server throws an error

14:15:13 1|Socket Server                  | {"time":"2025-06-26T12:15:13.606Z","level":"info","message":"SEND TO SENTRY [\n  AxiosError: Request failed with status code 401\n      at settle (/Volumes/User/parabol/dev/web.js:251834:12)\n      at IncomingMessage.handleStreamEnd (/Volumes/User/parabol/dev/web.js:252951:11)\n      at IncomingMessage.emit (node:events:530:35)\n      at endReadableNT (node:internal/streams/readable:1698:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:90:21)\n      at Axios.request (/Volumes/User/parabol/dev/web.js:254061:41)\n      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n      at async RecallAIServerManager.createBot (/Volumes/User/parabol/dev/web.js:1589875:24)\n      at async getBotId (/Volumes/User/parabol/dev/web.js:1519506:17)\n      at async addRecallBot (/Volumes/User/parabol/dev/web.js:1519510:51)\n      at async addTranscriptionBot (/Volumes/User/parabol/dev/web.js:1541778:3)\n      at async Object.addTranscriptionBot (/Volumes/User/parabol/dev/web.js:1514909:14)\n      at async Object.onMessage [as handleMessage] (/Volumes/User/parabol/dev/web.js:940484:35)\n      at async message (/Volumes/User/parabol/dev/web.js:940690:9) {\n    code: 'ERR_BAD_REQUEST',\n    config: {\n      transitional: [Object],\n      adapter: [Array],\n      transformRequest: [Array],\n      transformResponse: [Array],\n      timeout: 0,\n      xsrfCookieName: 'XSRF-TOKEN',\n      xsrfHeaderName: 'X-XSRF-TOKEN',\n      maxContentLength: -1,\n      maxBodyLength: -1,\n      env: [Object],\n      validateStatus: [Function: validateStatus],\n      headers: [Object [AxiosHeaders]],\n      method: 'post',\n      url: 'https://us-west-2.recall.ai/api/v1/bot',\n      data: '{\"meeting_url\":\"https://www.google.com/url?q=https://us06web.zoom.us/j/88939617931?pwd%3DTWNEc0ROTnUySU9CU29pYjNSRXh0UT09&sa=D&source=calendar&ust=1751359413550635&usg=AOvVaw0GrN_OKDH6f9ZIqAg9VmVz\",\"bot_name\":\"Parabol Notetaker\",\"recording_config\":{\"transcript\":{\"provider\":{\"meeting_captions\":{}}}}}',\n      allowAbsoluteUrls: true\n    },\n    request: ClientRequest {\n      _events: [Object: null prototype],\n      _eventsCount: 7,\n      _maxListeners: undefined,\n      outputData: [],\n      outputSize: 0,\n      writable: true,\n      destroyed: true,\n      _last: false,\n      chunkedEncoding: false,\n      shouldKeepAlive: true,\n      maxRequestsOnConnectionReached: false,\n      _defaultKeepAlive: true,\n      useChunkedEncodingByDefault: true,\n      sendDate: false,\n      _removedConnection: false,\n      _removedContLen: false,\n      _removedTE: false,\n      strictContentLength: false,\n      _contentLength: '300',\n      _hasBody: true,\n      _trailer: '',\n      finished: true,\n      _headerSent: true,\n      _closed: true,\n      _header: 'POST /api/v1/bot HTTP/1.1\\r\\n' +\n        'Accept: application/json, text/plain, */*\\r\\n' +\n        'Content-Type: application/json\\r\\n' +\n        'Authorization: Token 7a523d56177632b636cd7bada68ea55ea7af67aa\\r\\n' +\n        'User-Agent: axios/1.9.0\\r\\n' +\n        'Content-Length: 300\\r\\n' +\n        'Accept-Encoding: gzip, compress, deflate, br\\r\\n' +\n        'Host: us-west-2.recall.ai\\r\\n' +\n        'Connection: keep-alive\\r\\n' +\n        '\\r\\n',\n      _keepAliveTimeout: 0,\n      _onPendingData: [Function: nop],\n      agent: [Agent],\n      socketPath: undefined,\n      method: 'POST',\n      maxHeaderSize: undefined,\n      insecureHTTPParser: undefined,\n      joinDuplicateHeaders: undefined,\n      path: '/api/v1/bot',\n      _ended: true,\n      res: [IncomingMessage],\n      aborted: false,\n      timeoutCb: null,\n      upgradeOrConnect: false,\n      parser: null,\n      maxHeadersCount: null,\n      reusedSocket: false,\n      host: 'us-west-2.recall.ai',\n      protocol: 'https:',\n      _redirectable: [Writable],\n      [Symbol(shapeMode)]: false,\n      [Symbol(kCapture)]: false,\n      [Symbol(kBytesWritten)]: 0,\n      [Symbol(kNeedDrain)]: false,\n      [Symbol(corked)]: 0,\n      [Symbol(kChunkedBuffer)]: [],\n      [Symbol(kChunkedLength)]: 0,\n      [Symbol(kSocket)]: [TLSSocket],\n      [Symbol(kOutHeaders)]: [Object: null prototype],\n      [Symbol(errored)]: null,\n      [Symbol(kHighWaterMark)]: 65536,\n      [Symbol(kRejectNonStandardBodyWrites)]: false,\n      [Symbol(kUniqueHeaders)]: null\n    },\n    response: {\n      status: 401,\n      statusText: 'Unauthorized',\n      headers: [Object [AxiosHeaders]],\n      config: [Object],\n      request: [ClientRequest],\n      data: [Object]\n    },\n    status: 401\n  },\n  { tags: undefined }\n]"}

@nickoferrall
Copy link
Contributor Author

Yep, sorry, I updated the API key. Will share that with devs, staging, and prod

@nickoferrall nickoferrall merged commit ea2d8d6 into master Jun 27, 2025
8 checks passed
@nickoferrall nickoferrall deleted the feat/zoom-transcript branch June 27, 2025 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants