# Zoom LTI Pro - Error 2231

**URL:** <https://devforum.zoom.us/t/zoom-lti-pro-error-2231/81180>\
**Category:** API and Webhooks\
**Created:** [January 9, 2023, 8:27pm UTC](https://devforum.zoom.us/t/zoom-lti-pro-error-2231/81180 "2023-01-09T20:27:03Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![Dizolivemint](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/dizolivemint/32/12242_2.png) [@Dizolivemint](https://devforum.zoom.us/u/Dizolivemint)\
**Post date:** [January 12, 2023, 9:37pm UTC](https://devforum.zoom.us/t/zoom-lti-pro-error-2231/81180/3 "2023-01-12T21:37:55Z")

</div>

Following up, I redid the signature so the signature result now matches the examples here:  
[Google App Script example](https://devforum.zoom.us/t/zoom-lti-pro-bulk-import-api-usage/61565/5)  
[Powershell example](https://devforum.zoom.us/t/zoom-lti-pro-bulk-import-api-usage/61565/6)

In addition, I had to create a new credential using LTI 1.3, for the bulk import to work. Unfortunately, the meeting list endpoint still throws the same error.

Here is the function that creates the signature:

```auto
async function generateSignature(message: string) {
  const crypto = require('crypto');
  let ltiSecret = process.env.ZOOM_LTI_SECRET;

  let hmac = crypto.createHmac('sha1', ltiSecret);
  hmac.update(message);
  let signature = hmac.digest('base64');
  signature = signature.split('=')[0].replace(/\+/g, '-').replace(/\//g, '_');
  
  return signature;
}

```

Here is the function that fetches the meeting list. Still getting the same error 2231:

```auto
async function getMoodleCourseMeetingList(userId: string): Promise<GetCourseMeetingListResponseModel | void> {
  const timestamp = new Date(new Date().toUTCString()).getTime()
  const ltiKey = process.env.ZOOM_LTI_KEY
  const message = `isUpComing=true&key=${ltiKey}&pageNum=1&pageSize=20&timestamp=${timestamp}&userId=${userId}`
  const ltiSignatureHash = await generateSignature(message)
  
  const url = `${baseUrl}/open/meeting/list?${message}`

  const headers = {
    'X-Lti-Signature': ltiSignatureHash
  }

  try {
    const response = await Axios({
      method: 'get',
      url,
      headers
    })
    console.log(response.data)
    return response.data
  } catch (error) {
    console.error(error)
    return
  }
}

```

Here is the function that adds the meetings to Moodle (Bulk import API). It is working, but adding the userId, as per the documentation, does not work:

```auto
async function associateZoomMeetingWithCourse(meetingList: ZoomLtiRequestBodyType['meetingList']): Promise<any | void> {
  // const userId = process.env.ZOOM_USER_ID // Adding the userId doesn't work for me
  const timestamp = new Date(new Date().toUTCString()).getTime()
  const ltiKey = process.env.ZOOM_LTI_KEY
  const message = `key=${ltiKey}&timestamp=${timestamp}` // &userId=${userId}` // Adding the userId doesn't work
  const ltiSignatureHash = await generateSignature(message)

  console.log('ltiSignatureHash', ltiSignatureHash)
  const url = `${baseUrl}/meeting/bulkImport?${message}`
  console.log(url)

  const headers = {
    'X-Lti-Signature': ltiSignatureHash,
    'Content-Type': 'application/json',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept': 'application/json',
  }

  if (meetingList.length > 400) throw new Error('Too many meetings to associate with course. (Max 400)')

  const data = meetingList // Adding the userId doesn't work

  try {
    const response = await Axios({
      method: 'post',
      url,
      headers,
      data
    })
    console.log(response.data)
    return response.data
  } catch (error) {
    console.error(error)
    return
  }
}

```

---

_[View the full topic](https://devforum.zoom.us/t/zoom-lti-pro-error-2231/81180)._
