diff --git a/.gitignore b/.gitignore index 6704566..dfa6950 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.DS_Store + # Logs logs *.log diff --git a/README.md b/README.md index 6dae3d0..54faef1 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,16 @@ The [Webex APIs](https://developer.webex.com/docs/getting-started) provide your - Execute a command on a Webex RoomOS device - ...and much more! +## Get a Token + +If you don't already have a Webex account, go ahead and [sign up](https://www.webex.com/pricing/free-trial.html)! You'll need an account to use the APIs and SDKs. + +When making requests to the Webex REST API, an Authentication HTTP header is used to identify the requesting user. This header must include an access token. This access token may be a personal access token from this site (see below), a Bot token, or an OAuth token from an Integration or Guest Issuer application. + +Our interactive API Reference uses your personal access token, which can be used to interact with the Webex API as yourself. This token has a short lifetime—only 12 hours after logging into this site—so it shouldn't be used outside of app development. When using this token, any actions taken through the API will be done as you. + +Visit https://developer.webex.com/docs/getting-started and scroll down to "Your Personal Access Token". You'll copy this, paste it into the sample code file you want to run, save, and send it in your REST client requests as a bearer token in the headers. + ## Meetings The [Webex Meetings REST API](https://developer.webex.com/docs/meetings) enables seamless integration of Webex Meetings into your websites, apps, and services. Schedule meetings, invite meeting attendees, update preferences, and more. @@ -19,6 +29,8 @@ The [Webex Meetings REST API](https://developer.webex.com/docs/meetings) enables https://developer.webex.com/docs/api/v1/meetings/create-a-meeting +See sample code in this repo under [./meetings/create/](./meetings/create/) + #### READ a Meeting https://developer.webex.com/docs/api/v1/meetings/get-a-meeting @@ -31,8 +43,20 @@ https://developer.webex.com/docs/api/v1/meetings/update-a-meeting https://developer.webex.com/docs/api/v1/meetings/delete-a-meeting -## Further Reading +## Language Reference -Check out these resources for more: +### Node +At the time of writing, we're using the latest LTS release of Node. + +- https://nodejs.dev/learn/making-http-requests-with-nodejs + + +## Don't be a Stranger + +- https://developer.webex.com/docs - https://developer.webex.com/blog +- https://developer.webex.com/support +- @WebexDevs: https://twitter.com/webexdevs + +Made with <3 by the Webex Developer Evangelism Team at Cisco diff --git a/meetings/README.md b/meetings/README.md new file mode 100644 index 0000000..d68baa6 --- /dev/null +++ b/meetings/README.md @@ -0,0 +1,35 @@ +# Webex REST API Sample Code > Meetings + +The [Webex Meetings REST API](https://developer.webex.com/docs/meetings) enables seamless integration of Webex Meetings into your websites, apps, and services. Schedule meetings, invite meeting attendees, update preferences, and more. + +## CRUD + +The acronymn CRUD stands for: (C)reate, (R)ead, (U)pdate, (D)elete, which forms a basic set of essential operations when working with data. In this case, the data pertains to Webex meetings. You may make calls to the Webex API to create meetings, list meetings, make changes to meetings, and cancel meetings. Each operation is demonstrated seperately in sub-folders under this directory. + +### CREATE + +Create a Webex meeting, using the REST API. + +See [./create/README.md](./create/README.md) + +### READ + +https://developer.webex.com/docs/api/v1/meetings/get-a-meeting + +### UPDATE + +https://developer.webex.com/docs/api/v1/meetings/update-a-meeting + +### DELETE + +https://developer.webex.com/docs/api/v1/meetings/delete-a-meeting + + +## Don't be a Stranger + +- https://developer.webex.com/docs +- https://developer.webex.com/blog +- https://developer.webex.com/support +- @WebexDevs: https://twitter.com/webexdevs + +Made with <3 by the Webex Developer Evangelism Team at Cisco diff --git a/meetings/create/README.md b/meetings/create/README.md new file mode 100644 index 0000000..acae85e --- /dev/null +++ b/meetings/create/README.md @@ -0,0 +1,25 @@ +# Webex REST API Sample Code > Meetings > Create + +This directory contains sample code demonstrating a JavaScript implementation of a REST client that calls the Meetings API to create a meeting. + +## Get a Token + +See `Get a Token` in the main [/README.md](../../README.md) + +## Run the code + +This sample is JS, intended to be run via Node: + +`node ./create_meeting.js` + +At the time of writing, we're using the latest LTS release of Node. + + +## Don't be a Stranger + +- https://developer.webex.com/docs +- https://developer.webex.com/blog +- https://developer.webex.com/support +- @WebexDevs: https://twitter.com/webexdevs + +Made with <3 by the Webex Developer Evangelism Team at Cisco diff --git a/meetings/create/create_meeting.js b/meetings/create/create_meeting.js new file mode 100644 index 0000000..4e0c3e6 --- /dev/null +++ b/meetings/create/create_meeting.js @@ -0,0 +1,125 @@ +/** + * _ + * __ _____| |__ _____ __ + * \ \ /\ / / _ \ '_ \ / _ \ \/ / + * \ V V / __/ |_) | __/> < @WebexDevs + * \_/\_/ \___|_.__/ \___/_/\_\ + * + * CREATE a meeting in Webex with the REST API in Node + * https://developer.webex.com/docs/api/v1/meetings/create-a-meeting + * + * Step 0: Have a (free) Webex account: https://cart.webex.com/sign-up + * Step 1: Log in to https://developer.webex.com/login + * Step 2: Find your bearer token at + * https://developer.webex.com/docs/getting-started under "Your + * Personal Access Token" in the middle of the page. + * Step 3: Replace the string on the line that defines const myWebexDeveloperToken, + * just below, with your personal bearer (access) token. Hit "save". + * Step 4: Run this file with node from within + * this directory on the command line: + * + * node ./create_meeting.js + * + * Step 5: Profit. Get your app listed in the Webex App Hub! + * https://apphub.webex.com/ + * + */ + +const https = require('https'); // https://nodejs.org/api/https.html + + +const myWebexDeveloperToken = 'REPLACE ME WITH YOUR WEBEX DEVELOPER PERSONAL ACCESS TOKEN'; + + +const body = JSON.stringify({ + title: 'Book Club Discussion: Curious George', // String, Required | Meeting title. The title can be a maximum of 128 characters long. + start: '2022-08-12T13:51:43-04:00', // String, Required | https://en.wikipedia.org/wiki/ISO_8601 format + end: '2022-08-12T14:38:16-04:00' // String, Required | Replace the start/end with the times you'd like +}); + +const options = { + method: 'POST', // https://en.wikipedia.org/wiki/Representational_state_transfer#Semantics_of_HTTP_methods + hostname: 'webexapis.com', // https://developer.webex.com/docs/basics + path: '/v1/meetings', // https://developer.webex.com/docs/meetings + port: 443, // https://en.wikipedia.org/wiki/HTTPS#Technical + headers: { + 'Authorization': 'Bearer ' + myWebexDeveloperToken, // https://oauth.net/2/bearer-tokens/ + 'Content-Type': 'application/json', // https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON + 'Content-Length': body.length // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length + } +} + +const req = https.request(options, (res) => { + + console.log(`statusCode: ${res.statusCode}`); // https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log( JSON.parse(data) ); // https://nodejs.org/en/knowledge/javascript-conventions/what-is-json/ + }); + + res.on('error', (e) => { + console.error('Error: ' + e.message); // https://nodejs.org/api/errors.html#errormessage_1 + }); + +}); + +req.on('error', (e) => { + console.error(e); +}); + +req.write(body); + +req.end(); + +/** + * Expected output: + * + * The HTTPS request should receive a status code. We expect a 200. + * + * The body of the response is JSON text. We expect a single object + * containing details of the newly-created meeting. These details + * should include at least the following fields: + * + * - id + * - meetingNumber + * - title + * - password + * - phoneAndVideoSystemPassword + * - meetingType + * - state + * - timezone + * - start + * - end + * - hostUserId + * - hostDisplayName + * - hostEmail + * - hostKey + * - siteUrl + * - webLink + * - sipAddress + * - dialInIpAddress + * - enabledAutoRecordMeeting + * - allowAnyUserToBeCoHost + * - allowFirstUserToBeCoHost + * - allowAuthenticatedDevices + * - enabledJoinBeforeHost + * - joinBeforeHostMinutes + * - enableConnectAudioBeforeHost + * - excludePassword + * - publicMeeting + * - enableAutomaticLock + * - telephony + * - accessCode + * - callInNumbers + * - links + * + * An example of the response JSON may be found + * in this directory: ./example_response.json + * + */ diff --git a/meetings/create/example_response.json b/meetings/create/example_response.json new file mode 100644 index 0000000..25f19a7 --- /dev/null +++ b/meetings/create/example_response.json @@ -0,0 +1,74 @@ +{ + "id": "870f51ff287b41be84648412901e0402", + "meetingNumber": "123456789", + "title": "Example Daily Meeting", + "agenda": "Example Agenda", + "password": "BgJep@43", + "phoneAndVideoSystemPassword": "12345678", + "meetingType": "meetingSeries", + "state": "active", + "timezone": "Asia/Shanghai", + "start": "2019-11-01T20:00:00+08:00", + "end": "2019-11-01T21:00:00+08:00", + "recurrence": "FREQ=DAILY;COUNT=10;INTERVAL=1", + "hostUserId": "Y2lzY29zcGFyazovL3VzL1BFT1BMRS9jN2ZkNzNmMi05ZjFlLTQ3ZjctYWEwNS05ZWI5OGJiNjljYzY", + "hostDisplayName": "John Andersen", + "hostEmail": "john.andersen@example.com", + "hostKey": "123456", + "siteUrl": "site4-example.webex.com", + "webLink": "https://site4-example.webex.com/site4/j.php?MTID=md41817da6a55b0925530cb88b3577b1e", + "sipAddress": "123456789@site4-example.webex.com", + "dialInIpAddress": "192.168.100.100", + "enabledAutoRecordMeeting": false, + "allowAnyUserToBeCoHost": false, + "enabledJoinBeforeHost": false, + "enableConnectAudioBeforeHost": false, + "joinBeforeHostMinutes": 0, + "excludePassword": false, + "publicMeeting": false, + "reminderTime": 10, + "sessionTypeId": 3, + "scheduledType": "meeting", + "enableAutomaticLock": false, + "automaticLockMinutes": 0, + "allowFirstUserToBeCoHost": false, + "allowAuthenticatedDevices": false, + "telephony": { + "accessCode": "1234567890", + "callInNumbers": [ + { + "label": "US Toll", + "callInNumber": "123456789", + "tollType": "toll" + } + ], + "links": [ + { + "rel": "globalCallinNumbers", + "href": "/api/v1/meetings/870f51ff287b41be84648412901e0402/globalCallinNumbers", + "method": "GET" + } + ] + }, + "registration": { + "autoAcceptRequest": "false", + "requireFirstName": "true", + "requireLastName": "true", + "requireEmail": "true", + "requireJobTitle": "false", + "requireCompanyName": "true", + "requireAddress1": "false", + "requireAddress2": "false", + "requireCity": "false", + "requireState": "false", + "requireZipCode": "false", + "requireCountryRegion": "true", + "requireWorkPhone": "true", + "requireFax": "false" + }, + "integrationTags": [ + "dbaeceebea5c4a63ac9d5ef1edfe36b9", + "85e1d6319aa94c0583a6891280e3437d", + "27226d1311b947f3a68d6bdf8e4e19a1" + ] +}