diff --git a/connectors/microsoft-teams/README.md b/connectors/microsoft-teams/README.md index 6540cece28..d38faf01cc 100644 --- a/connectors/microsoft-teams/README.md +++ b/connectors/microsoft-teams/README.md @@ -1,19 +1,4 @@ -> A template for new C8 connectors. -> -> To use this template update the following resources to match the name of your connector: -> -> * [README](./README.md) (title, description) -> * [Element Template](./element-templates/template-connector.json) -> * [POM](./pom.xml) (artifact name, description) -> * [Connector Function](./src/main/java/io/camunda/connector/MyConnectorFunction.java) (rename and update `OutboundConnector` annotation) -> * [Publish Action](./.github/workflows/publish-cloud-function.yaml#L95) (name) -> * [Service Provider Interface (SPI)](./src/main/resources/META-INF/services/io.camunda.connector.api.ConnectorFunction#L1) (rename) -> * [Third-party notices template](./licenses/third-party.ftl#L34) (name) -> -> ...and delete this hint. - - -# Camunda Connector Template +# Camunda Microsoft Teams Connector Find the user documentation in our [Camunda Platform 8 Docs](https://docs.camunda.io/docs/components/integration-framework/connectors/out-of-the-box-connectors/available-connectors-overview). diff --git a/connectors/microsoft-teams/connector.yml b/connectors/microsoft-teams/connector.yml new file mode 100644 index 0000000000..956527518a --- /dev/null +++ b/connectors/microsoft-teams/connector.yml @@ -0,0 +1,3 @@ +name: MSTEAMS +type: io.camunda:connector-microsoft-teams:1 +variables: [ authentication, data ] \ No newline at end of file diff --git a/connectors/microsoft-teams/element-templates/microsoft-teams.json b/connectors/microsoft-teams/element-templates/microsoft-teams.json index fc0e98b7c5..93a6823ff3 100644 --- a/connectors/microsoft-teams/element-templates/microsoft-teams.json +++ b/connectors/microsoft-teams/element-templates/microsoft-teams.json @@ -1,7 +1,7 @@ { "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", "name": "Microsoft Teams Connector", - "id": "io.camunda:connector-microsoft-teams:1", + "id": "io.camunda.connectors.MSTeams.v1", "description": "Create, update, and send a message to your Microsoft Teams", "documentationRef": "https://docs.camunda.io/docs/components/integration-framework/connectors/out-of-the-box-connectors/microsoft-teams/", "version": 1, @@ -691,6 +691,6 @@ } ], "icon": { - "contents": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iODAwIiB3aWR0aD0iMTIwMCIgdmlld0JveD0iLTMzNC4zMjQ5NSAtNTE4LjMzMzUgMjg5Ny40ODI5IDMxMTAuMDAxIj48cGF0aCBkPSJNMTU1NC42MzcgNzc3LjVoNTc1LjcxM2M1NC4zOTEgMCA5OC40ODMgNDQuMDkyIDk4LjQ4MyA5OC40ODN2NTI0LjM5OGMwIDE5OS45MDEtMTYyLjA1MSAzNjEuOTUyLTM2MS45NTIgMzYxLjk1MmgtMS43MTFjLTE5OS45MDEuMDI4LTM2MS45NzUtMTYyLTM2Mi4wMDQtMzYxLjkwMVY4MjguOTcxYy4wMDEtMjguNDI3IDIzLjA0NS01MS40NzEgNTEuNDcxLTUxLjQ3MXoiIGZpbGw9IiM1MDU5QzkiLz48Y2lyY2xlIHI9IjIzMy4yNSIgY3k9IjQ0MC41ODMiIGN4PSIxOTQzLjc1IiBmaWxsPSIjNTA1OUM5Ii8+PGNpcmNsZSByPSIzMzYuOTE3IiBjeT0iMzM2LjkxNyIgY3g9IjEyMTguMDgzIiBmaWxsPSIjN0I4M0VCIi8+PHBhdGggZD0iTTE2NjcuMzIzIDc3Ny41SDcxNy4wMWMtNTMuNzQzIDEuMzMtOTYuMjU3IDQ1LjkzMS05NS4wMSA5OS42NzZ2NTk4LjEwNWMtNy41MDUgMzIyLjUxOSAyNDcuNjU3IDU5MC4xNiA1NzAuMTY3IDU5OC4wNTMgMzIyLjUxLTcuODkzIDU3Ny42NzEtMjc1LjUzNCA1NzAuMTY3LTU5OC4wNTNWODc3LjE3NmMxLjI0NS01My43NDUtNDEuMjY4LTk4LjM0Ni05NS4wMTEtOTkuNjc2eiIgZmlsbD0iIzdCODNFQiIvPjxwYXRoIGQ9Ik0xMjQ0IDc3Ny41djgzOC4xNDVjLS4yNTggMzguNDM1LTIzLjU0OSA3Mi45NjQtNTkuMDkgODcuNTk4YTkxLjg1NiA5MS44NTYgMCAwMS0zNS43NjUgNy4yNTdINjY3LjYxM2MtNi43MzgtMTcuMTA1LTEyLjk1OC0zNC4yMS0xOC4xNDItNTEuODMzYTYzMS4yODcgNjMxLjI4NyAwIDAxLTI3LjQ3Mi0xODMuNDlWODc3LjAyYy0xLjI0Ni01My42NTkgNDEuMTk4LTk4LjE5IDk0Ljg1NS05OS41MnoiIG9wYWNpdHk9Ii4xIi8+PHBhdGggZD0iTTExOTIuMTY3IDc3Ny41djg4OS45NzhhOTEuODAyIDkxLjgwMiAwIDAxLTcuMjU3IDM1Ljc2NWMtMTQuNjM0IDM1LjU0MS00OS4xNjMgNTguODMzLTg3LjU5OCA1OS4wOUg2OTEuOTc1Yy04LjgxMi0xNy4xMDUtMTcuMTA1LTM0LjIxLTI0LjM2Mi01MS44MzMtNy4yNTctMTcuNjIzLTEyLjk1OC0zNC4yMS0xOC4xNDItNTEuODMzYTYzMS4yODIgNjMxLjI4MiAwIDAxLTI3LjQ3Mi0xODMuNDlWODc3LjAyYy0xLjI0Ni01My42NTkgNDEuMTk4LTk4LjE5IDk0Ljg1NS05OS41MnoiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTExOTIuMTY3IDc3Ny41djc4Ni4zMTJjLS4zOTUgNTIuMjIzLTQyLjYzMiA5NC40Ni05NC44NTUgOTQuODU1aC00NDcuODRBNjMxLjI4MiA2MzEuMjgyIDAgMDE2MjIgMTQ3NS4xNzdWODc3LjAyYy0xLjI0Ni01My42NTkgNDEuMTk4LTk4LjE5IDk0Ljg1NS05OS41MnoiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTExNDAuMzMzIDc3Ny41djc4Ni4zMTJjLS4zOTUgNTIuMjIzLTQyLjYzMiA5NC40Ni05NC44NTUgOTQuODU1SDY0OS40NzJBNjMxLjI4MiA2MzEuMjgyIDAgMDE2MjIgMTQ3NS4xNzdWODc3LjAyYy0xLjI0Ni01My42NTkgNDEuMTk4LTk4LjE5IDk0Ljg1NS05OS41MnoiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTEyNDQgNTA5LjUyMnYxNjMuMjc1Yy04LjgxMi41MTgtMTcuMTA1IDEuMDM3LTI1LjkxNyAxLjAzNy04LjgxMiAwLTE3LjEwNS0uNTE4LTI1LjkxNy0xLjAzN2EyODQuNDcyIDI4NC40NzIgMCAwMS01MS44MzMtOC4yOTNjLTEwNC45NjMtMjQuODU3LTE5MS42NzktOTguNDY5LTIzMy4yNS0xOTguMDAzYTI4OC4wMiAyODguMDIgMCAwMS0xNi41ODctNTEuODMzaDI1OC42NDhjNTIuMzA1LjE5OCA5NC42NTcgNDIuNTQ5IDk0Ljg1NiA5NC44NTR6IiBvcGFjaXR5PSIuMSIvPjxwYXRoIGQ9Ik0xMTkyLjE2NyA1NjEuMzU1djExMS40NDJhMjg0LjQ3MiAyODQuNDcyIDAgMDEtNTEuODMzLTguMjkzYy0xMDQuOTYzLTI0Ljg1Ny0xOTEuNjc5LTk4LjQ2OS0yMzMuMjUtMTk4LjAwM2gxOTAuMjI4YzUyLjMwNC4xOTggOTQuNjU2IDQyLjU1IDk0Ljg1NSA5NC44NTR6IiBvcGFjaXR5PSIuMiIvPjxwYXRoIGQ9Ik0xMTkyLjE2NyA1NjEuMzU1djExMS40NDJhMjg0LjQ3MiAyODQuNDcyIDAgMDEtNTEuODMzLTguMjkzYy0xMDQuOTYzLTI0Ljg1Ny0xOTEuNjc5LTk4LjQ2OS0yMzMuMjUtMTk4LjAwM2gxOTAuMjI4YzUyLjMwNC4xOTggOTQuNjU2IDQyLjU1IDk0Ljg1NSA5NC44NTR6IiBvcGFjaXR5PSIuMiIvPjxwYXRoIGQ9Ik0xMTQwLjMzMyA1NjEuMzU1djEwMy4xNDhjLTEwNC45NjMtMjQuODU3LTE5MS42NzktOTguNDY5LTIzMy4yNS0xOTguMDAzaDEzOC4zOTVjNTIuMzA1LjE5OSA5NC42NTYgNDIuNTUxIDk0Ljg1NSA5NC44NTV6IiBvcGFjaXR5PSIuMiIvPjxsaW5lYXJHcmFkaWVudCBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIC0xIDAgMjA3NS4zMzMpIiB5Mj0iMzk0LjI2MSIgeDI9Ijk0Mi4yMzQiIHkxPSIxNjgzLjA3MyIgeDE9IjE5OC4wOTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjNWE2MmMzIi8+PHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0iIzRkNTViZCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzM5NDBhYiIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTk1LjAxIDQ2Ni41aDk1MC4zMTJjNTIuNDczIDAgOTUuMDEgNDIuNTM4IDk1LjAxIDk1LjAxdjk1MC4zMTJjMCA1Mi40NzMtNDIuNTM4IDk1LjAxLTk1LjAxIDk1LjAxSDk1LjAxYy01Mi40NzMgMC05NS4wMS00Mi41MzgtOTUuMDEtOTUuMDFWNTYxLjUxYzAtNTIuNDcyIDQyLjUzOC05NS4wMSA5NS4wMS05NS4wMXoiIGZpbGw9InVybCgjYSkiLz48cGF0aCBkPSJNODIwLjIxMSA4MjguMTkzaC0xODkuOTd2NTE3LjI5N2gtMTIxLjAzVjgyOC4xOTNIMzIwLjEyM1Y3MjcuODQ0aDUwMC4wODh6IiBmaWxsPSIjRkZGIi8+PC9zdmc+" + "contents": "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='18' width='18' viewBox='-334.32495 -518.3335 2897.4829 3110.001'%3E%3Cpath d='M1554.637 777.5h575.713c54.391 0 98.483 44.092 98.483 98.483v524.398c0 199.901-162.051 361.952-361.952 361.952h-1.711c-199.901.028-361.975-162-362.004-361.901V828.971c.001-28.427 23.045-51.471 51.471-51.471z' fill='%235059C9'/%3E%3Ccircle r='233.25' cy='440.583' cx='1943.75' fill='%235059C9'/%3E%3Ccircle r='336.917' cy='336.917' cx='1218.083' fill='%237B83EB'/%3E%3Cpath d='M1667.323 777.5H717.01c-53.743 1.33-96.257 45.931-95.01 99.676v598.105c-7.505 322.519 247.657 590.16 570.167 598.053 322.51-7.893 577.671-275.534 570.167-598.053V877.176c1.245-53.745-41.268-98.346-95.011-99.676z' fill='%237B83EB'/%3E%3Cpath d='M1244 777.5v838.145c-.258 38.435-23.549 72.964-59.09 87.598a91.856 91.856 0 01-35.765 7.257H667.613c-6.738-17.105-12.958-34.21-18.142-51.833a631.287 631.287 0 01-27.472-183.49V877.02c-1.246-53.659 41.198-98.19 94.855-99.52z' opacity='.1'/%3E%3Cpath d='M1192.167 777.5v889.978a91.802 91.802 0 01-7.257 35.765c-14.634 35.541-49.163 58.833-87.598 59.09H691.975c-8.812-17.105-17.105-34.21-24.362-51.833-7.257-17.623-12.958-34.21-18.142-51.833a631.282 631.282 0 01-27.472-183.49V877.02c-1.246-53.659 41.198-98.19 94.855-99.52z' opacity='.2'/%3E%3Cpath d='M1192.167 777.5v786.312c-.395 52.223-42.632 94.46-94.855 94.855h-447.84A631.282 631.282 0 01622 1475.177V877.02c-1.246-53.659 41.198-98.19 94.855-99.52z' opacity='.2'/%3E%3Cpath d='M1140.333 777.5v786.312c-.395 52.223-42.632 94.46-94.855 94.855H649.472A631.282 631.282 0 01622 1475.177V877.02c-1.246-53.659 41.198-98.19 94.855-99.52z' opacity='.2'/%3E%3Cpath d='M1244 509.522v163.275c-8.812.518-17.105 1.037-25.917 1.037-8.812 0-17.105-.518-25.917-1.037a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003a288.02 288.02 0 01-16.587-51.833h258.648c52.305.198 94.657 42.549 94.856 94.854z' opacity='.1'/%3E%3Cpath d='M1192.167 561.355v111.442a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003h190.228c52.304.198 94.656 42.55 94.855 94.854z' opacity='.2'/%3E%3Cpath d='M1192.167 561.355v111.442a284.472 284.472 0 01-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003h190.228c52.304.198 94.656 42.55 94.855 94.854z' opacity='.2'/%3E%3Cpath d='M1140.333 561.355v103.148c-104.963-24.857-191.679-98.469-233.25-198.003h138.395c52.305.199 94.656 42.551 94.855 94.855z' opacity='.2'/%3E%3ClinearGradient gradientTransform='matrix(1 0 0 -1 0 2075.333)' y2='394.261' x2='942.234' y1='1683.073' x1='198.099' gradientUnits='userSpaceOnUse' id='a'%3E%3Cstop offset='0' stop-color='%235a62c3'/%3E%3Cstop offset='.5' stop-color='%234d55bd'/%3E%3Cstop offset='1' stop-color='%233940ab'/%3E%3C/linearGradient%3E%3Cpath d='M95.01 466.5h950.312c52.473 0 95.01 42.538 95.01 95.01v950.312c0 52.473-42.538 95.01-95.01 95.01H95.01c-52.473 0-95.01-42.538-95.01-95.01V561.51c0-52.472 42.538-95.01 95.01-95.01z' fill='url(%23a)'/%3E%3Cpath d='M820.211 828.193h-189.97v517.297h-121.03V828.193H320.123V727.844h500.088z' fill='%23FFF'/%3E%3C/svg%3E" } } \ No newline at end of file diff --git a/connectors/microsoft-teams/pom.xml b/connectors/microsoft-teams/pom.xml index 885431ab23..9b036a34a6 100644 --- a/connectors/microsoft-teams/pom.xml +++ b/connectors/microsoft-teams/pom.xml @@ -4,15 +4,15 @@ io.camunda.connector connector-parent - 0.2.2 - + 0.4.0-SNAPSHOT + - connector-template-internal - Camunda Connector Template (Internal) - connector-template-internal + connector-microsoft-teams + Camunda Microsoft Teams Connector + connector-microsoft-teams jar - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT @@ -25,6 +25,10 @@ + 1.1.0 + 5.41.0 + 1.7.1 + Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under one or more contributor license agreements. Licensed under a proprietary license. See the License.txt file for more information. You may not use this file @@ -42,6 +46,29 @@ except in compliance with the proprietary license. connector-validation provided + + + com.microsoft.graph + microsoft-graph + ${version.microsoft-graph} + + + com.azure + azure-identity + ${version.azure-identity} + compile + + + + com.google.code.gson + gson + + + org.danilopianini + gson-extras + ${version.gson-extras} + + org.slf4j slf4j-api @@ -134,7 +161,15 @@ except in compliance with the proprietary license. io.camunda.connector connector-runtime-cloud - 0.2.0 + 0.3.0 + + + io.camunda.connector + connector-core + + + io.camunda.connector + connector-validation diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/Authentication.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/Authentication.java deleted file mode 100644 index 7da574e03b..0000000000 --- a/connectors/microsoft-teams/src/main/java/io/camunda/connector/Authentication.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. Licensed under a proprietary license. - * See the License.txt file for more information. You may not use this file - * except in compliance with the proprietary license. - */ -package io.camunda.connector; - -import io.camunda.connector.api.annotation.Secret; -import jakarta.validation.constraints.NotEmpty; -import java.util.Objects; - -public class Authentication { - - @NotEmpty private String user; - - @NotEmpty @Secret private String token; - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - @Override - public int hashCode() { - return Objects.hash(token, user); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - Authentication other = (Authentication) obj; - return Objects.equals(token, other.token) && Objects.equals(user, other.user); - } - - @Override - public String toString() { - return "Authentication [user=" + user + ", token=" + token + "]"; - } -} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MSTeamsFunction.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/MSTeamsFunction.java new file mode 100644 index 0000000000..83f049ae3a --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/MSTeamsFunction.java @@ -0,0 +1,46 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector; + +import com.google.gson.Gson; +import io.camunda.connector.api.annotation.OutboundConnector; +import io.camunda.connector.api.outbound.OutboundConnectorContext; +import io.camunda.connector.api.outbound.OutboundConnectorFunction; +import io.camunda.connector.model.MSTeamsRequest; +import io.camunda.connector.suppliers.GraphServiceClientSupplier; +import io.camunda.connector.suppliers.GsonSupplier; + +@OutboundConnector( + name = "MSTEAMS", + inputVariables = {"authentication", "data"}, + type = "io.camunda:connector-microsoft-teams:1") +public class MSTeamsFunction implements OutboundConnectorFunction { + + private final Gson gson; + private final GraphServiceClientSupplier graphSupplier; + + public MSTeamsFunction() { + this(new GraphServiceClientSupplier(), GsonSupplier.getGson()); + } + + public MSTeamsFunction(final GraphServiceClientSupplier graphSupplier, final Gson gson) { + this.graphSupplier = graphSupplier; + this.gson = gson; + } + + @Override + public Object execute(OutboundConnectorContext context) { + + final var variables = context.getVariables(); + final var msTeamsRequest = gson.fromJson(variables, MSTeamsRequest.class); + + context.validate(msTeamsRequest); + context.replaceSecrets(msTeamsRequest); + + return msTeamsRequest.invoke(graphSupplier); + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorFunction.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorFunction.java deleted file mode 100644 index 96913ad472..0000000000 --- a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorFunction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. Licensed under a proprietary license. - * See the License.txt file for more information. You may not use this file - * except in compliance with the proprietary license. - */ -package io.camunda.connector; - -import io.camunda.connector.api.annotation.OutboundConnector; -import io.camunda.connector.api.outbound.OutboundConnectorContext; -import io.camunda.connector.api.outbound.OutboundConnectorFunction; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@OutboundConnector( - name = "MYCONNECTOR", - inputVariables = {"myProperty", "authentication"}, - type = "io.camunda:my-connector:1") -public class MyConnectorFunction implements OutboundConnectorFunction { - - private static final Logger LOGGER = LoggerFactory.getLogger(MyConnectorFunction.class); - - @Override - public Object execute(OutboundConnectorContext context) throws Exception { - var connectorRequest = context.getVariablesAsType(MyConnectorRequest.class); - context.validate(connectorRequest); - context.replaceSecrets(connectorRequest); - - return executeConnector(connectorRequest); - } - - private MyConnectorResult executeConnector(final MyConnectorRequest connectorRequest) { - // TODO: implement connector logic - LOGGER.info("Executing my connector with request {}", connectorRequest); - var result = new MyConnectorResult(); - result.setMyProperty(connectorRequest.getMyProperty()); - return result; - } -} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorRequest.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorRequest.java deleted file mode 100644 index 5ce6066083..0000000000 --- a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. Licensed under a proprietary license. - * See the License.txt file for more information. You may not use this file - * except in compliance with the proprietary license. - */ -package io.camunda.connector; - -import io.camunda.connector.api.annotation.Secret; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import java.util.Objects; - -public class MyConnectorRequest { - - @NotEmpty private String myProperty; - - @Valid @NotNull @Secret private Authentication authentication; - - // TODO: add request properties - - public String getMyProperty() { - return myProperty; - } - - public void setMyProperty(final String myProperty) { - this.myProperty = myProperty; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - MyConnectorRequest that = (MyConnectorRequest) o; - return myProperty.equals(that.myProperty) && authentication.equals(that.authentication); - } - - @Override - public int hashCode() { - return Objects.hash(myProperty, authentication); - } - - @Override - public String toString() { - return "MyConnectorRequest{" - + "myProperty='" - + myProperty - + '\'' - + ", authentication=" - + authentication - + '}'; - } -} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorResult.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorResult.java deleted file mode 100644 index bcf384ef76..0000000000 --- a/connectors/microsoft-teams/src/main/java/io/camunda/connector/MyConnectorResult.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. Licensed under a proprietary license. - * See the License.txt file for more information. You may not use this file - * except in compliance with the proprietary license. - */ -package io.camunda.connector; - -import java.util.Objects; - -public class MyConnectorResult { - - // TODO: define connector result properties, which are returned to the process engine - private String myProperty; - - public String getMyProperty() { - return myProperty; - } - - public void setMyProperty(String myProperty) { - this.myProperty = myProperty; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final MyConnectorResult that = (MyConnectorResult) o; - return Objects.equals(myProperty, that.myProperty); - } - - @Override - public int hashCode() { - return Objects.hash(myProperty); - } - - @Override - public String toString() { - return "MyConnectorResult{" + "myProperty='" + myProperty + '\'' + '}'; - } -} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/MSTeamsRequest.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/MSTeamsRequest.java new file mode 100644 index 0000000000..6ae5f0bf62 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/MSTeamsRequest.java @@ -0,0 +1,63 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model; + +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.authentication.MSTeamsAuthentication; +import io.camunda.connector.model.request.MSTeamsRequestData; +import io.camunda.connector.suppliers.GraphServiceClientSupplier; +import java.util.Objects; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +public class MSTeamsRequest { + + @Valid @NotNull @Secret private MSTeamsAuthentication authentication; + @Valid @NotNull @Secret private MSTeamsRequestData data; + + public Object invoke(final GraphServiceClientSupplier graphSupplier) { + return data.invoke(authentication.buildAndGetGraphServiceClient(graphSupplier)); + } + + public MSTeamsAuthentication getAuthentication() { + return authentication; + } + + public void setAuthentication(final MSTeamsAuthentication authentication) { + this.authentication = authentication; + } + + public MSTeamsRequestData getData() { + return data; + } + + public void setData(final MSTeamsRequestData data) { + this.data = data; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final MSTeamsRequest that = (MSTeamsRequest) o; + return Objects.equals(authentication, that.authentication) && Objects.equals(data, that.data); + } + + @Override + public int hashCode() { + return Objects.hash(authentication, data); + } + + @Override + public String toString() { + return "MSTeamsRequest{" + "authentication=" + authentication + ", data=" + data + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/Member.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/Member.java new file mode 100644 index 0000000000..50b8d3627e --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/Member.java @@ -0,0 +1,105 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model; + +import com.google.gson.JsonPrimitive; +import io.camunda.connector.api.annotation.Secret; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.NotNull; + +public class Member { + + public static final String USER_DATA_BIND = "user@odata.bind"; + public static final String USER_DATA_TYPE = "@odata.type"; + public static final JsonPrimitive USER_CONVERSATION_MEMBER = + new JsonPrimitive("#microsoft.graph.aadUserConversationMember"); + public static final List OWNER_ROLES = List.of("owner"); + + @Secret private String userId; + @Secret private String userPrincipalName; + @Secret @NotNull private List roles; + + @AssertTrue(message = "Missing one of properties : [userId, userPrincipalName]") + private boolean isUserOrNameExist() { + return userId != null + && !userId.isBlank() + && userPrincipalName != null + && !userPrincipalName.isBlank(); + } + + public JsonPrimitive getAsGraphJsonPrimitive() { + return new JsonPrimitive( + "https://graph.microsoft.com/v1.0/users('" + + Optional.ofNullable(userId).orElse(userPrincipalName) + + "')"); + } + + public static JsonPrimitive toGraphJsonPrimitive(final String user) { + return new JsonPrimitive( + "https://graph.microsoft.com/v1.0/users('" + + Optional.ofNullable(user) + .orElseThrow( + () -> new NullPointerException("Must be userId or user principal name")) + + "')"); + } + + public String getUserId() { + return userId; + } + + public void setUserId(final String userId) { + this.userId = userId; + } + + public List getRoles() { + return roles; + } + + public void setRoles(final List roles) { + this.roles = roles; + } + + public String getUserPrincipalName() { + return userPrincipalName; + } + + public void setUserPrincipalName(final String userPrincipalName) { + this.userPrincipalName = userPrincipalName; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Member member = (Member) o; + return Objects.equals(userId, member.userId) + && Objects.equals(userPrincipalName, member.userPrincipalName) + && Objects.equals(roles, member.roles); + } + + @Override + public int hashCode() { + return Objects.hash(userId, userPrincipalName, roles); + } + + @Override + public String toString() { + return "Member{" + + "userId='" + + userId + + "'" + + ", userPrincipalName='" + + userPrincipalName + + "'" + + ", roles=" + + roles + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/OrderBy.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/OrderBy.java new file mode 100644 index 0000000000..48fa9531ab --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/OrderBy.java @@ -0,0 +1,26 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model; + +public enum OrderBy { + lastModifiedDateTime("lastModifiedDateTime desc"), + createdDateTime("createdDateTime desc"); + + private String value; + + OrderBy(final String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(final String value) { + this.value = value; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/BearerAuthentication.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/BearerAuthentication.java new file mode 100644 index 0000000000..28d140997a --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/BearerAuthentication.java @@ -0,0 +1,50 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.authentication; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.suppliers.GraphServiceClientSupplier; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class BearerAuthentication extends MSTeamsAuthentication { + @Secret @NotBlank private String token; + + @Override + public GraphServiceClient buildAndGetGraphServiceClient( + GraphServiceClientSupplier clientSupplier) { + return clientSupplier.buildAndGetGraphServiceClient(token); + } + + public String getToken() { + return token; + } + + public void setToken(final String token) { + this.token = token; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final BearerAuthentication that = (BearerAuthentication) o; + return Objects.equals(token, that.token); + } + + @Override + public int hashCode() { + return Objects.hash(token); + } + + @Override + public String toString() { + return "BearerAuthentication{" + "token='[secret_token]'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/ClientSecretAuthentication.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/ClientSecretAuthentication.java new file mode 100644 index 0000000000..70dd152e7c --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/ClientSecretAuthentication.java @@ -0,0 +1,82 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.authentication; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.suppliers.GraphServiceClientSupplier; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class ClientSecretAuthentication extends MSTeamsAuthentication { + @Secret @NotBlank private String clientId; + @Secret @NotBlank private String tenantId; + @Secret @NotBlank private String clientSecret; + + @Override + public GraphServiceClient buildAndGetGraphServiceClient( + final GraphServiceClientSupplier clientSupplier) { + return clientSupplier.buildAndGetGraphServiceClient(this); + } + + public String getClientId() { + return clientId; + } + + public void setClientId(final String clientId) { + this.clientId = clientId; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(final String tenantId) { + this.tenantId = tenantId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(final String clientSecret) { + this.clientSecret = clientSecret; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ClientSecretAuthentication that = (ClientSecretAuthentication) o; + return Objects.equals(clientId, that.clientId) + && Objects.equals(tenantId, that.tenantId) + && Objects.equals(clientSecret, that.clientSecret); + } + + @Override + public int hashCode() { + return Objects.hash(clientId, tenantId, clientSecret); + } + + @Override + public String toString() { + return "ClientSecretAuthentication{" + + "clientId='" + + clientId + + "'" + + ", tenantId='" + + tenantId + + "'" + + ", clientSecret='[client secret]'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/MSTeamsAuthentication.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/MSTeamsAuthentication.java new file mode 100644 index 0000000000..9c8974487f --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/authentication/MSTeamsAuthentication.java @@ -0,0 +1,18 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.authentication; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.suppliers.GraphServiceClientSupplier; +import okhttp3.Request; + +public abstract class MSTeamsAuthentication { + private transient String type; + + public abstract GraphServiceClient buildAndGetGraphServiceClient( + GraphServiceClientSupplier clientSupplier); +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/MSTeamsRequestData.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/MSTeamsRequestData.java new file mode 100644 index 0000000000..668a98e183 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/MSTeamsRequestData.java @@ -0,0 +1,17 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request; + +import com.microsoft.graph.requests.GraphServiceClient; +import okhttp3.Request; + +public abstract class MSTeamsRequestData { + + private transient String method; + + public abstract Object invoke(final GraphServiceClient graphClient); +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/CreateChannel.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/CreateChannel.java new file mode 100644 index 0000000000..edb43b84a3 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/CreateChannel.java @@ -0,0 +1,147 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.models.AadUserConversationMember; +import com.microsoft.graph.models.Channel; +import com.microsoft.graph.models.ChannelMembershipType; +import com.microsoft.graph.requests.ConversationMemberCollectionPage; +import com.microsoft.graph.requests.ConversationMemberCollectionResponse; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.Member; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.List; +import java.util.Objects; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class CreateChannel extends MSTeamsRequestData { + @NotBlank @Secret protected String groupId; + @NotBlank @Secret private String name; + @Secret private String description; + @NotBlank private String channelType; + private String owner; + + @AssertTrue(message = "property owner is required") + private boolean isOwnerValid() { + if (!ChannelMembershipType.STANDARD.name().equalsIgnoreCase(channelType)) { + return owner != null && !owner.isBlank(); + } + return true; + } + + public Channel invoke(final GraphServiceClient graphClient) { + ChannelMembershipType type = ChannelMembershipType.valueOf(channelType.toUpperCase()); + Channel channel = new Channel(); + channel.displayName = name; + channel.description = description; + channel.membershipType = type; + + if (type != ChannelMembershipType.STANDARD) { + + AadUserConversationMember members = new AadUserConversationMember(); + members + .additionalDataManager() + .put(Member.USER_DATA_BIND, Member.toGraphJsonPrimitive(owner)); + members.additionalDataManager().put(Member.USER_DATA_TYPE, Member.USER_CONVERSATION_MEMBER); + members.roles = Member.OWNER_ROLES; + + ConversationMemberCollectionResponse conversationMemberCollectionResponse = + new ConversationMemberCollectionResponse(); + conversationMemberCollectionResponse.value = List.of(members); + + channel.members = + new ConversationMemberCollectionPage(conversationMemberCollectionResponse, null); + } + + return graphClient.teams(groupId).channels().buildRequest().post(channel); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(final String description) { + this.description = description; + } + + public String getChannelType() { + return channelType; + } + + public void setChannelType(final String channelType) { + this.channelType = channelType; + } + + public String getOwner() { + return owner; + } + + public void setOwner(final String owner) { + this.owner = owner; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CreateChannel that = (CreateChannel) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(name, that.name) + && Objects.equals(description, that.description) + && Objects.equals(channelType, that.channelType) + && Objects.equals(owner, that.owner); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, name, description, channelType, owner); + } + + @Override + public String toString() { + return "CreateChannel{" + + "groupId='" + + groupId + + "'" + + ", name='" + + name + + "'" + + ", description='" + + description + + "'" + + ", channelType='" + + channelType + + "'" + + ", owner='" + + owner + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannel.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannel.java new file mode 100644 index 0000000000..f3b3077c5b --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannel.java @@ -0,0 +1,63 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class GetChannel extends MSTeamsRequestData { + + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.teams(groupId).channels(channelId).buildRequest().get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GetChannel that = (GetChannel) o; + return Objects.equals(groupId, that.groupId) && Objects.equals(channelId, that.channelId); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId); + } + + @Override + public String toString() { + return "GetChannel{" + "groupId='" + groupId + "'" + ", channelId='" + channelId + "'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannelMessage.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannelMessage.java new file mode 100644 index 0000000000..eb14012973 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/GetChannelMessage.java @@ -0,0 +1,84 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class GetChannelMessage extends MSTeamsRequestData { + + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + @NotBlank @Secret private String messageId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.teams(groupId).channels(channelId).messages(messageId).buildRequest().get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(final String messageId) { + this.messageId = messageId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GetChannelMessage that = (GetChannelMessage) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(channelId, that.channelId) + && Objects.equals(messageId, that.messageId); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId, messageId); + } + + @Override + public String toString() { + return "GetMessageFromChannel{" + + "groupId='" + + groupId + + "'" + + ", channelId='" + + channelId + + "'" + + ", messageId='" + + messageId + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMembers.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMembers.java new file mode 100644 index 0000000000..cd326c6fb9 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMembers.java @@ -0,0 +1,69 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class ListChannelMembers extends MSTeamsRequestData { + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.teams(groupId).channels(channelId).members().buildRequest().get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ListChannelMembers that = (ListChannelMembers) o; + return Objects.equals(groupId, that.groupId) && Objects.equals(channelId, that.channelId); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId); + } + + @Override + public String toString() { + return "ListMembersInChannel{" + + "groupId='" + + groupId + + "'" + + ", channelId='" + + channelId + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMessages.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMessages.java new file mode 100644 index 0000000000..79d66ed76c --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannelMessages.java @@ -0,0 +1,106 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.ChatMessageCollectionRequest; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import okhttp3.Request; + +public class ListChannelMessages extends MSTeamsRequestData { + private static final String EXPAND_VALUE = "replies"; + + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + private String isExpand; + + @Pattern(regexp = "^([0-9])*$") + private String top; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + ChatMessageCollectionRequest request = + graphClient.teams(groupId).channels(channelId).messages().buildRequest(); + if (Boolean.parseBoolean(isExpand)) { + request.expand(EXPAND_VALUE); + } + if (top != null) { + request.top(Integer.parseInt(top)); + } + return request.get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + public String getIsExpand() { + return isExpand; + } + + public void setIsExpand(final String isExpand) { + this.isExpand = isExpand; + } + + public String getTop() { + return top; + } + + public void setTop(final String top) { + this.top = top; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final ListChannelMessages that = (ListChannelMessages) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(channelId, that.channelId) + && Objects.equals(isExpand, that.isExpand) + && Objects.equals(top, that.top); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId, isExpand, top); + } + + @Override + public String toString() { + return "GetMessageFromChannel{" + + "groupId='" + + groupId + + "'" + + ", channelId='" + + channelId + + "'" + + ", isExpand='" + + isExpand + + "'" + + ", top='" + + top + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannels.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannels.java new file mode 100644 index 0000000000..affb4027f2 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListChannels.java @@ -0,0 +1,67 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class ListChannels extends MSTeamsRequestData { + + @NotBlank @Secret private String groupId; + @Secret private String filter; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + final var request = graphClient.teams(groupId).allChannels().buildRequest(); + if (filter != null) { + request.filter(filter); + } + return request.get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getFilter() { + return filter; + } + + public void setFilter(final String filter) { + this.filter = filter; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ListChannels that = (ListChannels) o; + return Objects.equals(groupId, that.groupId) && Objects.equals(filter, that.filter); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, filter); + } + + @Override + public String toString() { + return "ListAllChannel{" + "groupId='" + groupId + "'" + ", filter='" + filter + "'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListMessageRepliesInChannel.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListMessageRepliesInChannel.java new file mode 100644 index 0000000000..e598eaba7c --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/ListMessageRepliesInChannel.java @@ -0,0 +1,90 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class ListMessageRepliesInChannel extends MSTeamsRequestData { + + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + @NotBlank @Secret private String messageId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient + .teams(groupId) + .channels(channelId) + .messages(messageId) + .replies() + .buildRequest() + .get(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(final String messageId) { + this.messageId = messageId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ListMessageRepliesInChannel that = (ListMessageRepliesInChannel) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(channelId, that.channelId) + && Objects.equals(messageId, that.messageId); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId, messageId); + } + + @Override + public String toString() { + return "ListMessageRepliesInChannel{" + + "groupId='" + + groupId + + "'" + + ", channelId='" + + channelId + + "'" + + ", messageId='" + + messageId + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/SendMessageToChannel.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/SendMessageToChannel.java new file mode 100644 index 0000000000..3406ecbcdc --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/channel/SendMessageToChannel.java @@ -0,0 +1,96 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.channel; + +import com.microsoft.graph.models.ChatMessage; +import com.microsoft.graph.models.ItemBody; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class SendMessageToChannel extends MSTeamsRequestData { + + @NotBlank @Secret private String groupId; + @NotBlank @Secret private String channelId; + @NotBlank @Secret private String content; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + ChatMessage chatMessage = new ChatMessage(); + ItemBody body = new ItemBody(); + body.content = content; + chatMessage.body = body; + + return graphClient + .teams(groupId) + .channels(channelId) + .messages() + .buildRequest() + .post(chatMessage); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(final String groupId) { + this.groupId = groupId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(final String channelId) { + this.channelId = channelId; + } + + public String getContent() { + return content; + } + + public void setContent(final String content) { + this.content = content; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SendMessageToChannel that = (SendMessageToChannel) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(channelId, that.channelId) + && Objects.equals(content, that.content); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, channelId, content); + } + + @Override + public String toString() { + return "SendMessageToChannel{" + + "groupId='" + + groupId + + "'" + + ", channelId='" + + channelId + + "'" + + ", content='" + + content + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/CreateChat.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/CreateChat.java new file mode 100644 index 0000000000..89736dbb1d --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/CreateChat.java @@ -0,0 +1,94 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.models.AadUserConversationMember; +import com.microsoft.graph.models.Chat; +import com.microsoft.graph.models.ChatType; +import com.microsoft.graph.models.ConversationMember; +import com.microsoft.graph.requests.ConversationMemberCollectionPage; +import com.microsoft.graph.requests.ConversationMemberCollectionResponse; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.Member; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import javax.validation.constraints.NotNull; +import okhttp3.Request; + +public class CreateChat extends MSTeamsRequestData { + + @NotNull private ChatType chatType; + @NotNull @Secret private List members; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + + Chat chat = new Chat(); + chat.chatType = chatType; + LinkedList membersList = new LinkedList<>(); + + for (int i = 0; i < members.size(); i++) { + AadUserConversationMember conversationMembers = new AadUserConversationMember(); + conversationMembers.roles = members.get(i).getRoles(); + conversationMembers + .additionalDataManager() + .put(Member.USER_DATA_BIND, members.get(i).getAsGraphJsonPrimitive()); + conversationMembers + .additionalDataManager() + .put(Member.USER_DATA_TYPE, Member.USER_CONVERSATION_MEMBER); + membersList.add(conversationMembers); + } + + ConversationMemberCollectionResponse conversationMemberCollectionResponse = + new ConversationMemberCollectionResponse(); + conversationMemberCollectionResponse.value = membersList; + chat.members = new ConversationMemberCollectionPage(conversationMemberCollectionResponse, null); + + return graphClient.chats().buildRequest().post(chat); + } + + public ChatType getChatType() { + return chatType; + } + + public void setChatType(final ChatType chatType) { + this.chatType = chatType; + } + + public List getMembers() { + return members; + } + + public void setMembers(final List members) { + this.members = members; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CreateChat that = (CreateChat) o; + return chatType == that.chatType && Objects.equals(members, that.members); + } + + @Override + public int hashCode() { + return Objects.hash(chatType, members); + } + + @Override + public String toString() { + return "CreateChat{" + "chatType=" + chatType + ", members=" + members + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetChat.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetChat.java new file mode 100644 index 0000000000..a2aa3d474e --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetChat.java @@ -0,0 +1,53 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class GetChat extends MSTeamsRequestData { + @NotBlank @Secret protected String chatId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.chats(chatId).buildRequest().get(); + } + + public String getChatId() { + return chatId; + } + + public void setChatId(final String chatId) { + this.chatId = chatId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GetChat getChat = (GetChat) o; + return Objects.equals(chatId, getChat.chatId); + } + + @Override + public int hashCode() { + return Objects.hash(chatId); + } + + @Override + public String toString() { + return "GetChat{" + "chatId='" + chatId + "'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetMessageInChat.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetMessageInChat.java new file mode 100644 index 0000000000..af111ff14c --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/GetMessageInChat.java @@ -0,0 +1,69 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class GetMessageInChat extends MSTeamsRequestData { + @NotBlank @Secret private String chatId; + @NotBlank @Secret private String messageId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.chats(chatId).messages(messageId).buildRequest().get(); + } + + public String getChatId() { + return chatId; + } + + public void setChatId(final String chatId) { + this.chatId = chatId; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(final String messageId) { + this.messageId = messageId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GetMessageInChat that = (GetMessageInChat) o; + return Objects.equals(chatId, that.chatId) && Objects.equals(messageId, that.messageId); + } + + @Override + public int hashCode() { + return Objects.hash(chatId, messageId); + } + + @Override + public String toString() { + return "GetMessageInChat{" + + "chatId='" + + chatId + + "'" + + ", messageId='" + + messageId + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListChatMembers.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListChatMembers.java new file mode 100644 index 0000000000..af6b94f55d --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListChatMembers.java @@ -0,0 +1,54 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class ListChatMembers extends MSTeamsRequestData { + + @NotBlank @Secret private String chatId; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + return graphClient.chats(chatId).members().buildRequest().get(); + } + + public String getChatId() { + return chatId; + } + + public void setChatId(final String chatId) { + this.chatId = chatId; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ListChatMembers that = (ListChatMembers) o; + return Objects.equals(chatId, that.chatId); + } + + @Override + public int hashCode() { + return Objects.hash(chatId); + } + + @Override + public String toString() { + return "ListChatMembers{" + "chatId='" + chatId + "'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListMessagesInChat.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListMessagesInChat.java new file mode 100644 index 0000000000..8c7ec99019 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/ListMessagesInChat.java @@ -0,0 +1,116 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.requests.ChatMessageCollectionPage; +import com.microsoft.graph.requests.ChatMessageCollectionRequest; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.OrderBy; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import okhttp3.Request; + +public class ListMessagesInChat extends MSTeamsRequestData { + + @NotBlank @Secret private String chatId; + @NotBlank @Secret private String filter; + @NotNull private OrderBy orderBy; + + @Pattern(regexp = "^([1-9])|([1-4][0-9])|(50)$") + @Secret + private String top; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + ChatMessageCollectionRequest request = graphClient.chats(chatId).messages().buildRequest(); + if (filter != null) { + request.filter(filter); + } + if (orderBy != null) { + request.orderBy(orderBy.getValue()); + } + if (top != null) { + request.top(Integer.parseInt(top)); + } + ChatMessageCollectionPage chatMessageCollectionPage = request.get(); + System.out.println(chatMessageCollectionPage); + return chatMessageCollectionPage; + } + + public String getChatId() { + return chatId; + } + + public void setChatId(final String chatId) { + this.chatId = chatId; + } + + public String getFilter() { + return filter; + } + + public void setFilter(final String filter) { + this.filter = filter; + } + + public OrderBy getOrderBy() { + return orderBy; + } + + public void setOrderBy(final OrderBy orderBy) { + this.orderBy = orderBy; + } + + public String getTop() { + return top; + } + + public void setTop(final String top) { + this.top = top; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ListMessagesInChat that = (ListMessagesInChat) o; + return Objects.equals(chatId, that.chatId) + && Objects.equals(filter, that.filter) + && orderBy == that.orderBy + && Objects.equals(top, that.top); + } + + @Override + public int hashCode() { + return Objects.hash(chatId, filter, orderBy, top); + } + + @Override + public String toString() { + return "ListMessagesInChat{" + + "chatId='" + + chatId + + "'" + + ", filter='" + + filter + + "'" + + ", orderBy=" + + orderBy + + ", top='" + + top + + "'" + + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/SendMessageInChat.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/SendMessageInChat.java new file mode 100644 index 0000000000..c0dc13606c --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/model/request/chat/SendMessageInChat.java @@ -0,0 +1,69 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.model.request.chat; + +import com.microsoft.graph.models.ChatMessage; +import com.microsoft.graph.models.ItemBody; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.api.annotation.Secret; +import io.camunda.connector.model.request.MSTeamsRequestData; +import java.util.Objects; +import javax.validation.constraints.NotBlank; +import okhttp3.Request; + +public class SendMessageInChat extends MSTeamsRequestData { + @NotBlank @Secret private String chatId; + + @NotBlank @Secret private String content; + + @Override + public Object invoke(final GraphServiceClient graphClient) { + ChatMessage chatMessage = new ChatMessage(); + ItemBody body = new ItemBody(); + body.content = content; + chatMessage.body = body; + return graphClient.chats(chatId).messages().buildRequest().post(chatMessage); + } + + public String getChatId() { + return chatId; + } + + public void setChatId(final String chatId) { + this.chatId = chatId; + } + + public String getContent() { + return content; + } + + public void setContent(final String content) { + this.content = content; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SendMessageInChat that = (SendMessageInChat) o; + return Objects.equals(chatId, that.chatId) && Objects.equals(content, that.content); + } + + @Override + public int hashCode() { + return Objects.hash(chatId, content); + } + + @Override + public String toString() { + return "SendMessageInChat{" + "chatId='" + chatId + "'" + ", content='" + content + "'" + "}"; + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GraphServiceClientSupplier.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GraphServiceClientSupplier.java new file mode 100644 index 0000000000..4d8f896ca2 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GraphServiceClientSupplier.java @@ -0,0 +1,58 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.suppliers; + +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.microsoft.graph.authentication.IAuthenticationProvider; +import com.microsoft.graph.authentication.TokenCredentialAuthProvider; +import com.microsoft.graph.requests.GraphServiceClient; +import io.camunda.connector.model.authentication.ClientSecretAuthentication; +import java.net.URL; +import java.util.concurrent.CompletableFuture; +import okhttp3.Request; +import org.jetbrains.annotations.NotNull; + +public class GraphServiceClientSupplier { + + public GraphServiceClient buildAndGetGraphServiceClient( + final ClientSecretAuthentication authentication) { + + ClientSecretCredential build = + new ClientSecretCredentialBuilder() + .tenantId(authentication.getTenantId()) + .clientId(authentication.getClientId()) + .clientSecret(authentication.getClientSecret()) + .build(); + + TokenCredentialAuthProvider tokenCredentialAuthProvider = + new TokenCredentialAuthProvider(build); + return GraphServiceClient.builder() + .authenticationProvider(tokenCredentialAuthProvider) + .buildClient(); + } + + public GraphServiceClient buildAndGetGraphServiceClient(final String bearerToken) { + return GraphServiceClient.builder() + .authenticationProvider(new DelegateAuthenticationProvider(bearerToken)) + .buildClient(); + } + + public static class DelegateAuthenticationProvider implements IAuthenticationProvider { + private String token; + + public DelegateAuthenticationProvider(String token) { + this.token = token; + } + + @NotNull + @Override + public CompletableFuture getAuthorizationTokenAsync(@NotNull URL url) { + return CompletableFuture.completedFuture(token); + } + } +} diff --git a/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GsonSupplier.java b/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GsonSupplier.java new file mode 100644 index 0000000000..77f2e10768 --- /dev/null +++ b/connectors/microsoft-teams/src/main/java/io/camunda/connector/suppliers/GsonSupplier.java @@ -0,0 +1,64 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.suppliers; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; +import io.camunda.connector.model.authentication.BearerAuthentication; +import io.camunda.connector.model.authentication.ClientSecretAuthentication; +import io.camunda.connector.model.authentication.MSTeamsAuthentication; +import io.camunda.connector.model.request.MSTeamsRequestData; +import io.camunda.connector.model.request.channel.CreateChannel; +import io.camunda.connector.model.request.channel.GetChannel; +import io.camunda.connector.model.request.channel.GetChannelMessage; +import io.camunda.connector.model.request.channel.ListChannelMembers; +import io.camunda.connector.model.request.channel.ListChannelMessages; +import io.camunda.connector.model.request.channel.ListChannels; +import io.camunda.connector.model.request.channel.ListMessageRepliesInChannel; +import io.camunda.connector.model.request.channel.SendMessageToChannel; +import io.camunda.connector.model.request.chat.CreateChat; +import io.camunda.connector.model.request.chat.GetChat; +import io.camunda.connector.model.request.chat.GetMessageInChat; +import io.camunda.connector.model.request.chat.ListChatMembers; +import io.camunda.connector.model.request.chat.ListMessagesInChat; +import io.camunda.connector.model.request.chat.SendMessageInChat; + +public final class GsonSupplier { + + private static final Gson GSON = + new GsonBuilder() + .registerTypeAdapterFactory( + RuntimeTypeAdapterFactory.of(MSTeamsAuthentication.class, "type") + .registerSubtype(BearerAuthentication.class, "token") + .registerSubtype(ClientSecretAuthentication.class, "clientSecret")) + .registerTypeAdapterFactory( + RuntimeTypeAdapterFactory.of(MSTeamsRequestData.class, "method") + // channel + .registerSubtype(CreateChannel.class, "createChannel") + .registerSubtype(GetChannel.class, "getChannel") + .registerSubtype(ListChannels.class, "listAllChannels") + .registerSubtype(GetChannelMessage.class, "getMessageFromChannel") + .registerSubtype(SendMessageToChannel.class, "sendMessageToChannel") + .registerSubtype(ListChannelMessages.class, "listChannelMessages") + .registerSubtype(ListMessageRepliesInChannel.class, "listMessageRepliesInChannel") + .registerSubtype(ListChannelMembers.class, "listMembersInChannel") + // chat + .registerSubtype(CreateChat.class, "createChat") + .registerSubtype(GetChat.class, "getChat") + .registerSubtype(GetMessageInChat.class, "getMessageFromChat") + .registerSubtype(ListChatMembers.class, "listMembersOfChat") + .registerSubtype(ListMessagesInChat.class, "listMessagesInChat") + .registerSubtype(SendMessageInChat.class, "sendMessageToChat")) + .create(); + + private GsonSupplier() {} + + public static Gson getGson() { + return GSON; + } +} diff --git a/connectors/microsoft-teams/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction b/connectors/microsoft-teams/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction index 60900aa7ce..7e597cbc03 100644 --- a/connectors/microsoft-teams/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction +++ b/connectors/microsoft-teams/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction @@ -1 +1 @@ -io.camunda.connector.MyConnectorFunction \ No newline at end of file +io.camunda.connector.MSTeamsFunction \ No newline at end of file diff --git a/connectors/microsoft-teams/src/test/java/io/camunda/connector/BaseTest.java b/connectors/microsoft-teams/src/test/java/io/camunda/connector/BaseTest.java new file mode 100644 index 0000000000..6bbc74133d --- /dev/null +++ b/connectors/microsoft-teams/src/test/java/io/camunda/connector/BaseTest.java @@ -0,0 +1,96 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.nio.file.Files.readString; + +import com.google.gson.Gson; +import io.camunda.connector.suppliers.GsonSupplier; +import io.camunda.connector.test.outbound.OutboundConnectorContextBuilder; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.stream.Stream; +import org.junit.jupiter.params.provider.Arguments; + +public abstract class BaseTest { + + protected static final Gson gson = GsonSupplier.getGson(); + + interface ActualValue { + + interface Authentication { + String CLIENT_ID = "abc01234-0c7f-012c-9876-testClientId"; + String TENANT_ID = "5357c0a8-4728-418b-8c41-testTenantId"; + String CLIENT_SECRET = "Wao8Q~yzXYfgdM_testClientSecret_RZyqPaET"; + } + + interface ChatData { + String CHAT_ID = "19:1c5b01696d2e4a179c292bc9cf04e63b@thread.v2"; + String CONTENT_PART_1 = "microsoft teams"; + String CONTENT_PART_2 = "camunda connector"; + String CONTENT = "Hi " + CONTENT_PART_1 + " from " + CONTENT_PART_2 + "!!!"; + } + + interface ChannelData { + String CHANNEL_ID = "abc01234-0c7f-012c-9876-testClientId"; + String GROUP_ID = "19:1c5b01696d2e4a179c292bc9cf04e63b@thread.v2"; + String NAME = "ChannelTest"; + String DESCRIPTION = "Test channel description"; + String CHANNEL_TYPE = "private"; + } + } + + interface Secrets { + + interface Authentication { + String CLIENT_ID = "CLIENT_ID_KEY"; + String TENANT_ID = "TENANT_ID_KEY"; + String CLIENT_SECRET = "CLIENT_SECRET_ID_KEY"; + } + + interface ChatData { + String CHAT_ID = "CHAT_ID_KEY"; + String CONTENT_PART_1 = "MICROSOFT_TEAMS_KEY"; + String CONTENT_PART_2 = "CAMUNDA_CONNECTOR_KEY"; + } + + interface ChannelData { + String CHANNEL_ID = "CHANNEL_ID_KEY"; + String TEAM_ID = "TEAM_ID"; + String NAME = "NAME"; + String DESCRIPTION = "DESCRIPTION"; + String CHANNEL_TYPE = "CHANNEL_TYPE"; + } + } + + protected static OutboundConnectorContextBuilder getContextBuilderWithSecrets() { + return OutboundConnectorContextBuilder.create() + .secret(Secrets.Authentication.CLIENT_ID, ActualValue.Authentication.CLIENT_ID) + .secret(Secrets.Authentication.TENANT_ID, ActualValue.Authentication.TENANT_ID) + .secret(Secrets.Authentication.CLIENT_SECRET, ActualValue.Authentication.CLIENT_SECRET) + .secret(Secrets.ChatData.CHAT_ID, ActualValue.ChatData.CHAT_ID) + .secret(Secrets.ChannelData.CHANNEL_ID, ActualValue.ChannelData.CHANNEL_ID) + .secret(Secrets.ChannelData.TEAM_ID, ActualValue.ChannelData.GROUP_ID) + .secret(Secrets.ChatData.CONTENT_PART_1, ActualValue.ChatData.CONTENT_PART_1) + .secret(Secrets.ChatData.CONTENT_PART_2, ActualValue.ChatData.CONTENT_PART_2); + } + + protected static Stream executeSendMessageToChat() throws IOException { + return loadTestCasesFromResourceFile(""); + } + + @SuppressWarnings("unchecked") + protected static Stream loadTestCasesFromResourceFile(final String fileWithTestCasesUri) + throws IOException { + final String cases = readString(new File(fileWithTestCasesUri).toPath(), UTF_8); + final Gson testingGson = new Gson(); + var array = testingGson.fromJson(cases, ArrayList.class); + return array.stream().map(testingGson::toJson).map(Arguments::of); + } +} diff --git a/connectors/microsoft-teams/src/test/java/io/camunda/connector/TestCasesPath.java b/connectors/microsoft-teams/src/test/java/io/camunda/connector/TestCasesPath.java new file mode 100644 index 0000000000..87279a1c4a --- /dev/null +++ b/connectors/microsoft-teams/src/test/java/io/camunda/connector/TestCasesPath.java @@ -0,0 +1,11 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector; + +interface TestCasesPath { + String PATH = "src/test/resources/requests/"; +}