Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
k2oss authored Jun 16, 2020
1 parent 1e0afe5 commit 3974106
Show file tree
Hide file tree
Showing 13 changed files with 3,133 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 SourceCode Technology Holdings Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Binary file added OAuthResource.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
148 changes: 148 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# K2 Microsoft Teams Connector

This connector for K2 Nexus integrates with Microsoft Teams. It allows you to create, update, and delete Teams, Channels in Teams, and Tabs in Channels. It also allows you to send a message to a channel.

# Features

- Work with Teams, Channels, and Tabs using SmartObjects
- Send a message to a Channel
- SVG icons if you want to add Custom Workflow Steps to K2 Designer for four methods: Create Team, Update Team, Create Channel, Send Message to Channel
- Sample unit tests with mocks and code coverage
- RollupJS configuration for TypeScript


## Getting the Microsoft Teams Connector to work in your K2 environment

Before you see SmartObjects and run methods on them, you must do the following:

- Create an Azure App in your Azure tenant
- Assign permissions (Application and/or Delegated) to the app so it has the necessary permissions
in Microsoft Graph to work from K2. For more information about the rights required for each method, see the Help topic at https://k2.com/help/servicetypes/jssp/teams
- Create a secret for your app and copy the secret and the ID of the app for configuring an OAuth resource in K2
- Configure an OAuth Resource in K2 Management based on the Microsoft Online Resource Type
- Create a Microsoft Teams service type with your bundled .js file (or use the index.jssp file in this repo's release)
- Create a service instance for the type using the OAuth resource you created

### Creating the Azure App and Adding Permissions

Create a new app in Azure by browsing to **Azure Active Directory > App registrations**. Give it a name like **K2 for Microsoft Teams**. Once you have the app created, make a note of its Application ID. This is the app's client ID that you'll use when you create the OAuth resource in K2.

Also, you need to create a secret. Click Certificates & secrets and then click **New client secret**. Once you create the secret, make a note of it as you'll also need to add this to your OAuth Resource.

Next, configure permissions by clicking **API permissions**. Permissions allow K2 to act on behalf of users. There are **Application** and **Delegated** permissions available in Azure. It's safest to grant both types to the app where specified. Click the **Add a permission** button and find the following permissions to add (search usually works best):

* Azure Permissions
+ K2 API (search for this one and assign Delegated permissions)
+ Directory.Read.All
+ email
+ Group.Create
+ Group.ReadWrite.All
+ openid
+ profile
+ TeamsActivity.ReadWrite.All
+ TeamsActivity.Send
+ TeamsApp.ReadWrite.All
+ TeamSettings.ReadWrite.All
+ TeamsTab.ReadWrite.All
+ User.Read

Once you have all of these permissions granted, you must click the **Grant admin consent** button at the top of the page. This gives your new app the ability to perform Teams-related tasks suppported by the connector's methods. If you do not want to grant all of these permissions, you can grant a subset of the permissions but the connector methods will not function. If you choose, you can edit the connector source file directly to only have the methods you need for your Teams automation needs.

Lastly, make a note of the endpoints in your environment. At the top of the **Overview** page for your app, click the **Endpoints** button. Here you need to copy the **OAuth 2.0 authorization endpoint (v2)** and the **OAuth 2.0 token endpoint (v2)**.

### Creating the OAuth Resource in K2

Next, create the OAuth resource in K2. Follow these steps:

1. Browse to K2 Management and expand the **Authentication** node
2. Expand the **OAuth** node
3. Click **Resources** and then click **New**
4. Give your resource a name and then paste the authorization endpoint into the **Authorization Endpoint** field, and the token endpoint into the **Token Endpoint** and *Refresh Token Endpoint** fields.
5. Add the following parameters to your resource:
* Resource parameters
+ grant_type: **Token Value** = authorization_code, **Refresh Value** = refresh_token
+ client_id: the app ID that you made a note of for all three values
+ redirect_uri: for **Authorization Value** and **Token Value** put in the URL https://{KUID}.onk2.com/Identity/token/oauth/2
+ scope: for **Authorization Value** and **Token Value** put TeamsApp.ReadWrite.All
+ response_type: for **Authorization Value** put code
+ client_secret: for **Token Value** and *Refresh Value** put your client secret
6. Save the resource and confirm that it's similar to the following figure

![Example OAuth Resource for Microsoft Teams](/OAuthResource.png)

Once you've created your OAuth resource, you can now use it to configure a service instance, but you must first create your service type.

### Creating your Microsoft Teams Connector Service Type

Either build the project by cloning the repo or download the index.jssp from the release.

Once you have your index.jssp file for the Microsoft Teams Connector, create your service type using the example form from the Help topic or one you've built yourself.

When your service type is created, register a service instance using the OAuth resource you created, and generate SmartObjects.

## Creating Custom Workflow Steps

Also included in this repo are four SVG icons that you can use if you want to create custom workflow steps in the K2 Workflow Designer. The following icons are available:
+ Create Team (CreateTeam32.svg)
+ Update Team (UpdateTeam32.svg)
+ Create Channel (CreateChannel32.svg)
+ Send Message to Channel (MessageChannel32.svg)

For more information about creating custom workflow steps, see [Creating custom Workflow steps](https://help.k2.com/onlinehelp/k2cloud/DevRef/current/default.htm#Extend/WF/Steps/Steps-Creating.htm%3FTocPath%3DExtending%2520K2%2520Cloud%7CCustom%2520workflow%2520steps%7C_____3)

## Building the Microsoft Teams Connector

If you've made changes to the source code, use these steps to build a new version of your connector.

**Note**: This template requires [Node.js](https://nodejs.org/) v12.14.1+ to run.

Install the dependencies and devDependencies:

```bash
npm install
```

See the documentation for [@k2oss/k2-broker-core](https://www.npmjs.com/package/@k2oss/k2-broker-core)
for more information about how to use the broker SDK package.

# Running Unit Tests
To run the unit tests, run:

```bash
npm test
```

You can also use a development build for debugging and coverage gutters:

```bash
npm run test:dev
```

You will find the code coverage results in [coverage/index.html](./coverage/index.html).

# Building your bundled JS
When you're ready to build your connector, run the following command:

```bash
npm run build
```

Add :dev to the end of the build if you want to be able to read your bundled .js:

```bash
npm run build:dev
```

Find the bundled JavaScript file in the [dist/index.js](./dist/index.js). If you're using the example Create or Update From File SmartForm or you've built your own, rename this file to index.jssp in order to attach it to the form.

# Creating a service type
Once you have a bundled .js file, register the service type using the system SmartObject located
at System > Management > SmartObjects > SmartObjects > JavaScript Service
Provider and run the Create From File method. Note that you'll need a form to do this. You can build
your own or use the one provided in the Help topic.

### License

MIT, found in the [LICENSE](./LICENSE) file.

[www.k2.com](https://www.k2.com)
15 changes: 15 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = function (api) {
api.cache(true);
return {
presets: [
["@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3
}],
"@babel/preset-typescript"
],
comments: false,
exclude: [/(\/|\\)core-js(\/|\\)/]
}
};
7 changes: 7 additions & 0 deletions icons/CreateChannel32.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions icons/CreateTeam32.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions icons/MessageChannel32.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions icons/UpdateTeam32.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"name": "MicrosoftTeamsConnector",
"version": "1.0.0",
"description": "JSSP-based Microsoft Teams Connector",
"homepage": "https://www.k2.com",
"license": "MIT",
"private": true,
"author": {
"name": "K2 OSS",
"email": "[email protected]",
"url": "https://www.k2.com"
},
"files": [
"dist/index.js"
],
"keywords": [
"k2-extension",
"k2-broker"
],
"scripts": {
"build": "npm run build:bundle-prod",
"build:dev": "npm run build:bundle-dev",
"build:bundle-dev": "node node_modules/rollup/dist/bin/rollup -c --environment NODE_ENV:development",
"build:bundle-prod": "node node_modules/rollup/dist/bin/rollup -c --environment NODE_ENV:production",
"watch": "node node_modules/rollup/dist/bin/rollup -c --watch --environment NODE_ENV:development",
"run-tests": "nyc ava",
"test": "npm run build && npm run run-tests",
"test:dev": "npm run build:dev && npm run run-tests"
},
"ava": {
"typescript": {
"rewritePaths": {
"src/": "dist/"
}
}
},
"nyc": {
"reporter": [
"text",
"html",
"cobertura"
],
"exclude": [
"src/test.ts"
]
},
"devDependencies": {
"@ava/typescript": "1.0.0",
"@babel/core": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
"@babel/register": "^7.8.3",
"@babel/runtime": "^7.8.3",
"@k2oss/k2-broker-core": "1.0.0",
"@rollup/plugin-commonjs": "11.0.1",
"@rollup/plugin-json": "4.0.1",
"@rollup/plugin-node-resolve": "7.0.0",
"@rollup/plugin-replace": "2.3.0",
"ava": "^3.1.0",
"core-js": "^3.6.4",
"nyc": "^15.0.0",
"rollup": "^2.7.6",
"rollup-plugin-babel": "4.3.3",
"rollup-plugin-terser": "5.2.0"
}
}
87 changes: 87 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import json from '@rollup/plugin-json';
import babel from 'rollup-plugin-babel';
import { terser } from "rollup-plugin-terser";

const BUILD_ENV = JSON.stringify(process.env.NODE_ENV || 'development');
const devBuild = process.env.NODE_ENV === 'development';

function getOutputFile(inputFile) {
const inputFileIndex = inputFile.lastIndexOf('.');
const outputFile = (inputFileIndex >= 0 ? inputFile.substr(0, inputFileIndex) : inputFile) + ".js";
return (outputFile.startsWith("src/"))
? outputFile.substr(4)
: outputFile;
}

function buildConfig(inputFile) {

const outputFile = getOutputFile(inputFile);
const extensions = ['.js', '.ts'];
const runtimeHelpers = true;

const plugins = [
resolve(),
commonjs(),
replace({ BUILD_ENV, 'process.env.NODE_ENV': BUILD_ENV }),
json(),
babel({ extensions, runtimeHelpers })
];

if (!devBuild) {
plugins.push(
terser()
);
}

return {
input: inputFile,
output: {
file: 'dist/' + outputFile,
format: 'iife',
sourcemap: true,
strict: false, // HACK: Only required for preview.
},
plugins
};
}

function buildTestConfig(inputFile) {

const outputFile = getOutputFile(inputFile);
const extensions = ['.js', '.ts'];
const runtimeHelpers = true;

const plugins = [
resolve(),
commonjs(),
replace({ BUILD_ENV, 'process.env.NODE_ENV': BUILD_ENV }),
json(),
babel({ extensions, runtimeHelpers })
];

if (!devBuild) {
plugins.push(
terser()
);
}

return {
input: inputFile,
external: [ "ava" ],
external: () => true,
output: {
file: 'dist/' + outputFile,
format: 'cjs',
sourcemap: true
},
plugins
};
}

export default [
buildConfig('src/index.ts'),
buildTestConfig('src/test.ts')
];
Loading

0 comments on commit 3974106

Please sign in to comment.