Caccl
The Canvas App Complete Connection Library (CACCL) is an all-in-one library for building Canvas-integrated apps. By handling LTI, authorization, and api for you, CACCL makes building Canvas-integrated tools quick and easy. Keywords: Canvas LMS Instructure API LTI Authorization EdTech Education
Install / Use
/learn @harvard-edtech/CacclREADME
CACCL
The Canvas App Complete Connection Library (CACCL) is an all-in-one library for building Canvas-integrated apps. By handling LTI, authorization, and API for you, CACCL makes building Canvas-integrated tools quick and easy.
Beta: this project is in beta and breaking changes may occur at any time.
Setup CACCL
The fastest way to get set up is to use our template app. It uses Node.js and Express.js on the back-end and React on the front-end. Both use typescript. If you'd like to set up your project manually, check out the Manual Setup section.
1. Create Project
Make a new npm project and navigate to the top-level directory.
Then, use npx create-caccl and follow instructions.
Among many other updates, you should now find two folders: server/ and client/ which contain an Express server and a React app, respectively.
2. Set Up the Server
Out of the box, your CACCL app will be ready to run in development mode. Here's how to set up your server so it is ready for production.
In server/src/index.ts, you'll find a call to initCACCL({ ... }). All CACCL configuration gets passed into initCACCL.
Required: Configure LTI
All CACCL apps integrate with Canvas via LTI v1.1 (LTI v1.3 coming soon). You can think of LTI as a standardized interface between Canvas and an app that integrates with Canvas. For more info on LTI, check out the IMS Global LTI Docs.
I. Add Credentials
When your LTI app is installed into Canvas, it will be installed with installation credentials: consumer key and consumer secret (also referred to as a shared secret).
Provide your installation credential(s) to CACCL as an lti.installationCredentials map in the form { key => secret }.
initCACCL({
lti: {
installationCredentials: {
'first-key': 'first-secret',
'second-key': 'second-secret',
...
},
},
});
If you only have one key/secret pair (all app installs use the same installation credentials), you can include your credentials as two environment variables instead: CONSUMER_KEY and CONSUMER_SECRET.
II. Choose Other Features
Disable Authorization After Launch: If the api is configured (see the next section) but you would not like to automatically authorize users with the API when they launch via LTI, add the lti.dontAuthorizeAfterLaunch: true flag. This is not a feature that's used very often, but it is useful if you sometimes want users to be redirected for API authorization (perhaps you only use the API for specific features or specific users). Then, since the user will not automatically be authorized to use the API, you'll need to manually redirect the user to the authorization process (see the "redirectToAuth" function in later sections). Note: the lti.dontAuthorizeAfterLaunch flag is automatically set to true if the app is not set up for API integration.
initCACCL({
lti: {
dontAuthorizeAfterLaunch: true,
},
});
Self Launch: Usually, LTI apps are launched by users who start in Canvas. However, if you'd like your app to be able to launch itself, CACCL has a clever self-launch process that allows your app to launch itself, given information about the Canvas instance and course. To enable this feature, add an lti.selfLaunch configuration object. CACCL needs to know the appId (also referred to as the external tool id) of your app as it is installed in the course that you'd like to self-launch from. For more information, see the Enable Self Launch section. There are many ways you can share appIds with CACCL:
Optional: Configure API
You can skip this section if your app doesn't need to access the Canvas API on behalf of the current user. If your app uses a predefined access token (not recommended), check out the Access API via Predefined Access Token section.
I. Add Credentials
To integrate with the Canvas API, your app needs to be registered with the Canvas instance. This is something you'll need to work through with the school/university/organization and their Canvas admins. Once they approve your app and add it to their Canvas instance, you should be able to get developer credentials for the app (client id and secret).
Provide your developer credential(s) to CACCL as an auth.developerCredentials map in the form { canvasHost => { clientId, clientSecret } }.
initCACCL({
auth: {
developerCredentials: {
'canvas.harvard.edu': {
clientId: '12340000000000000000125',
clientSecret: 'dgha7ht29837hgasdhfa0873grasheklh287gt097a08h3ug8',
},
},
},
});
If you only have one set of developer credentials to include, you can include your credentials as three environment variables: DEFAULT_CANVAS_HOST, CLIENT_ID, and CLIENT_SECRET.
II. Configure Client-side API
If your client-side React app accesses the Canvas API directly, you can skip this section. But if your client app does not need access to the Canvas API, you can disable it by adding the following flag:
initCACCL({
api: {
disableClientSideAPI: true,
},
});
III. Add API Scopes
Sometimes, universities and schools limit the API scopes that apps are allowed to access. If your app is limited, you will need to include an array of scopes when initializing CACCL, included as api.scopes:
initCACCL({
api: {
scopes: [
'url:GET|/api/v1/courses',
'url:GET|/api/v1/courses/:course_id/assignments',
...
],
},
});
3. Setup Development Mode
Create a Sandbox Course
First, you'll need access to "sandbox course" in a real Canvas instance. You can visit canvas.instructure.com to log in or create an account. A "sandbox course" can be any Canvas course that is used for testing. We recommend adding one test teacher, at least one test TA, and at least one test student to your sandbox.
Get Access Tokens for All Test Users
Get each test user's access token (teacher, TAs, students):
- Log in as the user
- Click "Account" in the top left
- Click "Settings"
- Scroll down to "+ Access Token"
- Follow instructions
Create a /config/devEnvironment.json File
From the top level of your project, create a /config/devEnvironment.json file and add your sandbox information:
{
"canvasHost": "canvas.harvard.edu",
"courseId": 19248,
"teacherAccessToken": "1234~fasdhf782egjoasidnfga8723rhfahs9d8ga7yegf",
"taAccessTokens": [
"1234~ncb6dhf0qe9gga6q3b48vb87df8adf787w"
],
"studentAccessTokens": [
"1234~3r5983tbtnfm28tn2898ansd928377t097",
"1234~riout8r9e8u7y38f7a78odg8g7rgh87aer"
]
}
canvasHost is the hostname of the Canvas instance containing your sandbox. This is optional and defaults to canvas.instructure.com.
courseId can be found in the URL when visiting the Canvas course: https://canvas.harvard.edu/courses/19248 where 19248 is the id.
teacherAccessToken is the access token for a teacher in the sandbox.
taAccessTokens is an optional array of access tokens for TAs in the sandbox.
studentAccessTokens is an optional array of access tokens for students in the sandbox.
If your app has any custom parameters that you want to include, add them in a customParams map:
{
...
"customParams": {
"name": "value"
...
}
}
Remember that custom parameters cannot have capital letters. For example, termName is not allowed and should be replaced with simply term or term_name.
Also, we support the case where your app doesn't get launched via the / path. This is an unusual case, but nevertheless, it is supported by caccl. To include custom launch paths, simply include them in a list:
{
...
customLaunchPaths: [
{
"name": "Cat Video Player",
"path": "/videos/cats"
},
{
"name": "Desserts Video Player",
"path": "/videos/desserts"
}
],
};
Done!
You can now head over to the Using CACCL section.
Check out the Advanced Setup section for more advanced configuration.
Using CACCL
Now that your CACCL app is configured, you're ready to start development!
Start App in Development Mode
Open three terminal windows/tabs and navigate to the top-level directory of the project.
In the first window, use npm run dev:server to initialize the server in dev mode.
In the second window, use npm run dev:client to initialize the client in dev mode.
In the third window, use npm run dev:canvas to initialize a Canvas launch simulator.
Follow instructions in the third window. Logs from the server will appear in the first window and logs from the client will appear in the browser console.
Check LTI/Auth Status and Get Launch Info
To check the user's current status, use CACCL's getStatus function to get a status object.
If the user has not launched via LTI, the status object will take the form:
{
launched: false,
}
If the user has launched via LTI, the status object will take the form:
{
launched: true,
launchInfo: LaunchInfo,
authorized: boolean,
}
Where authorized is true if the user is authorized to access the Canvas API and launchInfo contains all LTI launch info. See the LaunchInfo docs for detailed information on all the properties in the launchInfo object.
On the server:
Import getStatus:
import { getStatus } from 'caccl/server';
From within a route, call getStatus with the express req instance:
const status = await getSta
