Skip navigation
All Places > Blackboard Developer Community > Blackboard Learn Developers > Blog
1 2 3 4 Previous Next

Blackboard Learn Developers

59 posts

I'm writing this blog to help you if you're having difficulty placing content in a course using REST APIs. For this example we'll use an LTI "managed placement" in an Original course. We'll show how to set the managed placement for a Course content tool that has an icon associated with it. One that looks like this Administrator Panel -> LTI Tool Providers -> Manage Placements: your.domain.org -> Edit placement page. (All credit to https://www.tsugi.org/ for the Map tool used in this example.)

 

 

1. The first step is to determine the JSON you need for the REST call to create the content. The easy way to do that is to use the Learn UI to go into a course as an instructor and use the UI to place the LTI managed placement link. We did that in a course without much else in it. Course -> Content -> Build Content -> A Tsugi Store Map

 

2. Now you want to see what the JSON should look like for the REST API call you will make that adds another "A Tsugi Store Map" link to the course. You need the course ID which is shown in the above screenshot as _1465_1. As the instructor, or admin, you can place the following in a web-browsers address field see how that JSON will look.

 

You will, of course, modify the URL for the Learn system and course you are working with:

https://bd-partner-a-ultra.blackboard.com/learn/api/public/v1/courses/_1465_1/contents?recursive=true

TIP: NOTE THE USE OF THE recursive=true PARAMETER!

 

The output includes the following JSON. You are looking for a stanza that starts with ,{"id":  and ends with },

,{"id":"_15790_1","parentId":"_15789_1","title":"A Tsugi Store Map","body":"<p>Course Content tool link placed in this Original course by the Instructor Using the UI.</p>","created":"2019-06-03T22:38:57.503Z","modified":"2019-06-03T22:38:57.511Z","position":0,"availability":{"available":"Yes","allowGuests":true,"adaptiveRelease":{}},"contentHandler":{"id":"resource/x-bb-bltiplacement-atsugistoremap","placementHandle":"atsugistoremap"}},

 

3. Now you can build JSON for the content you want to place. The JSON you create should look like the JSON for the content you discovered, less the id and created fields. For example:

{"title":"Yet Another Tsugi Store Map","body":"<p>Course Content tool link placed in this Original course by a REST API Call.</p>","availability":{"available":"Yes","allowGuests":true,"adaptiveRelease":{}},"contentHandler":{"id":"resource/x-bb-bltiplacement-atsugistoremap","placementHandle":"atsugistoremap"}}

 

4. Now you can add that to the course. First you get your access token. Then, as an example, use that to make the following call:

ganymede:~ mbk$ curl -k -X POST -H "Authorization: Bearer ZAEwWWGKqbMi3d2lBJOsaFXHbPLn60OF" -H "Content-Type: application/json" --data '{"title":"Yet Another Tsugi Store Map","body":"<p>Course Content tool link placed in this Original course by a REST  API Call.</p>","availability":{"available":"Yes","allowGuests":true,"adaptiveRelease":{}},"contentHandler":{"id":"resource/x-bb-bltiplacement-atsugistoremap","placementHandle":"atsugistoremap"}}' https://bd-partner-a-ultra.blackboard.com/learn/api/public/v1/courses/_1465_1/contents/_15789_1/children

 

You should see something like the following as a response:

{"id":"_17041_1","parentId":"_15789_1","title":"Yet Another Tsugi Store Map","body":"<p>Course Content tool link placed in this Original course by a REST API Call.</p>","created":"2019-06-13T00:11:18.660Z","modified":"2019-06-13T00:11:18.675Z","position":2,"availability":{"available":"Yes","allowGuests":true,"adaptiveRelease":{}},"contentHandler":{"id":"resource/x-bb-bltiplacement-atsugistoremap","placementHandle":"atsugistoremap"}}

 

And... Success! You have your new content in the course:

In conclusion you can use a similar to understand how to use REST to set any of the LTI managed placement  types as content, or any other content type supported by the REST API POST /learn/api/public/v1/courses/{courseId}/contents/{contentId}/children 

 

Reference: https://developer.blackboard.com

Remember to check the model!

If you're getting a 400 response from a REST API call to add a string to Ultra content with the message: "Could not read document: Invalid Blackboard Markup found in..." it's because Ultra restricts input to only valid BbML, a small subset of HTML.  While  your input worked for a Classic course, it does not work for an Ultra course.  For example, the style attribute of the p element is not considered valid BbML. 

 

So if you were to attempt POST to courses/(courseId)/gradebook/columns for an Ultra course,  and have the following HTML in the description field of the JSON:

{ "name": "A Grade Column Name", "description": "<p style=\"display: none;\">[blinkid:XL:urn:bobson:mybigco.com/xl/certdb:abigmystery/OU812-H-90125-69]</p>",...

 

you get the 400 response and message.

 

See: https://community.blackboard.com/docs/DOC-3851-blackboard-markup-language-bbml for more details. 

 

Use only valid BbML.

Quite the problem is  mis-matched time on the Learn server and the tool provider. So first, make certain both servers are running some means of syncing to a time server, ex: ntpd. Second, from a case that I needed help from our OAuth expert with, make certain that the code that calculates the OAuth signature includes everything, including the port. Example: If the Learn server is available on https://mybig.co.com:8443 then the OAuth signature calculation for the LTI launch must include the 8443 portion of the URL. 

 

May all your LTI launches be successful!

Recently we had a report that an application running on a partner's server was no longer able to send requests to Blackboard's Learn servers. They were SOAP requests - which is being deprecated - but that wasn't the issue. 

 

We've moved our servers to TLSv1.1/1.2. We're also using a modern set of ciphers. Make certain you're using both and you'll be able to connect!

 

Here's one article that describes a symptom and solution for those using Microsoft .Net libraries.

https://stackoverflow.com/questions/35621686/authentication-failed-because-the-remote-party-has-closed-the-transport-stream-e

 

Happy Coding!

I've been getting multiple inquires about finding log files in SaaS. As of 3600.0.0, Kibana is no longer available in SaaS. READ: https://blackboard.secure.force.com/btbb_articleview?id=kA41O000000Cgaa 

 

To stay up to date on changes like this to Learn - keep abreast of announcements on Behind the Blackboard. This video shows you how you can subscribe to receive an email  when a new release comes out with changes like this.

 

Here is our latest help documentation about getting the log files from SaaS:  https://help.blackboard.com/Learn/Administrator/SaaS/System_Management/Logs

Here's how. Watch this video.

mkauffman

My LTI xxx Doesn't Work

Posted by mkauffman Apr 24, 2019


Solution -  Use our reference tool provider and compare what you are doing with what works. See: https://github.com/blackboard/BBDN-LTI-Tool-Provider-Node

 

Example:

I can't figure out why my JSON doesn't create deep links. Can you help?

 

Sure -watch this video.

The following works as shown in the video. Compare your JSON to the working code.

 

{"@context":"http://purl.imsglobal.org/ctx/lti/v1/ContentItem","@graph":[{"@type":"LtiLinkItem","mediaType":"application/vnd.ims.lti.v1.ltilink","icon":{"@id":"https://www.wpclipart.com/animals/F/ferret/.cache/Ferret_black-footed.jpg","width":50,"height":50},"title":"Week 1 reading LTI + Link<script>alert('help me');</script> <span style=\"font-family: Garamond; font-weight: bold; font-size: 24px\">Hello</span>","text":"Read this section prior to your tutorial. <script>alert('help me');</script> <span style=\"font-family: Garamond; font-weight: bold; font-size: 24px\">This should be large and bold</span>","custom":{"chapter":"12","section":"3","duedate":"2018-03-31T11:15:00+01:00"},"placementAdvice":{"displayHeight":100,"displayWidth":100,"windowTarget":"_blank"}},{"@type":"LtiLinkItem","mediaType":"application/vnd.ims.lti.v1.ltilink","icon":{"@id":"https://www.wpclipart.com/animals/F/frogs/.cache/Frog_eyeing_dinner.png","width":50,"height":50},"title":"Week 2 reading LTI","text":"Read this section prior to your tutorial.","custom":{"chapter":"12","section":"4","duedate":"2019-05-24T23:15:00+01:00"},"placementAdvice":{"displayHeight":100,"displayWidth":100,"presentationDocumentTarget":"iframe","windowTarget":"_blank"},"lineItem":{"@type":"LineItem","label":"Chapter 12 quiz","reportingMethod":"res:totalScore","assignedActivity":{"@id":"http://toolprovider.example.com/assessment/66400","activityId":"a-9334df-33"},"scoreConstraints":{"@type":"NumericLimits","normalMaximum":100,"extraCreditMaximum":10,"totalMaximum":110}}},{"@type":"ContentItem","@id":":item1","title":"Assignment: Assignment Specification","mediaType":"text/html","text":"Assignment: Assignment Specification","url":"https://www.py4e.com/install.php","placementAdvice":{"presentationDocumentTarget":"WINDOW","windowTarget":"_blank"},"icon":{"@id":"https://www.dr-chuck.net/tsugi-static/font-awesome-4.4.0/png/lock.png","width":64,"height":64}},{"@type":"ContentItem","url":"http://www.imageserver.com/path/image.jpg","mediaType":"image/jpg","title":"Title for my picture","placementAdvice":{"height":100,"width":100}}]}

 

Hope this helps. Cheers!

On April 10, 2019, Eric Preston, Blackboard's resident LTI expert, spoke with us in Technical Office Hours. He gave us an overview of LTI technology. Watch recording in Bb Collaborate.

 

On May 1, 2019, Eric followed up with another, deeper dive into coding an LTI integration. Watch the recording in Bb Collaborate and check out the slide deck attached.

 

Here is the sample code referenced in the presentations: https://github.com/blackboard/BBDN-LTI-Tool-Provider-Node


There are still questions floating around about Ultra and Building Blocks. As an example, one developer writes the following. I'm writing this to answer these questions, and any others you might have.

 

We are currently using a building block for one of the tools that we make available to customers using Blackboard. It is our understanding that any tools using building blocks will not be made available if a customer has switched to the Ultra experience. We have a couple of questions:

  1. If the admin has enabled Ultra but an instructor has not enabled it at the course level, can the instructor still access our tool if the tool using a building block has already been made available to them?
  2. Will you still make tools using building blocks available to customers using the original experience, or can they only access a tool using a building block if it was made available to them before Ultra was released?

 

First, to help clarify around the first question, switching to the Ultra experience (navigation) does not remove the Original courses that exist in the system. Building Blocks that work in a SaaS environment will continue to work in these Original experience courses when the system is switched to the Ultra experience. If a new Original experience course is created, the Building Block functionality will be available in this new course.  However, the Building Block integrations will not be available for use in any Ultra Experience courses that are created. As we've discussed previously in this blog, only LTI & REST API integrations are are available in Ultra courses. Building Blocks can not surface content in an Ultra course.

 

Regarding the second question, yes clients can request that their support team install any building block they would like in their SaaS system, both Ultra navigation and Original experience, before or after the switch from Original Experience to Ultra.

Given that I've seen multiple questions about the IMS spec and Deep Linking 1.0, I'm writing this post.  Below, for reference from our test implementation of a Tool Provider GitHub - blackboard/BBDN-LTI-Tool-Provider-Node: A node.js LTI Tool Provider for testing LTI launches, Caliper, and Outc… is sample JSON that can serve as guide for what works. It places multiple links to the provider, the highlighted LineItem is the gradable item. Hope this helps!

 

{"@context":"http://purl.imsglobal.org/ctx/lti/v1/ContentItem","@graph":[{"@type":"LtiLinkItem","mediaType":"application/vnd.ims.lti.v1.ltilink","icon":{"@id":"https://www.wpclipart.com/animals/F/ferret/.cache/Ferret_black-footed.jpg","width":50,"height":50},"title":"Week 1 reading LTI + Link<script>alert('help me');</script> <span style=\"font-family: Garamond; font-weight: bold; font-size: 24px\">Hello</span>","text":"Read this section prior to your tutorial. <script>alert('help me');</script> <span style=\"font-family: Garamond; font-weight: bold; font-size: 24px\">This should be large and bold</span>","custom":{"chapter":"12","section":"3","duedate":"2018-03-31T11:15:00+01:00"},"placementAdvice":{"displayHeight":100,"displayWidth":100,"windowTarget":"_blank"}},{"@type":"LtiLinkItem","mediaType":"application/vnd.ims.lti.v1.ltilink","icon":{"@id":"https://www.wpclipart.com/animals/F/frogs/.cache/Frog_eyeing_dinner.png","width":50,"height":50},"title":"Week 2 reading LTI","text":"Read this section prior to your tutorial.","custom":{"chapter":"12","section":"4","duedate":"2019-05-24T23:15:00+01:00"},"placementAdvice":{"displayHeight":100,"displayWidth":100,"presentationDocumentTarget":"iframe","windowTarget":"_blank"},"lineItem":{"@type":"LineItem","label":"Chapter 12 quiz","reportingMethod":"res:totalScore","assignedActivity":{"@id":"http://toolprovider.example.com/assessment/66400","activityId":"a-9334df-33"},"scoreConstraints":{"@type":"NumericLimits","normalMaximum":100,"extraCreditMaximum":10,"totalMaximum":110}}},{"@type":"ContentItem","@id":":item1","title":"Assignment: Assignment Specification","mediaType":"text/html","text":"Assignment: Assignment Specification","url":"https://www.py4e.com/install.php","placementAdvice":{"presentationDocumentTarget":"WINDOW","windowTarget":"_blank"},"icon":{"@id":"https://www.dr-chuck.net/tsugi-static/font-awesome-4.4.0/png/lock.png","width":64,"height":64}},{"@type":"ContentItem","url":"http://www.imageserver.com/path/image.jpg","mediaType":"image/jpg","title":"Title for my picture","placementAdvice":{"height":100,"width":100}}]}

 

Next week, Wednesday April 24, at 1100 EDT you can ask our lead LTI Developer any questions you have about Deep Linking 1.0 and LTI 1.3/Advantage with Deep Linking 2.0 during our Technical Office Hours!

I'm writing this as we've had a few questions from developers come in who have never written a Web Application in their life. I hope this helps.

 

First, get up to speed on developing web applications. A Google search for 'web application in <your favorite language>' is a good start. Here's an example result that I found Quickstart: use Visual Studio to create a Python web app - Visual Studio | Microsoft Docs - Side comment - Visual Studio Code is one of the nicest tools I've seen come out of Microsoft.

 

Next, when you start coding your Web Application to integrate with Blackboard Learn, we recommend use of our REST APIs plus LTI. Use LTI as the starting point for the user of the Learn instance. Why? You get information about the user and any course context from the LTI launch parameters. Then, if necessary the LTI Tool Provider that you write can make additional REST API calls back into the Blackboard Learn instance that made the launch. You can also, for some cases just write a REST application that a user connects to Learn via Three-Legged OAuth and then makes REST calls on behalf of that user. Note that everything, your server/Tool Provider & Learn running in production will/should be using HTTPS via the standard port 443. See the following list of resources for getting started.

 

Here are several resources for developing REST Applications for Blackboard Learn:

We offer weekly technical office hours everyone is welcome to attend, free of charge: https://community.blackboard.com/groups/technical-office-hours (Link to join is on the upper right of the page.) LTI is an industry standard. Below are links to several resources:

 

I hope this helps you get started! Below is a high-level architecture diagram as an example. It's not meant to be all-inclusive, but does show one type of relationship between the User, the Blackboard Learn System, and your Application.

Blackboard-AppIntegrationArchitecture.jpg

mkauffman

Space Matters

Posted by mkauffman Mar 20, 2019

If you're having problems getting Let's Encrypt to work with your AMI, space matters.

 

Only this works - notice the space on either side of the :

ssldomain : <FQDN>

sslemail : <email address>

 

Not -

ssldomain: <FQDN>

sslemail: <email address>

 

Not -

ssldomain:<FQDN>

sslemail:<email address>

 

Reference https://community.blackboard.com/docs/DOC-4242-using-the-blackboard-learn-ami-for-rest-and-lti-development#jive_content_…

I just had a couple of great questions come in. After discussing with product management, here are the answers as of the date of this blog post. (Can you guess?)

 

Question: I want to move courses from one Bb instance to another, programmatically.  Assuming I have course exports from the source instance, is there an API to create courses in the target instance?

Answer: No

 

Question: Is there an API call to export an IMS Common Cartridge from a course.

Answer: No

 

More detail: Exporting and importing Common Cartridge data via REST APIs are not currently on the 2019 roadmap.

 

If you have a need for the above, head on over to https://community.blackboard.com/community/developers/learn/rest/pages/rest-api-ideas and rally your fellow developers around these. We may say "no", but not "never"*.

 

*Statements regarding our product development initiatives, including new products and future product upgrades, updates or enhancements represent our current intentions, but may be modified, delayed or abandoned without prior notice and there is no assurance that such offering, upgrades, updates or functionality will become available unless and until they have been made generally available to our customers.

 

See I'm sorry, Dave, I'm afraid I can't do that. for the answer to the question about displaying B2 content in an Ultra course. You can probably guess by the title, no is the answer.

 

I'm writing this post because we've had an additional question surface as Blackboard Partners have started providing  LTI integrations in addition to their B2s. The question being, "When I convert my Original course to an Ultra course, will my B2 links automatically be converted to the LTI link for the Partner content?" The answer is "No*."

 

*Except for a few Partner Cloud partners who are working with our team on a "migration tool" for their content. More details to come later in 2019.

Next time you go to developer.blackboard.com to register an application, you'll notice some changes. Now you can also register a LTI tool. You register an LTI tool in pretty much the same way you register a REST application. For more information about registering an LTI tool, see Register as a Developer and Manage Your Applications with the Developer Portal.

 

We will be further adjusting the developer portal to make it more powerful and easier to use, so stay tuned for more updates.