diff --git a/.classpath b/.classpath index 6b9e6e56..e55e2f0b 100755 --- a/.classpath +++ b/.classpath @@ -1,8 +1,9 @@ - - - + + + + diff --git a/.dockerignore b/.dockerignore index 9bdae771..e3f6dc5f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ ./social-bot-manager/build -./social-bot-manager/export \ No newline at end of file +./social-bot-manager/export +lib +service \ No newline at end of file diff --git a/.github/workflows/docker-CI.yml b/.github/workflows/docker-CI.yml index a9f8cbc5..7622367e 100644 --- a/.github/workflows/docker-CI.yml +++ b/.github/workflows/docker-CI.yml @@ -3,14 +3,44 @@ name: Docker Build and Push on: push: - branches: [ master, develop] + branches: [ master, develop, ma-lakhoune] jobs: + test: + runs-on: ubuntu-latest + env: + DB_DATABASE: LAS2PEERMON + DB_USER: root + DB_PASSWORD: root + WEBCONNECTOR_URL: http://localhost:8080 + steps: + - name: Set up MySQL + run: | + sudo /etc/init.d/mysql start + mysql -e 'CREATE DATABASE ${{ env.DB_DATABASE }};' -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'adopt' + - run: mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} ${{ env.DB_DATABASE }} < ./SBF.sql + # copy etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample to etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: cp etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databasePassword =|databasePassword = ${{ env.DB_PASSWORD }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databaseUser =|databaseUser = ${{ env.DB_USER }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databaseName =|databaseName = ${{ env.DB_DATABASE }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|webconnectorUrl =|webconnectorUrl = ${{ env.WEBCONNECTOR_URL }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - name: Grant Gradle permissions + run: chmod +x gradlew + - name: Test with Gradle + run: ./gradlew clean test --stacktrace --info build: runs-on: ubuntu-latest + needs: test steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Extract branch name shell: bash run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml new file mode 100644 index 00000000..e12e5541 --- /dev/null +++ b/.github/workflows/docker-pr.yml @@ -0,0 +1,35 @@ +name: Run tests on pull requests + +on: + pull_request: + branches: [ master, develop] + +jobs: + test: + runs-on: ubuntu-latest + env: + DB_DATABASE: LAS2PEERMON + DB_USER: root + DB_PASSWORD: root + WEBCONNECTOR_URL: http://localhost:8080 + steps: + - name: Set up MySQL + run: | + sudo /etc/init.d/mysql start + mysql -e 'CREATE DATABASE ${{ env.DB_DATABASE }};' -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'adopt' + - run: mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} ${{ env.DB_DATABASE }} < ./SBF.sql + - run: cp etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databasePassword =|databasePassword = ${{ env.DB_PASSWORD }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databaseUser =|databaseUser = ${{ env.DB_USER }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|databaseName =|databaseName = ${{ env.DB_DATABASE }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - run: sed -i "s|webconnectorUrl =|webconnectorUrl = ${{ env.WEBCONNECTOR_URL }}|g" etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties + - name: Grant Gradle permissions + run: chmod +x gradlew + - name: Test with Gradle + run: ./gradlew clean test --stacktrace --info \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6d01144c..48977594 100755 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ bin/start_network.bat bin/start_network.sh .project mysql +etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties .env diff --git a/Dockerfile b/Dockerfile index c93f2b96..c9997b01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ RUN dos2unix /app/gradle.properties RUN dos2unix /app/docker-entrypoint.sh RUN dos2unix /app/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample -RUN dos2unix /app/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties +RUN mv /app/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample /app/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties EXPOSE $LAS2PEER_PORT ENTRYPOINT ["/app/docker-entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 6dce53d8..6f7edfed 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +

@@ -101,7 +101,7 @@ See [database](#Database) for a description of the settings. | DATABASE_PASSWORD | *mandatory* || | DATABASE_HOST | mysql | | | DATABASE_PORT | 3306 | | -| ADDRESS | / |Webconnector address. Needed for auto-restart functionality | +| WEBCONNECTOR_URL | / |Webconnector address. Needed for auto-restart functionality | | RESTARTERBOTNAME | / | Name of restarterBot agent. Needed for auto-restart functionality | | RESTARTERBOTPW | / | Password for restarterBot agent. Needed for auto-restart functionality | diff --git a/SBF.sql b/SBF.sql index 6233de38..386af8f1 100644 --- a/SBF.sql +++ b/SBF.sql @@ -26,7 +26,7 @@ SET FOREIGN_KEY_CHECKS = 0; -- Table structure for attributes -- ---------------------------- CREATE TABLE IF NOT EXISTS `attributes` ( - `id` varchar(255) NOT NULL AUTO_INCREMENT, +`id` INT NOT NULL AUTO_INCREMENT, `bot` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `channel` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `user` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, diff --git a/docker-compose.yml b/docker-compose.yml index 57e2741b..3cc489bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,19 @@ version: '3' services: + mobsos-data-processing: + image: ${MOBSOS_DATA_PROCESSING_IMAGE:-registry.tech4comp.dbis.rwth-aachen.de/rwthacis/mobsos-data-processing:master} + environment: + MYSQL_HOST: db + MYSQL_PORT: ${DATABASE_PORT:-3306} + MYSQL_USER: ${DATABASE_USER:-root} + MYSQL_PASSWORD: ${DATABASE_PASSWORD:-root} + LAS2PEER_PORT: 9013 + BOOTSTRAP: social-bot-manager:9011 + ports: + - "9013:9013" + depends_on: + - social-bot-manager social-bot-manager: build: . environment: @@ -9,6 +22,14 @@ services: DATABASE_PORT: ${DATABASE_PORT:-3306} DATABASE_USER: ${DATABASE_USER:-root} DATABASE_PASSWORD: ${DATABASE_PASSWORD:-root} + WEBCONNECTOR_URL: ${WEBCONNECTOR_URL:-http://127.0.0.1:8080} + MONGO_HOST: ${MONGO_HOST:-mongo:8080} + MONGO_DB: ${MONGO_DB:-sbf} + MONGO_USER: ${MONGO_USER:-admin} + MONGO_PASSWORD: ${MONGO_PASSWORD:-password} + MONGO_AUTH: ${MONGO_AUTH:-auth} + LRS_URL: ${LRL_URL:-127.0.0.1:8080} + LRS_AUTH_TOKEN: ${LRL_AUTH_TOKEN:-token} ports: - "8090:8080" - "9011:9011" @@ -25,4 +46,18 @@ services: MYSQL_INITDB_SQL: /docker-entrypoint-initdb.d/init.sql volumes: - ./SBF.sql:/docker-entrypoint-initdb.d/init.sql - \ No newline at end of file + ports: + - "8085:3306" + rasa: + image: ${RASA_IMAGE:-rasa/rasa:3.4.2-full} + command: run --enable-api -m models --cors "*" --debug + ports: + - "5005:5005" + mongo: + image: mongo + restart: always + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER:-admin} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD:-password} + ports: + - 8086:27017 \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 214d1b1f..500021be 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -30,7 +30,7 @@ set_in_service_config databaseHost ${DATABASE_HOST} set_in_service_config databasePort ${DATABASE_PORT} set_in_service_config databaseUser ${DATABASE_USER} set_in_service_config databasePassword ${DATABASE_PASSWORD} -set_in_service_config address ${ADDRESS} +set_in_service_config webconnectorUrl ${WEBCONNECTOR_URL} set_in_service_config restarterBotName ${RESTARTERBOTNAME} set_in_service_config restarterBotPW ${RESTARTERBOTPW} set_in_service_config mongoHost ${MONGO_HOST} @@ -39,9 +39,10 @@ set_in_service_config mongoUser ${MONGO_USER} set_in_service_config mongoPassword ${MONGO_PASSWORD} set_in_service_config mongoAuth ${MONGO_AUTH} set_in_service_config lrsURL ${LRS_URL} +set_in_service_config lrsURLStatic ${LRS_URL} set_in_service_config lrsAuthToken ${LRS_AUTH_TOKEN} -check_if_exists "$ADDRESS" "ADDRESS" +check_if_exists "$WEBCONNECTOR_URL" "WEBCONNECTOR_URL" if [ "$ENV_VARIABLE_NOT_SET" = true ] ; then echo "Missing environment variables, exiting..." diff --git a/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties b/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties deleted file mode 100644 index ce801003..00000000 --- a/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties +++ /dev/null @@ -1,15 +0,0 @@ -databaseUser = root -databasePassword = root -databaseName = LAS2PEERMON -databaseHost = 127.0.0.1 -databasePort = 3306 -mongoUser = admin -mongoPassword = password -mongoDB = sbf -mongoHost = 127.0.0.1:27017 -mongoAuth = admin -address = http://127.0.0.1:8080 -restarterBotName = -restarterBotPW = -lrsAuthToken = -lrsURL = \ No newline at end of file diff --git a/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample b/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample index f1b0a384..9103f754 100644 --- a/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample +++ b/etc/i5.las2peer.services.socialBotManagerService.SocialBotManagerService.properties.sample @@ -1,13 +1,13 @@ databaseUser = root databasePassword = root -databaseName = LAS2PEERMON -databaseHost = host.docker.internal +databaseName = SBF +databaseHost = localhost:3306 databasePort = 3306 mongoUser = admin mongoPassword = password mongoDB = sbf mongoHost = 127.0.0.1:27017 mongoAuth = admin -address = http://127.0.0.1:8080 +webconnectorUrl = http://127.0.0.1:8080 restarterBotName = restarterBotPW = \ No newline at end of file diff --git a/etc/ivy/ivy.xml b/etc/ivy/ivy.xml deleted file mode 100755 index 84114ae8..00000000 --- a/etc/ivy/ivy.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/etc/ivy/ivysettings.xml b/etc/ivy/ivysettings.xml deleted file mode 100755 index 5e9b1a63..00000000 --- a/etc/ivy/ivysettings.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/etc/nodeInfo.xml b/etc/nodeInfo.xml index d0d5c99f..e8c7ab81 100755 --- a/etc/nodeInfo.xml +++ b/etc/nodeInfo.xml @@ -2,5 +2,5 @@ Admin admin@mail.com Advanced Community Information Systems (ACIS) Group, RWTH Aachen University - This node hosts a sample service. +This node hosts the social bot manager service diff --git a/gradle.properties b/gradle.properties index 53057e11..2138b899 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ -core.version=1.2.4 +core.version=1.3.1 service.name=i5.las2peer.services.socialBotManagerService service.class=SocialBotManagerService -service.version=1.6.0 +service.version=2.1.0 java.version=17 las2peer_user1.name=alice diff --git a/social-bot-manager/build.gradle b/social-bot-manager/build.gradle index e3ec4a93..b42e6dbc 100644 --- a/social-bot-manager/build.gradle +++ b/social-bot-manager/build.gradle @@ -150,7 +150,7 @@ task startscripts { # this script is autogenerated by 'gradle startscripts' # it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project # pls execute it from the root folder of your deployment, e. g. ./bin/start_network.sh -java -cp "lib/*" --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService\\(\\'${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}\\'\\) startWebConnector interactive +java -cp "lib/*" --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service -o uploadStartupDirectory startService\\(\\'${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}\\'\\) startWebConnector interactive """ new File("$rootDir/bin", "start_network.bat").text = """:: this script is autogenerated by 'gradle startscripts' :: it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java index 5825577a..8a441268 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java @@ -2,8 +2,6 @@ import java.math.BigInteger; import java.io.*; -import java.lang.reflect.Array; -import java.lang.reflect.Field; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -45,8 +43,6 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; -import com.slack.api.Slack; - import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataMultiPart; @@ -55,12 +51,10 @@ import org.apache.commons.io.FileUtils; import org.apache.tika.Tika; -import com.fasterxml.jackson.core.JsonProcessingException; import com.google.gson.Gson; import i5.las2peer.api.Context; import i5.las2peer.api.ManualDeployment; -import i5.las2peer.api.ServiceException; import i5.las2peer.api.execution.InternalServiceException; import i5.las2peer.api.execution.ServiceAccessDeniedException; import i5.las2peer.api.execution.ServiceInvocationFailedException; @@ -73,11 +67,7 @@ import i5.las2peer.api.persistency.EnvelopeAccessDeniedException; import i5.las2peer.api.persistency.EnvelopeNotFoundException; import i5.las2peer.api.persistency.EnvelopeOperationFailedException; -import i5.las2peer.api.security.Agent; -import i5.las2peer.api.security.AgentAccessDeniedException; -import i5.las2peer.api.security.AgentAlreadyExistsException; import i5.las2peer.api.security.AgentException; -import i5.las2peer.api.security.AgentLockedException; import i5.las2peer.api.security.AgentNotFoundException; import i5.las2peer.api.security.AgentOperationFailedException; import i5.las2peer.api.security.UserAgent; @@ -110,7 +100,7 @@ import i5.las2peer.services.socialBotManagerService.model.Trigger; import i5.las2peer.services.socialBotManagerService.model.TriggerFunction; import i5.las2peer.services.socialBotManagerService.model.BotRoutine; -import i5.las2peer.services.socialBotManagerService.model.Messenger; +import i5.las2peer.services.socialBotManagerService.model.ConversationMessage; import i5.las2peer.services.socialBotManagerService.nlu.Entity; import i5.las2peer.services.socialBotManagerService.nlu.TrainingHelper; import i5.las2peer.services.socialBotManagerService.parser.BotParser; @@ -133,8 +123,6 @@ import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import com.mongodb.MongoException; -import com.mongodb.ServerApi; -import com.mongodb.ServerApiVersion; import com.mongodb.client.MongoDatabase; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSBuckets; @@ -173,8 +161,8 @@ public class SocialBotManagerService extends RESTService { private String databaseUser; private String databasePassword; private SQLDatabase database; // The database instance to write to. - private String address; // address of running webconnector - private static String addressStatic; // address of running webconnector + private String webconnectorUrl = "http://localhost:8080"; // address of running webconnector + private static String webconnectorUrlStatic; private String restarterBotName; // name of restarterBot private static String restarterBotNameStatic; private String restarterBotPW; // PW of restarterBot @@ -222,15 +210,12 @@ public void setL2pcontext(Context l2pcontext) { this.l2pcontext = l2pcontext; } - public SocialBotManagerService() throws Exception{ + public SocialBotManagerService() throws Exception { super(); setFieldValues(); // This sets the values of the configuration file restarterBotNameStatic = restarterBotName; restarterBotPWStatic = restarterBotPW; - if(address == null || address.equals("")){ - throw new Exception("ADDRESS VARIABLE NEEDS TO BE SET!!!!!"); - } - addressStatic = address; + webconnectorUrlStatic = webconnectorUrl; TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { @@ -272,20 +257,20 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) { System.out.println("Failed to Connect: " + e.getMessage()); } - // mongo db connection for exchanging files - mongoUri = "mongodb://"+mongoUser+":"+mongoPassword+"@"+mongoHost+"/?authSource="+mongoAuth; - // Construct a ServerApi instance using the ServerApi.builder() method - CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); + // mongo db connection for exchanging files + mongoUri = "mongodb://" + mongoUser + ":" + mongoPassword + "@" + mongoHost + "/?authSource=" + mongoAuth; + // Construct a ServerApi instance using the ServerApi.builder() method + CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry); MongoClientSettings settings = MongoClientSettings.builder() .uuidRepresentation(UuidRepresentation.STANDARD) .applyConnectionString(new ConnectionString(mongoUri)) .codecRegistry(codecRegistry) .build(); - + // Create a new client and connect to the server MongoClient mongoClient = MongoClients.create(settings); - // Create a new client and connect to the server + // Create a new client and connect to the server try { MongoDatabase database = mongoClient.getDatabase(mongoDB); // Send a ping to confirm a successful connection @@ -294,7 +279,9 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) { System.out.println("Pinged your deployment. You successfully connected to MongoDB!"); } catch (MongoException me) { System.err.println(me); - } finally{ + } catch (Exception e) { + System.err.println(e); + } finally { mongoClient.close(); } @@ -315,6 +302,38 @@ protected void initResources() { getResourceConfig().register(RESTfulChatResource.class); } + /** + * Returns the custom message descriptions for the service. + */ + @Override + public HashMap getCustomMessageDescriptions() { + HashMap descriptions = new HashMap<>(); + descriptions.put( + "SERVICE_CUSTOM_MESSAGE_1", + "Monitors whenever a bot gets initialized"); + descriptions.put( + "SERVICE_CUSTOM_MESSAGE_2", + "(deprecated) Was used to log the user messages."); + descriptions.put( + "SERVICE_CUSTOM_MESSAGE_3", + "Logs whenever a new bot gets created. " + + "| Key | Description |" + + "|---------------|--------------------------------|" + + "| botName | Represents the bot name. |" + + "| agentId | Represents the agent of the bot|"); + descriptions.put( + "SERVICE_CUSTOM_MESSAGE_42", + "| Key | Description |" + + "|-------------|-------------------------------------------------------------------------------------------------------------|" + + "| task | Represents the task being performed. |" + + "| email | Represents the email address associated with the user. |" + + "| time | Represents the time taken to perform the task, calculated as the difference between the current time and `start` time. |"); + descriptions.put( + "SERVICE_CUSTOM_MESSAGE_80", + "Logs the whole json body of the request."); + return descriptions; + } + @POST @Path("/trainAndLoad") @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8") @@ -407,8 +426,6 @@ public Response restartBots() { if (restarterBot == null) { try { try { - System.out.println( - "Fetching restarter bot"); restarterBot = (BotAgent) Context.getCurrent().fetchAgent( Context.getCurrent().getUserAgentIdentifierByLoginName(restarterBotNameStatic)); // if bot didn't exist before, no need to try to restart the previous bots, as @@ -425,10 +442,10 @@ public Response restartBots() { init(entry.getValue()); } - System.out.println("Restarting bots completed"); + } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException | EnvelopeOperationFailedException e) { - System.out.println("no bot models found in storage"); + } } catch (Exception e) { @@ -445,7 +462,7 @@ public Response restartBots() { } catch (AgentException | CryptoException e2) { // TODO Errorhandling e2.printStackTrace(); - } catch (Exception e3){ + } catch (Exception e3) { e3.printStackTrace(); } } @@ -490,8 +507,8 @@ public Response getBots() { @ApiOperation(value = "Retrieve bot by name", notes = "Returns bot information by the given name.") public Response getBotsForVLE(@PathParam("botName") String name) { Bot b = getConfig().getBots().get(name); - if (b==null){ - return Response.status(Status.NOT_FOUND).entity("Bot "+name+" not found.").build(); + if (b == null) { + return Response.status(Status.NOT_FOUND).entity("Bot " + name + " not found.").build(); } JSONObject bot = new JSONObject(); JSONObject ac = new JSONObject(); @@ -516,93 +533,101 @@ public Response getBotsForVLE(@PathParam("botName") String name) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Init successful.") }) @ApiOperation(value = "Init Bot", notes = "Reads the configuration file.") public Response init(BotModel botModel) { - sbfservice.setL2pcontext(Context.getCurrent()); - BotParser bp = BotParser.getInstance(); - - String returnString = ""; - LinkedHashMap nodes = botModel.getNodes(); - LinkedHashMap edges = botModel.getEdges(); - Set list = SocialBotManagerService.getBotAgents().keySet(); - ArrayList oldArray = new ArrayList(); - // do agentid here maybe instead of loginname, as some people use the same login - // name - for (String entry : list) { - oldArray.add(entry); - } - String botToken = ""; - for (Entry entry : nodes.entrySet()) { - if (entry.getValue().getType().equals("Messenger")) { - for (Entry subEntry : entry.getValue().getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - if (subVal.getName().equals("Authentication Token")) { - botToken = subVal.getValue(); + try { + sbfservice.setL2pcontext(Context.getCurrent()); + BotParser bp = BotParser.getInstance(); + + String returnString = ""; + LinkedHashMap nodes = botModel.getNodes(); + LinkedHashMap edges = botModel.getEdges(); + Set list = SocialBotManagerService.getBotAgents().keySet(); + ArrayList oldArray = new ArrayList(); + // do agentid here maybe instead of loginname, as some people use the same login + // name + for (String entry : list) { + oldArray.add(entry); + } + String botToken = ""; + for (Entry entry : nodes.entrySet()) { + if (entry.getValue().getType().equals("Messenger")) { + for (Entry subEntry : entry.getValue().getAttributes() + .entrySet()) { + BotModelNodeAttribute subElem = subEntry.getValue(); + BotModelValue subVal = subElem.getValue(); + if (subVal.getName().equals("Authentication Token")) { + botToken = subVal.getValue(); + } } } } - } - if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") - && !restarterBotPWStatic.equals("")) { - try { - restarterBot = (BotAgent) Context.getCurrent() - .fetchAgent(Context.getCurrent().getUserAgentIdentifierByLoginName(restarterBotNameStatic)); - restarterBot.unlock(restarterBotPWStatic); - } catch (Exception e) { - e.printStackTrace(); + if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") + && !restarterBotPWStatic.equals("")) { + try { + restarterBot = (BotAgent) Context.getCurrent() + .fetchAgent( + Context.getCurrent().getUserAgentIdentifierByLoginName(restarterBotNameStatic)); + restarterBot.unlock(restarterBotPWStatic); + } catch (Exception e) { + e.printStackTrace(); + } } - } - Envelope env = null; - HashMap old = null; - try { - bp.parseNodesAndEdges(SocialBotManagerService.getConfig(), SocialBotManagerService.getBotAgents(), - nodes, edges, sbfservice.database, addressStatic); - } catch (ParseBotException | IllegalArgumentException | IOException | DeploymentException - | AuthTokenException e) { - e.printStackTrace(); - if (e.toString().toLowerCase().contains("login name longer")) { - return Response.status(Status.BAD_REQUEST).entity("Bot Name needs to have at least 4 characters!") - .build(); - } - return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } - // initialized = true; - JSONObject logData = new JSONObject(); - logData.put("status", "initialized"); - env = null; - old = null; - if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") - && !restarterBotPWStatic.equals("")) { + Envelope env = null; + HashMap old = null; try { - // try to add project to project list (with service group agent) - env = Context.get().requestEnvelope(restarterBotNameStatic, restarterBot); - old = (HashMap) env.getContent(); - old.put(botToken, botModel); - env.setContent(old); - Context.get().storeEnvelope(env, restarterBot); - } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException - | EnvelopeOperationFailedException e) { - System.out.println(e); + bp.parseNodesAndEdges(SocialBotManagerService.getConfig(), SocialBotManagerService.getBotAgents(), + nodes, edges, sbfservice.database, webconnectorUrlStatic); + } catch (ParseBotException | IllegalArgumentException | IOException | DeploymentException + | AuthTokenException e) { + e.printStackTrace(); + if (e.toString().toLowerCase().contains("login name longer")) { + return Response.status(Status.BAD_REQUEST) + .entity("Bot Name needs to have at least 4 characters!") + .build(); + } + return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + // initialized = true; + JSONObject logData = new JSONObject(); + logData.put("status", "initialized"); + env = null; + old = null; + if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") + && !restarterBotPWStatic.equals("")) { try { - env = Context.get().createEnvelope(restarterBotNameStatic, restarterBot); - env.setPublic(); - old = new HashMap(); + // try to add project to project list (with service group agent) + env = Context.get().requestEnvelope(restarterBotNameStatic, restarterBot); + old = (HashMap) env.getContent(); old.put(botToken, botModel); - // System.out.println(botToken); env.setContent(old); Context.get().storeEnvelope(env, restarterBot); - } catch (EnvelopeOperationFailedException | EnvelopeAccessDeniedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (Exception e2) { - e2.printStackTrace(); + } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException + | EnvelopeOperationFailedException e) { + System.out.println(e); + try { + env = Context.get().createEnvelope(restarterBotNameStatic, restarterBot); + env.setPublic(); + old = new HashMap(); + old.put(botToken, botModel); + // System.out.println(botToken); + env.setContent(old); + Context.get().storeEnvelope(env, restarterBot); + } catch (EnvelopeOperationFailedException | EnvelopeAccessDeniedException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (Exception e2) { + e2.printStackTrace(); + } } - } + Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_1, logData.toString()); + + return Response.ok().entity(returnString).build(); + } catch (Exception e) { + e.printStackTrace(); + return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); } - Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_1, logData.toString()); - return Response.ok().entity(returnString).build(); } /** @@ -635,7 +660,7 @@ public Response join(String body, @PathParam("botName") String botName) { if (bot == null) { return Response.status(Status.NOT_FOUND).entity("Bot " + botName + " not found").build(); } - + if (j.get("directJoin") == null) { String joinPath = (String) j.get("joinPath"); @@ -643,8 +668,8 @@ public Response join(String body, @PathParam("botName") String botName) { MiniClient client = new MiniClient(); client.setConnectorEndpoint(basePath); - client.setLogin(botAgent.getLoginName(), botPass); - //client.setLogin("alice", "pwalice"); + client.setLogin(botAgent.getLoginName(), botPass); + // client.setLogin("alice", "pwalice"); j.remove("joinPath"); j.remove("basePath"); @@ -661,7 +686,8 @@ public Response join(String body, @PathParam("botName") String botName) { /** * Endpoint that handles incoming webhook calls. - * @param body JSONObject + * + * @param body JSONObject * @param botName Name of the bot. * @return HTTP response */ @@ -678,13 +704,14 @@ public Response webhook(String body, @PathParam("botName") String botName) { // check if bot exists Bot bot = null; for (String botId : getConfig().getBots().keySet()) { - if(getConfig().getBots().get(botId).getName().toLowerCase().equals(botName.toLowerCase())){ + if (getConfig().getBots().get(botId).getName().toLowerCase().equals(botName.toLowerCase())) { bot = getConfig().getBot(botId); break; } } if (bot == null) - return Response.status(HttpURLConnection.HTTP_NOT_FOUND).entity("Bot " + botName + " not found.").build(); + return Response.status(HttpURLConnection.HTTP_NOT_FOUND).entity("Bot " + botName + " not found.") + .build(); try { // parse body @@ -692,12 +719,13 @@ public Response webhook(String body, @PathParam("botName") String botName) { JSONObject parsedBody = (JSONObject) p.parse(body); // all webhook calls need to include the "event" property - if(!parsedBody.containsKey("event")) - return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).entity("Field event is missing.").build(); + if (!parsedBody.containsKey("event")) + return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).entity("Field event is missing.") + .build(); String event = parsedBody.getAsString("event"); // handle webhook depending on the event (currently only chat_message supported) - if(event.equals("chat_message")) { + if (event.equals("chat_message")) { String messenger = parsedBody.getAsString("messenger"); if (!parsedBody.containsKey("messenger")) { for (String m : bot.getMessengers().keySet()) { @@ -757,7 +785,7 @@ public Response trigger(String body, @PathParam("botName") String name) { public Response triggerRoutine(String body, @PathParam("botName") String name) { String returnString = "Routine is running."; SocialBotManagerService sbf = this.sbfservice; - String addr = sbf.address; + String addr = sbf.webconnectorUrl; new Thread(new Runnable() { @Override public void run() { @@ -811,7 +839,7 @@ public Response triggerButton(String body, @PathParam("botName") String name, // json result = result.substring(8); - System.out.println("Handling message..."); + JSONObject bodyInput = (JSONObject) p.parse(result); String channel = ""; @@ -912,8 +940,6 @@ public Response triggerButton(String body, @PathParam("botName") String name, new ArrayList<>()); // this.triggeredFunction.get(message.getChannel()); - System.out.println( - "Got info: " + messageInfo.getMessage().getText() + " " + messageInfo.getTriggeredFunctionId()); Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, body); SocialBotManagerService sbf = this.sbfservice; @@ -937,7 +963,7 @@ public void run() { for (Messenger m : messengers.values()) { // System.out.println("messenger: " + m); HashMap intentsHM = m - .getKnownIntents(); + .getRootChildren(); // System.out.println("intentsHM: " + intentsHM); for (String s : intentsHM.keySet()) { if (s.equals(expectedIntent)) { @@ -946,6 +972,7 @@ public void run() { i5.las2peer.services.socialBotManagerService.model.IncomingMessage chatResponses = incomingMessage; // System.out.println(chatResponses); // System.out.println(chatResponses.getTriggeredFunctionId()); + // get first trigger function for now triggerdFunctionId = chatResponses.getTriggeredFunctionId(); messengerName = m.getName(); } @@ -969,7 +996,7 @@ public void run() { } catch (Exception e) { e.printStackTrace(); } - System.out.println("Intent processing finished."); + } }).start(); return Response.ok().build(); @@ -997,7 +1024,7 @@ public void run() { // Identify bot Bot bot = null; - + for (Bot b : getConfig().getBots().values()) { if (bot.getMessenger(ChatService.SLACK) != null) { ChatMediator mediator = bot.getMessenger(ChatService.SLACK) @@ -1044,14 +1071,15 @@ public Response triggerIntent(String body, @PathParam("botName") String name) { cleanedJson.put("user", encryptThisString(cleanedJson.getAsString("user"))); if (cleanedJson.containsKey("email")) { cleanedJson.put("email", encryptThisString(cleanedJson.getAsString("email"))); - JSONObject xAPI = createXAPIStatement(cleanedJson.getAsString("email"), name, m.getIntent().getKeyword(), m.getMessage().getText()); + JSONObject xAPI = createXAPIStatement(cleanedJson.getAsString("email"), name, + m.getIntent().getKeyword(), m.getMessage().getText()); sendXAPIStatement(xAPI, lrsAuthTokenStatic); } Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, cleanedJson.toString()); } catch (Exception e) { e.printStackTrace(); } - System.out.println("Got info: " + m.getMessage().getText() + " " + m.getTriggeredFunctionId()); + Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, body); // If no action should be triggered, just return if (m.getTriggeredFunctionId() == null) { @@ -1077,7 +1105,7 @@ public void run() { } catch (Exception e) { e.printStackTrace(); } - System.out.println("Intent processing finished."); + } }).start(); return Response.ok().build(); @@ -1102,7 +1130,7 @@ public JSONObject createXAPIStatement(String userMail, String botName, .parse(new String("{'definition':{'interactionType':'other', 'name':{'en-US':'" + intent + "'}, 'description':{'en-US':'" + intent + "'}, 'type':'https://tech4comp.de/xapi/activitytype/bot'},'id':'https://tech4comp.de/bot/" - + botName+ "', 'objectType':'Activity'}")); + + botName + "', 'objectType':'Activity'}")); JSONObject context = (JSONObject) p.parse(new String( "{'extensions':{'https://tech4comp.de/xapi/context/extensions/intent':{'botName':'" + botName + "','text':'" @@ -1113,7 +1141,7 @@ public JSONObject createXAPIStatement(String userMail, String botName, xAPI.put("authority", p.parse( new String( "{'objectType': 'Agent','name': 'New Client', 'mbox': 'mailto:hello@learninglocker.net'}"))); - xAPI.put("context", context); + xAPI.put("context", context); // xAPI.put("timestamp", java.time.LocalDateTime.now()); xAPI.put("actor", actor); xAPI.put("object", object); @@ -1125,8 +1153,12 @@ public void sendXAPIStatement(JSONObject xAPI, String lrsAuthToken) { // Copy pasted from LL service // POST statements try { + if (lrsURLStatic == null || lrsAuthTokenStatic == null) { + return; + } + URL url = new URL(lrsURLStatic + "/data/xAPI/statements"); - System.out.println(url + lrsAuthTokenStatic); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); @@ -1271,7 +1303,8 @@ public void run() { } } - public void checkRoutineTrigger(BotConfiguration botConfig, JSONObject j, BotAgent botAgent, String botFunctionId, JSONObject context) + public void checkRoutineTrigger(BotConfiguration botConfig, JSONObject j, BotAgent botAgent, String botFunctionId, + JSONObject context) throws ServiceNotFoundException, ServiceNotAvailableException, InternalServiceException, ServiceMethodNotFoundException, ServiceInvocationFailedException, ServiceAccessDeniedException, ServiceNotAuthorizedException, ParseBotException, AgentNotFoundException, AgentOperationFailedException { @@ -1302,6 +1335,7 @@ public void performIntentTrigger(BotConfiguration botConfig, BotAgent botAgent, ServiceNotAuthorizedException, ParseBotException, AgentNotFoundException, AgentOperationFailedException { String botId = botAgent.getIdentifier(); Bot bot = botConfig.getBots().get(botId); + if (bot != null) { System.out.println("Bot " + botAgent.getLoginName() + " triggered:"); ServiceFunction botFunction = bot.getBotServiceFunctions().get(messageInfo.getTriggeredFunctionId()); @@ -1309,19 +1343,25 @@ public void performIntentTrigger(BotConfiguration botConfig, BotAgent botAgent, if (botFunction.getActionType().equals(ActionType.SERVICE)) { functionPath = botFunction.getFunctionPath(); } else if (botFunction.getActionType().equals(ActionType.OPENAPI)) { - functionPath = botFunction.getFunctionPath(); + functionPath = botFunction.getFunctionPath(); } JSONObject body = new JSONObject(); HashMap attlist = new HashMap(); JSONObject triggerAttributes = new JSONObject(); for (ServiceFunctionAttribute sfa : botFunction.getAttributes()) { + // if (botFunction.getServiceName().equals("https://api.openai.com/v1")) { + // body.put(sfa.getName(), sfa.getContent()); + // } else { formAttributes(botConfig, sfa, bot, body, functionPath, attlist, triggerAttributes); + // } } // Patch attributes so that if a chat message is sent, it is sent // to the same channel the action was triggered from. // TODO: Handle multiple messengers + String mail = messageInfo.getMessage().getEmail(); - if(mail==null) mail = ""; + if (mail == null) + mail = ""; body.put("email", messageInfo.getMessage().getEmail()); body.put("channel", messageInfo.getMessage().getChannel()); body.put("user", messageInfo.getMessage().getUser()); @@ -1370,6 +1410,7 @@ public void performIntentTrigger(BotConfiguration botConfig, BotAgent botAgent, body.put("entities", entities); body.put("msg", messageInfo.getMessage().getText()); body.put("contextOn", messageInfo.contextActive()); + body.put("conversationId", messageInfo.getConversationId()); botFunction.setMessengerName(messageInfo.getMessengerName()); performTrigger(botConfig, botFunction, botAgent, functionPath, "", body); } @@ -1479,8 +1520,9 @@ public void checkTriggerBot(BotConfiguration botConfig, JSONObject body, BotAgen String functionPath = ""; // add path if the triggered function is a service function - if (triggeredFunction.getActionType().equals(ActionType.SERVICE)) + if (triggeredFunction.getActionType().equals(ActionType.SERVICE) || triggeredFunction.getActionType().equals(ActionType.OPENAPI)){ functionPath = triggeredFunction.getFunctionPath(); + } JSONObject triggeredBody = new JSONObject(); HashMap attlist = new HashMap(); for (ServiceFunction bsf : bot.getBotServiceFunctions().values()) { @@ -1488,10 +1530,27 @@ public void checkTriggerBot(BotConfiguration botConfig, JSONObject body, BotAgen attlist.put(bsfa.getId(), bsfa); } } + String user = body.getAsString("user"); + String channel = body.getAsString("channel"); + String email = body.getAsString("email"); + String convId = body.getAsString("conversationId"); + String intent = body.getAsString("intent"); + String contextOn = body.getAsString("contextOn"); + triggeredBody.put("user", user); + triggeredBody.put("channel", channel); + triggeredBody.put("email", email); + triggeredBody.put("conversationId", convId); + triggeredBody.put("intent", intent); + triggeredBody.put("contextOn", contextOn); + triggeredBody.put("entities", body.get("entities")); + triggeredBody.put("organization", body.get("organization")); + + JSONObject triggerAttributes = (JSONObject) body.get("attributes"); for (ServiceFunctionAttribute triggeredFunctionAttribute : triggeredFunction.getAttributes()) { - formAttributes(botConfig, triggeredFunctionAttribute, bot, triggeredBody, functionPath, attlist, + formAttributes(botConfig, triggeredFunctionAttribute, bot, triggeredBody, functionPath, + attlist, triggerAttributes); } @@ -1506,37 +1565,59 @@ public void checkTriggerBot(BotConfiguration botConfig, JSONObject body, BotAgen } // Aaron : if name of body is empty add as part of an array of contents ? - private void formAttributes(BotConfiguration botConfig, ServiceFunctionAttribute triggeredFunctionAttribute, Bot bot, + private void formAttributes(BotConfiguration botConfig, ServiceFunctionAttribute triggeredFunctionAttribute, + Bot bot, JSONObject triggeredBody, String functionPath, HashMap attlist, JSONObject triggerAttributes) throws ServiceNotFoundException, ServiceNotAvailableException, InternalServiceException, ServiceMethodNotFoundException, ServiceInvocationFailedException, ServiceAccessDeniedException, ServiceNotAuthorizedException, ParseBotException { // Attributes of the triggered function + // System.out.println(triggeredFunctionAttribute.getName()); if (triggeredFunctionAttribute.isSameAsTrigger()) { mapAttributes(triggeredBody, triggeredFunctionAttribute, functionPath, attlist, triggerAttributes); - } else if (triggeredFunctionAttribute.getName() == "body") { + } else if (triggeredFunctionAttribute.getParameterType().equals("body")) { // triggeredFunctionAttribute.getName() + // == "body", doesn't make sense? JSONObject triggerBody = (JSONObject) triggerAttributes.get("body"); - for (ServiceFunctionAttribute subsfa : triggeredFunctionAttribute.getChildAttributes()) { - if (subsfa.isSameAsTrigger()) { - ServiceFunctionAttribute mappedTo = subsfa.getMappedTo(); - if (triggerBody.get(mappedTo.getName()) != null) { - triggeredBody.put(subsfa.getName(), triggerBody.get(mappedTo.getName())); - } else - triggeredBody.put(subsfa.getName(), triggerAttributes.get(mappedTo.getName())); - } else { - if (triggeredFunctionAttribute.getItb() != null) { - mapWithIfThen(triggeredFunctionAttribute.getItb(), triggeredFunctionAttribute, - triggeredBody, attlist, triggerAttributes, functionPath); + // sfa has child attributes + if (!triggeredFunctionAttribute.getChildAttributes().isEmpty()) { + JSONArray jsonArray = new JSONArray(); + + for (ServiceFunctionAttribute subsfa : triggeredFunctionAttribute.getChildAttributes()) { + // Same as trigger is never set because the edge doesn't even exist in the + // frontend + if (subsfa.isSameAsTrigger()) { + ServiceFunctionAttribute mappedTo = subsfa.getMappedTo(); + if (triggerBody.get(mappedTo.getName()) != null) { + triggeredBody.put(subsfa.getName(), triggerBody.get(mappedTo.getName())); + } else + triggeredBody.put(subsfa.getName(), triggerAttributes.get(mappedTo.getName())); } else { - if (subsfa.hasStaticContent()) { - mapWithStaticContent(subsfa, triggeredBody); + if (triggeredFunctionAttribute.getItb() != null) { + mapWithIfThen(triggeredFunctionAttribute.getItb(), triggeredFunctionAttribute, + triggeredBody, attlist, triggerAttributes, functionPath); } else { - // TODO no match! + if (subsfa.hasStaticContent()) { + mapWithStaticContent(subsfa, triggeredBody); + } else { + // sfa's content is empty, treat sfa as a list and subsfa as a list item + if (triggeredFunctionAttribute.getContent().isEmpty()) { + HashMap listItemMap = new HashMap(); + // Put the attributes of the list item into a map + for (ServiceFunctionAttribute listItemAttributes : subsfa.getChildAttributes()) { + listItemMap.put(listItemAttributes.getName(), listItemAttributes.getContent()); + } + JSONObject jsonlistItemMap = new JSONObject(listItemMap); + jsonArray.add(jsonlistItemMap); + } + } } } - } - + if (triggeredFunctionAttribute.getContent().isEmpty()) { + triggeredBody.put(triggeredFunctionAttribute.getName(), jsonArray); + } + } else { // sfa has no child attributes + triggeredBody.put(triggeredFunctionAttribute.getName(), triggeredFunctionAttribute.getContent()); } } else { if (triggeredFunctionAttribute.getItb() != null) { @@ -1554,7 +1635,7 @@ private void formAttributes(BotConfiguration botConfig, ServiceFunctionAttribute if (triggeredFunctionAttribute.getParameterType().equals("form")) { mapWithStaticFormContent(triggeredFunctionAttribute, triggeredBody); } else { - System.out.println("Unknown mapping" + triggeredFunctionAttribute.getContentType() + System.out.println("Unknown mapping " + triggeredFunctionAttribute.getContentType() + triggeredFunctionAttribute.getParameterType()); } } @@ -1627,30 +1708,31 @@ private void mapWithStaticContent(ServiceFunctionAttribute triggeredFunctionAttr } } - private void mapWithStaticFormContent(ServiceFunctionAttribute triggeredFunctionAttribute, JSONObject triggeredBody) { + private void mapWithStaticFormContent(ServiceFunctionAttribute triggeredFunctionAttribute, + JSONObject triggeredBody) { if (triggeredFunctionAttribute.getContent().length() > 0) { if (triggeredBody.containsKey(triggeredFunctionAttribute.getName())) { JSONArray array = new JSONArray(); array.add(triggeredBody.get(triggeredFunctionAttribute.getName())); array.add(triggeredFunctionAttribute.getContent()); - if(triggeredBody.get("form") == null){ + if (triggeredBody.get("form") == null) { JSONObject form = new JSONObject(); form.put(triggeredFunctionAttribute.getName(), array); - triggeredBody.put("form",form); + triggeredBody.put("form", form); } else { JSONObject form = (JSONObject) triggeredBody.get("form"); form.put(triggeredFunctionAttribute.getName(), array); - triggeredBody.put("form",form); + triggeredBody.put("form", form); } - } else { - if(triggeredBody.get("form") == null){ + } else { + if (triggeredBody.get("form") == null) { JSONObject form = new JSONObject(); form.put(triggeredFunctionAttribute.getName(), triggeredFunctionAttribute.getContent()); - triggeredBody.put("form",form); + triggeredBody.put("form", form); } else { JSONObject form = (JSONObject) triggeredBody.get("form"); form.put(triggeredFunctionAttribute.getName(), triggeredFunctionAttribute.getContent()); - triggeredBody.put("form",form); + triggeredBody.put("form", form); } } @@ -1710,38 +1792,68 @@ private void mapAttributes(JSONObject b, ServiceFunctionAttribute sfa, String fu } } - private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotAgent botAgent, String functionPath, String triggerUID, + private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotAgent botAgent, String functionPath, + String triggerUID, JSONObject triggeredBody) throws AgentNotFoundException, AgentOperationFailedException { + JSONObject remarks = new JSONObject(); + String serviceEndpoint = ""; + remarks.put("user", encryptThisString(triggeredBody.getAsString("user"))); if (sf.getActionType().equals(ActionType.SERVICE) || sf.getActionType().equals(ActionType.OPENAPI)) { MiniClient client = new MiniClient(); if (sf.getActionType().equals(ActionType.SERVICE)) { - client.setConnectorEndpoint(address); + client.setConnectorEndpoint(webconnectorUrl); + serviceEndpoint = webconnectorUrl; } else if (sf.getActionType().equals(ActionType.OPENAPI)) { client.setConnectorEndpoint(sf.getServiceName() + functionPath); - } - //client.setLogin("alice", "pwalice"); - //client.setLogin(botAgent.getLoginName(), botPass); - String userId= triggeredBody.getAsString("user"); + serviceEndpoint = sf.getServiceName() + functionPath; + } + remarks.put("serviceEndpoint", serviceEndpoint); + l2pcontext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_3, remarks.toJSONString(), + triggeredBody.get("conversationId").toString(), sf.getFunctionName(), + botAgent.getIdentifier().toString(), "bot", "start", System.currentTimeMillis()); + // client.setLogin("alice", "pwalice"); + // client.setLogin(botAgent.getLoginName(), botPass); + String userId = triggeredBody.getAsString("user"); Bot bot = botConfig.getBots().get(botAgent.getIdentifier()); String messengerID = sf.getMessengerName(); + String channel = triggeredBody.getAsString("channel"); + HashMap headers = new HashMap(); + // HashMap attlist = new HashMap(); + // JSONObject triggerAttributes = new JSONObject(); + + // Get the channel's conversation and add them to the json array + JSONArray jsonArray = new JSONArray(); + HashMap> conversation = bot.getMessenger(messengerID) + .getConversationMap(); + for (ConversationMessage msg : conversation.get(channel)) { + HashMap msgMap = new HashMap(); + msgMap.put("role", msg.getRole()); + msgMap.put("content", msg.getContent()); + JSONObject jsonmsgMap = new JSONObject(msgMap); + jsonArray.add(jsonmsgMap); + } + triggeredBody.put("conversationPath", jsonArray); triggeredBody.put("messenger", bot.getMessenger(messengerID).getChatService().toString()); triggeredBody.put("botId", bot.getId()); triggeredBody.put("botName", bot.getName()); - String channel = triggeredBody.getAsString("channel"); - HashMap headers = new HashMap(); - System.out.println(sf.getServiceName() + functionPath + " ; " + triggeredBody.toJSONString() + " " - + sf.getConsumes() + " " + sf.getProduces() + " My string is" + ":" + triggeredBody.toJSONString()); + + ClientResponse r = null; JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE); - if(triggeredBody.containsKey("form")){ + if (triggeredBody.containsKey("form")) { try { File f = null; - if(triggeredBody.containsKey("fileBody")){ - byte[] decodedBytes = java.util.Base64.getDecoder().decode(triggeredBody.getAsString("fileBody")); - f = new File(triggeredBody.getAsString("fileName") + "." + triggeredBody.getAsString("fileType")); - /* if(fileType.equals("")){ - file = new File(fileName); - } */ + if (triggeredBody.containsKey("fileBody")) { + byte[] decodedBytes = java.util.Base64.getDecoder() + .decode(triggeredBody.getAsString("fileBody")); + f = new File( + triggeredBody.getAsString("fileName") + "." + triggeredBody.getAsString("fileType")); + /* + * if(fileType.equals("")){ + * file = new File(fileName); + * } + */ try { FileUtils.writeByteArrayToFile(f, decodedBytes); } catch (IOException e) { @@ -1749,85 +1861,87 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA e.printStackTrace(); } } - - Client textClient = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); - functionPath = functionPath.replace("[channel]",channel); + functionPath = functionPath.replace("[channel]", channel); // will need to add email here as well - // functionPath = functionPath.replace("[email]", email); + // functionPath = functionPath.replace("[email]", email); functionPath = functionPath.replace("[intent]", triggeredBody.getAsString("intent")); functionPath = bot.getMessenger(messengerID).replaceVariables(channel, functionPath); JSONObject entities = (JSONObject) triggeredBody.get("entities"); - for(String eName : entities.keySet()){; - if(functionPath.toLowerCase().contains("["+eName+"]")){ - functionPath = functionPath.replace("["+eName+"]",((JSONObject) entities.get(eName)).get("value").toString()); - } + for (String eName : entities.keySet()) { + ; + if (functionPath.toLowerCase().contains("[" + eName + "]")) { + functionPath = functionPath.replace("[" + eName + "]", + ((JSONObject) entities.get(eName)).get("value").toString()); } - + } + JSONObject form = (JSONObject) triggeredBody.get("form"); FormDataMultiPart mp = new FormDataMultiPart(); String queryParams = "?"; - if(form != null){ - for (String key : form.keySet()) { - if(sf.getHttpMethod().equals("get")){ - if (form.getAsString(key).equals("[channel]")) { - queryParams+=key+"="+channel+"&"; - } else if (form.getAsString(key).equals("[email]")) { - // queryParams+=key+"="+email+"&"; - } else if (form.getAsString(key).equals("[organization]")) { - queryParams+=key+"="+triggeredBody.getAsString("organization")+"&"; - } else { - queryParams+=key+"="+form.getAsString(key)+"&"; - } + if (form != null) { + for (String key : form.keySet()) { + if (sf.getHttpMethod().equals("get")) { + if (form.getAsString(key).equals("[channel]")) { + queryParams += key + "=" + channel + "&"; + } else if (form.getAsString(key).equals("[email]")) { + // queryParams+=key+"="+email+"&"; + } else if (form.getAsString(key).equals("[organization]")) { + queryParams += key + "=" + triggeredBody.getAsString("organization") + "&"; } else { - if (form.getAsString(key).equals("[channel]")) { - mp = mp.field(key, channel); - } else if (form.getAsString(key).equals("[email]")) { - // mp = mp.field(key, email); - } else if (form.getAsString(key).equals("[organization]")) { - mp = mp.field(key, triggeredBody.get("organization").toString()); - } else if(form.getAsString(key).contains("[")) { - for(String eName : entities.keySet()){ - if(form.getAsString(key).toLowerCase().contains(eName)){ - mp = mp.field(key, ((JSONObject) entities.get(eName)).get("value").toString()); - } + queryParams += key + "=" + form.getAsString(key) + "&"; + } + } else { + if (form.getAsString(key).equals("[channel]")) { + mp = mp.field(key, channel); + } else if (form.getAsString(key).equals("[email]")) { + // mp = mp.field(key, email); + } else if (form.getAsString(key).equals("[organization]")) { + mp = mp.field(key, triggeredBody.get("organization").toString()); + } else if (form.getAsString(key).contains("[")) { + for (String eName : entities.keySet()) { + if (form.getAsString(key).toLowerCase().contains(eName)) { + mp = mp.field(key, + ((JSONObject) entities.get(eName)).get("value").toString()); } - } else { - mp = mp.field(key, form.getAsString(key)); } + } else { + mp = mp.field(key, form.getAsString(key)); } } } - for(String key : form.keySet()){ - if(form.getAsString(key).equals("[channel]")){ + } + for (String key : form.keySet()) { + if (form.getAsString(key).equals("[channel]")) { mp = mp.field(key, channel); } else { mp = mp.field(key, form.getAsString(key)); } - + } - if(f != null && f.exists()){ + if (f != null && f.exists()) { FileDataBodyPart filePart = new FileDataBodyPart("file", f); mp.bodyPart(filePart); } - + WebTarget target = textClient.target(sf.getServiceName() + functionPath + queryParams); if (f != null && f.exists()) { - FileDataBodyPart filePart = new FileDataBodyPart("file", f); - mp.bodyPart(filePart); - } + FileDataBodyPart filePart = new FileDataBodyPart("file", f); + mp.bodyPart(filePart); + } Response response = null; - if(sf.getHttpMethod().equals("get")){ - response = target.request().get(); - } else { - response = target.request() + if (sf.getHttpMethod().equals("get")) { + response = target.request().get(); + } else { + response = target.request() .post(javax.ws.rs.client.Entity.entity(mp, mp.getMediaType())); - } + } String test = response.readEntity(String.class); mp.close(); try { - java.nio.file.Files.deleteIfExists(Paths.get(triggeredBody.getAsString("fileName") + "." + triggeredBody.getAsString("fileType"))); + java.nio.file.Files.deleteIfExists(Paths.get( + triggeredBody.getAsString("fileName") + "." + triggeredBody.getAsString("fileType"))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -1835,40 +1949,48 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA ChatMediator chat = bot.getMessenger(messengerID).getChatMediator(); triggeredBody = new JSONObject(); triggeredBody.put("channel", channel); - triggeredBody.put("text", test); + triggeredBody.put("text", test); JSONObject jsonResponse = (JSONObject) parser.parse(test); - for(String key : jsonResponse.keySet()){ - bot.getMessenger(messengerID).addVariable(channel, key, jsonResponse.getAsString(key)); - } + for (String key : jsonResponse.keySet()) { + bot.getMessenger(messengerID).addVariable(channel, key, jsonResponse.getAsString(key)); + } bot.getMessenger(messengerID).setContextToBasic(channel, - userId); - //triggerChat(chat, triggeredBody); + userId); + // triggerChat(chat, triggeredBody); + l2pcontext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_3, remarks.toJSONString(), + triggeredBody.get("conversationId").toString(), sf.getFunctionName(), + botAgent.getIdentifier().toString(), "bot", "complete", System.currentTimeMillis()); return; - - // FormDataMultiPart multipart = (FormDataMultiPart) mp.field("msg", newText).field("description", "") - // .bodyPart(filePart); - /* FileDataBodyPart filePart = new FileDataBodyPart("file", f); - if(f.getName().toLowerCase().contains("json")){ - filePart.setMediaType(MediaType.APPLICATION_JSON_TYPE); - } - FormDataMultiPart mp = new FormDataMultiPart(); - FormDataMultiPart multipart = (FormDataMultiPart) mp.field("msg", newText).field("description", "") - .bodyPart(filePart); - Response response = target.request().header("X-User-Id", client.getMyUserId()).header("X-Auth-Token", token) - .post(Entity.entity(multipart, multipart.getMediaType())); - System.out.println(response.getEntity().toString()); - mp.close(); - multipart.close(); - try { - java.nio.file.Files.deleteIfExists(Paths.get(f.getName())); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - }*/ + + // FormDataMultiPart multipart = (FormDataMultiPart) mp.field("msg", + // newText).field("description", "") + // .bodyPart(filePart); + /* + * FileDataBodyPart filePart = new FileDataBodyPart("file", f); + * if(f.getName().toLowerCase().contains("json")){ + * filePart.setMediaType(MediaType.APPLICATION_JSON_TYPE); + * } + * FormDataMultiPart mp = new FormDataMultiPart(); + * FormDataMultiPart multipart = (FormDataMultiPart) mp.field("msg", + * newText).field("description", "") + * .bodyPart(filePart); + * Response response = target.request().header("X-User-Id", + * client.getMyUserId()).header("X-Auth-Token", token) + * .post(Entity.entity(multipart, multipart.getMediaType())); + * System.out.println(response.getEntity().toString()); + * mp.close(); + * multipart.close(); + * try { + * java.nio.file.Files.deleteIfExists(Paths.get(f.getName())); + * } catch (IOException e) { + * // TODO Auto-generated catch block + * e.printStackTrace(); + * } + */ } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); - + } } else { if (sf.getActionType().equals(ActionType.SERVICE)) { @@ -1880,59 +2002,158 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA } } - System.out.println("Connect Success"); - System.out.println(r.getResponse()); - if (Boolean.parseBoolean(triggeredBody.getAsString("contextOn"))) { - try { - JSONObject response = (JSONObject) parser.parse(r.getResponse()); - for(String key : response.keySet()){ - bot.getMessenger(messengerID).addVariable(channel, key, response.getAsString(key)); - } - triggeredBody.put("text", response.getAsString("text")); - ChatMediator chat = bot.getMessenger(messengerID).getChatMediator(); - if (response.containsKey("fileBody")) { - triggeredBody.put("fileBody", response.getAsString("fileBody")); - triggeredBody.put("fileName", response.getAsString("fileName")); - triggeredBody.put("fileType", response.getAsString("fileType")); - } else - triggeredBody.remove("fileBody"); - if (response.containsKey("contactList")) { - triggeredBody.put("contactList", response.getAsString("contactList")); - } - if (response.containsKey("contactText")) { - triggeredBody.put("contactText", response.getAsString("contactText")); - } - if (response.containsKey("blocks")) { - triggeredBody.put("blocks", response.getAsString("blocks")); - if (response.containsKey("updateBlock")) { - triggeredBody.put("updateBlock", response.getAsString("updateBlock")); - if (response.containsKey("ts")) { - triggeredBody.put("ts", response.getAsString("ts")); + // if the result is successful + if (r.getResponse() != null) { + if (r.getResponse().toString().length() > 30) { + System.out.println(r.getResponse().toString().substring(0, 30) + "..."); + } else { + System.out.println(r.getResponse()); + } + + if (Boolean.parseBoolean(triggeredBody.getAsString("contextOn"))) { + try { + JSONObject response = (JSONObject) parser.parse(r.getResponse()); + for (String key : response.keySet()) { + bot.getMessenger(messengerID).addVariable(channel, key, response.getAsString(key)); + } + triggeredBody.put("text", response.getAsString("text")); + + ChatMediator chat = bot.getMessenger(messengerID).getChatMediator(); + if (response.containsKey("fileBody")) { + triggeredBody.put("fileBody", response.getAsString("fileBody")); + triggeredBody.put("fileName", response.getAsString("fileName")); + triggeredBody.put("fileType", response.getAsString("fileType")); + } else + triggeredBody.remove("fileBody"); + if (response.containsKey("contactList")) { + triggeredBody.put("contactList", response.getAsString("contactList")); + } + if (response.containsKey("contactText")) { + triggeredBody.put("contactText", response.getAsString("contactText")); + } + if (response.containsKey("blocks")) { + triggeredBody.put("blocks", response.getAsString("blocks")); + if (response.containsKey("updateBlock")) { + triggeredBody.put("updateBlock", response.getAsString("updateBlock")); + if (response.containsKey("ts")) { + triggeredBody.put("ts", response.getAsString("ts")); + } } } - } - if(response.containsKey("multiFiles")){ - for(Object o : (JSONArray) response.get("multiFiles")){ - JSONObject jsonO = (JSONObject) o; - System.out.println("handling multifiles"); - jsonO.put("channel", triggeredBody.getAsString("channel")); - jsonO.put("email", triggeredBody.getAsString("email")); - triggerChat(chat, jsonO); + if (response.containsKey("multiFiles")) { + for (Object o : (JSONArray) response.get("multiFiles")) { + JSONObject jsonO = (JSONObject) o; + jsonO.put("channel", triggeredBody.getAsString("channel")); + jsonO.put("email", triggeredBody.getAsString("email")); + triggerChat(chat, jsonO); + } + } else { + // if the service function triggers another service function, do not trigger chat, add the response to the conversationpath + if (!sf.getTrigger().isEmpty()){ + HashMap> convMap = bot.getMessenger(messengerID).getConversationMap(); + Collection conv = convMap.get(triggeredBody.getAsString("channel")); + ArrayList convList = new ArrayList<>(conv); + ConversationMessage botMsg = convList.get(convList.size() - 1); + String convId = botMsg.getConversationId(); + triggeredBody.put("conversationId", convId); + ConversationMessage newConvMsg = new ConversationMessage(convId, "assistant", + triggeredBody.getAsString("text")); + conv.add(newConvMsg); + bot.getMessenger(messengerID).updateConversationInConversationMap(triggeredBody.getAsString("channel"), conv); + + //Trigger trigger = sf.getTrigger().iterator().next(); + //ServiceFunction triggeredSf = trigger.getTriggeredFunction(); + Gson gson = new Gson(); + String service = (String) sf.getServiceName(); + triggeredBody.put("serviceAlias", service); + String triggerFunctionName = sf.getFunctionName(); + triggeredBody.put("functionName", triggerFunctionName); + String triggerID = sf.getId(); + triggeredBody.put("uid", triggerID); + JSONObject triggerAttributes = new JSONObject(); + triggeredBody.put("attributes", triggerAttributes); + + //Set the endpoint to the base url for the SBFManager + if (sf.getActionType().equals(ActionType.OPENAPI)){ + client.setConnectorEndpoint(webconnectorUrl); + } + + try { + ClientResponse result = client.sendRequest("POST", + "SBFManager/bots/" + bot.getName() + "/trigger/service", gson.toJson(triggeredBody), + MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); + } catch (Exception e) { + e.printStackTrace(); + } + + } else{ + triggerChat(chat, triggeredBody); + } + // if the response is from the openai service, + // replace the last message in the conversation map which should be the normal + // bot response with the enhanced bot message + if (Boolean.parseBoolean(response.getAsString("openai"))) { + // add token count to body + triggeredBody.put("tokens", response.getAsNumber("tokens")); + + HashMap> convMap = bot.getMessenger(messengerID) + .getConversationMap(); + Collection conv = convMap.get(triggeredBody.getAsString("channel")); + ArrayList convList = new ArrayList<>(conv); + ConversationMessage botMsg = convList.get(convList.size() - 1); + String convId = botMsg.getConversationId(); + convList.remove(botMsg); + ConversationMessage newConvMsg = new ConversationMessage(convId, "assistant", + triggeredBody.getAsString("text")); + convList.add(newConvMsg); + conv = convList; + bot.getMessenger(messengerID) + .updateConversationInConversationMap(triggeredBody.getAsString("channel"), conv); + } } - } else { - triggerChat(chat, triggeredBody); - } - if (response.get("closeContext") == null || Boolean.valueOf(response.getAsString("closeContext"))) { - System.out.println("Closed Context"); - bot.getMessenger(messengerID).setContextToBasic(triggeredBody.getAsString("channel"), + //We check if there is a leadsTo after the bot action: + if (!sf.getLeadsTo().isEmpty()) { + + /** ADD CHECKS HERE TO DETERMINE WHETHER OR NOT TO ADD THE LEADS TO INCOMING MESSAGE TO THE FOLLOW UP STATE + * + * Example: Check the response code and flags returned by the service call + * + * */ + + // We add the incoming message to the followupmessage of the current conversation state + IncomingMessage currentState = bot.getMessenger(messengerID).getStateMap().get(channel); + + for (int i = 0; i < sf.getLeadsTo().size(); i++) { + IncomingMessage msg = (IncomingMessage) sf.getLeadsTo().keySet().toArray()[i]; + String intentKey = (String) sf.getLeadsTo().values().toArray()[i]; + currentState.addFollowupMessage(intentKey, msg); + } + currentState.setFreezeMessageSend(true); + } else if (!sf.getTrigger().isEmpty()){ + IncomingMessage currentState = bot.getMessenger(messengerID).getStateMap().get(channel); + currentState.setFreezeMessageSend(true); + } + if (response.get("closeContext") == null || Boolean.valueOf(response.getAsString("closeContext"))) { + System.out.println("Closed Context"); + bot.getMessenger(messengerID).setContextToBasic(triggeredBody.getAsString("channel"), triggeredBody.getAsString("user")); + } else if (Boolean.valueOf(response.getAsString("closeContext")) == false) { + System.out.println("Keep Context open"); + bot.getMessenger(messengerID).restoreConversationState(triggeredBody.getAsString("channel")); + } + + } catch (ParseException e) { + e.printStackTrace(); } - } catch (ParseException e) { - e.printStackTrace(); } + } else { + System.out.println("Response from request is null"); } - + l2pcontext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_3, remarks.toJSONString(), + triggeredBody.get("conversationId").toString(), sf.getFunctionName(), + botAgent.getIdentifier().toString(), "bot", "complete", System.currentTimeMillis()); } else if (sf.getActionType().equals(ActionType.SENDMESSAGE)) { + // deprecated Bot bot = botConfig.getBots().get(botAgent.getIdentifier()); if (triggeredBody.get("channel") == null && triggeredBody.get("email") == null) { // TODO Anonymous agent error @@ -1956,6 +2177,7 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA } public void triggerChat(ChatMediator chat, JSONObject body) { + String text = body.getAsString("text"); String blocks = body.getAsString("blocks"); String channel = null; @@ -1981,18 +2203,17 @@ public void triggerChat(ChatMediator chat, JSONObject body) { channel = chat.getChannelByEmail(s); if (textArray[i] != null) { - chat.sendMessageToChannel(channel, textArray[i],"text"); + chat.sendMessageToChannel(channel, textArray[i], "text"); } i++; } } else { // if no specific text, send the regular text for (String s : emailArray) { - System.out.println(s); channel = chat.getChannelByEmail(s); if (text != null && channel != null) { - chat.sendMessageToChannel(channel, text,"text"); + chat.sendMessageToChannel(channel, text, "text"); } } @@ -2004,9 +2225,9 @@ public void triggerChat(ChatMediator chat, JSONObject body) { email = body.getAsString("email"); channel = chat.getChannelByEmail(email); } - chat.sendMessageToChannel(channel, "ContactList contacted.","text"); + chat.sendMessageToChannel(channel, "ContactList contacted.", "text"); - }else { + } else { if (body.containsKey("channel")) { channel = body.getAsString("channel"); } else if (body.containsKey("email")) { @@ -2015,7 +2236,7 @@ public void triggerChat(ChatMediator chat, JSONObject body) { channel = chat.getChannelByEmail(email); } if (text != null && !body.containsKey("fileBody")) { - chat.sendMessageToChannel(channel, text,"text"); + chat.sendMessageToChannel(channel, text, "text"); } if (body.containsKey("blocks")) { System.out.println("Body has blocks"); @@ -2042,8 +2263,8 @@ public void triggerChat(ChatMediator chat, JSONObject body) { } monitorEvent42.put("time", System.currentTimeMillis() - start); } - if (l2pcontext!=null){ - l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_42,monitorEvent42.toString()); + if (l2pcontext != null) { + l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_42, monitorEvent42.toString()); } } @@ -2271,7 +2492,7 @@ public void getXapiStatements(ArrayList statements) { System.out.println("\u001B[33mDebug --- Partition: " + statementsPerCourse.toString() + "\u001B[0m"); // Check if any bots take xAPI statements first - HashMap bots = config.getBots(); + HashMap bots = config.getBots(); for (Entry botEntry : bots.entrySet()) { HashMap messengers = botEntry.getValue().getMessengers(); @@ -2349,7 +2570,7 @@ public void run() { if (restarterBot == null) { MiniClient clientRestart = new MiniClient(); - clientRestart.setConnectorEndpoint(address); + clientRestart.setConnectorEndpoint(webconnectorUrl); clientRestart.setLogin("alice", "pwalice"); HashMap headers = new HashMap(); try { @@ -2372,131 +2593,130 @@ public void run() { SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); SimpleDateFormat df2 = new SimpleDateFormat("HH:mm"); Gson gson = new Gson(); - for (Bot bot : getConfig().getBots().values()) { - ArrayList messageInfos = new ArrayList(); - for (MessageInfo m : messageInfos) { - ChatStatement chatStatement = ChatStatement.generate(m.getMessage().getUser(), m.getBotName(), - m.getMessage().getText(), m.getMessage().getTime(), m.getMessage().getDomain()); - String chatStatementJSON = gson.toJson(chatStatement); - // l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_2, chatStatementJSON); + for (Bot bot : getConfig().getBots().values()) { + ArrayList messageInfos = new ArrayList(); + for (MessageInfo m : messageInfos) { + ChatStatement chatStatement = ChatStatement.generate(m.getMessage().getUser(), m.getBotName(), + m.getMessage().getText(), m.getMessage().getTime(), m.getMessage().getDomain()); + String chatStatementJSON = gson.toJson(chatStatement); + // l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_2, + // chatStatementJSON); + } + bot.handleMessages(messageInfos); + + // TODO: Handle multiple environments (maybe?) + + MiniClient client = new MiniClient(); + client.setConnectorEndpoint(webconnectorUrl); + + HashMap headers = new HashMap(); + for (MessageInfo m : messageInfos) { + try { + ClientResponse result = client.sendRequest("POST", + "SBFManager/bots/" + m.getBotName() + "/trigger/intent", gson.toJson(m), + MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); + } catch (Exception e) { + e.printStackTrace(); } - bot.handleMessages(messageInfos); + } - // TODO: Handle multiple environments (maybe?) + for (BotRoutine r : bot.getRoutines().values()) { + // current time + Calendar c = Calendar.getInstance(); + long d1 = c.getTime().getTime(); + // last time updated + long d2 = r.getLastUpdate(); - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(address); + long diffInMillies = d1 - d2; - HashMap headers = new HashMap(); - for (MessageInfo m : messageInfos) { - try { - ClientResponse result = client.sendRequest("POST", - "SBFManager/bots/" + m.getBotName() + "/trigger/intent", gson.toJson(m), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - } catch (Exception e) { - e.printStackTrace(); + int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); + + boolean trigger = false; + long min = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS); + if (r.getInterval().equals("Minute")) { + if (min >= Integer.parseInt(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); } } - - for (BotRoutine r : bot.getRoutines().values()) { - // current time - Calendar c = Calendar.getInstance(); - long d1 = c.getTime().getTime(); - // last time updated - long d2 = r.getLastUpdate(); - - long diffInMillies = d1 - d2; - - int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); - - boolean trigger = false; - long min = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (r.getInterval().equals("Minute")) { - if (min >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } + if (r.getInterval().equals("Hour")) { + long hour = TimeUnit.HOURS.convert(diffInMillies, TimeUnit.MILLISECONDS); + if (hour >= Integer.parseInt(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); } - if (r.getInterval().equals("Hour")) { - long hour = TimeUnit.HOURS.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (hour >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } + } + if (r.getInterval().equals("Day")) { + long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); + if (day >= Integer.parseInt(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); } - if (r.getInterval().equals("Day")) { - long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (day >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } + } + if (r.getInterval().equals("Month")) { + long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); + // TODO + day = day / 28; + if (day >= Integer.parseInt(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); } - if (r.getInterval().equals("Month")) { - long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); - // TODO - day = day / 28; - if (day >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Working days") && dayOfWeek != Calendar.SATURDAY - && dayOfWeek != Calendar.SUNDAY) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Weekend") - && (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY)) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Every day")) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } + } else if (r.getInterval().equals("Working days") && dayOfWeek != Calendar.SATURDAY + && dayOfWeek != Calendar.SUNDAY) { + if (min >= 1 && df2.format(d1).equals(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); } - if (trigger) { - for (Bot b : getConfig().getBots().values()) { - HashMap activeBots = b.getActive(); - HashSet tList = r.getTrigger(); - for (Trigger t : tList) { - // for (Entry entry : activeBots.entrySet()) { - // If bot is active - // if (entry.getValue()) { - - System.out.println(df.format(d1) + ": " + b.getName()); - - JSONObject body = new JSONObject(); - body.put("serviceAlias", ""); // TODO - - JSONObject atts = new JSONObject(); - - body.put("function", t.getTriggeredFunction().getId()); - body.put("bot", b.getName()); - // atts.put(vle.getEnvironmentSeparator(), entry.getKey()); - body.put("attributes", atts); - - headers = new HashMap(); - String path = "SBFManager/bots/" + b.getName() + "/trigger/routine"; - try { - path = "SBFManager/bots/" + URLEncoder.encode(b.getName(), "UTF-8") - + "/trigger/routine"; - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - ClientResponse result = client.sendRequest("POST", path, body.toJSONString(), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - // } + } else if (r.getInterval().equals("Weekend") + && (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY)) { + if (min >= 1 && df2.format(d1).equals(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); + } + } else if (r.getInterval().equals("Every day")) { + if (min >= 1 && df2.format(d1).equals(r.getTime())) { + trigger = true; + r.setLastUpdate(d1); + } + } + if (trigger) { + for (Bot b : getConfig().getBots().values()) { + HashMap activeBots = b.getActive(); + HashSet tList = r.getTrigger(); + for (Trigger t : tList) { + // for (Entry entry : activeBots.entrySet()) { + // If bot is active + // if (entry.getValue()) { + + JSONObject body = new JSONObject(); + body.put("serviceAlias", ""); // TODO + + JSONObject atts = new JSONObject(); + + body.put("function", t.getTriggeredFunction().getId()); + body.put("bot", b.getName()); + // atts.put(vle.getEnvironmentSeparator(), entry.getKey()); + body.put("attributes", atts); + + headers = new HashMap(); + String path = "SBFManager/bots/" + b.getName() + "/trigger/routine"; + try { + path = "SBFManager/bots/" + URLEncoder.encode(b.getName(), "UTF-8") + + "/trigger/routine"; + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + ClientResponse result = client.sendRequest("POST", path, body.toJSONString(), + MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); + // } } } - } + } - + } + } } @@ -2739,7 +2959,7 @@ public Response testRoute(@PathParam("token") String token, @PathParam("email") System.out.println("Using email " + email); String channel = chatMediator.getChannelByEmail(email); - chatMediator.sendMessageToChannel(channel, msgtext,"text"); + chatMediator.sendMessageToChannel(channel, msgtext, "text"); } catch (Exception e) { e.printStackTrace(); @@ -2771,7 +2991,7 @@ public Response sendMessageToRocketChat(@PathParam("token") String token, @PathP JSONObject bodyInput = (JSONObject) p.parse(input); String msgtext = bodyInput.getAsString("msg"); String channel = chatMediator.getChannelByEmail(email); - chatMediator.sendMessageToChannel(channel, msgtext,"text"); + chatMediator.sendMessageToChannel(channel, msgtext, "text"); } catch (Exception e) { e.printStackTrace(); @@ -2829,7 +3049,7 @@ public Response editMessage(@PathParam("token") String token, @PathParam("email" } - // Should be an own resource.. this whole class needs refactoring. + // Should be an own resource.. this whole class needs refactoring. @Api(value = "RESTfulChat Resource") @SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.6.0", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "BSD 3-Clause License", url = "https://raw.githubusercontent.com/rwth-acis/las2peer-social-bot-manager-service/master/LICENSE"))) @Path("/RESTfulChat") @@ -2841,13 +3061,14 @@ public static class RESTfulChatResource { // adding this temporarily to avoid needing to add stuff elsewhere static HashMap channelToMessenger = new HashMap(); + /** * Handles RESTful chat requests. * - * @param bot the name of the bot to send the message to + * @param bot the name of the bot to send the message to * @param organization the organization to send the message to - * @param channel the channel to send the message to - * @param input the input message, in JSON format + * @param channel the channel to send the message to + * @param input the input message, in JSON format * @return the response from the bot, in plain text format */ @POST @@ -2855,39 +3076,43 @@ public static class RESTfulChatResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Sends a message to the RESTful chat bot and channel", notes = "Provides a service to send a message to the specified bot and channel through a RESTful API endpoint") - @ApiResponses(value = {@ApiResponse(code = 200, message = "Message successfully sent"),@ApiResponse(code = 500, message = "Internal server error"),@ApiResponse(code = 400, message = "Bad request, required parameters not provided")}) - public Response handleRESTfulChat(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, + @ApiResponses(value = { @ApiResponse(code = 200, message = "Message successfully sent"), + @ApiResponse(code = 500, message = "Internal server error"), + @ApiResponse(code = 400, message = "Bad request, required parameters not provided") }) + public Response handleRESTfulChat(@PathParam("bot") String bot, @PathParam("organization") String organization, + @PathParam("channel") String channel, String input) { - RESTfulChatResponse answerMsg = null; - String email = ""; - try{ - UserAgent userAgent = (UserAgent) Context.getCurrent().getMainAgent(); - email = userAgent.getEmail(); - emailToChannel.put(email, organization +"-"+channel); - } catch (Exception e){ - e.printStackTrace(); - } + RESTfulChatResponse answerMsg = null; + String email = ""; + try { + UserAgent userAgent = (UserAgent) Context.getCurrent().getMainAgent(); + email = userAgent.getEmail(); + emailToChannel.put(email, organization + "-" + channel); + } catch (Exception e) { + e.printStackTrace(); + } try { Bot b = null; - for(Bot botIterator: getConfig().getBots().values()){ - if(botIterator.getName().equalsIgnoreCase(bot)){ + for (Bot botIterator : getConfig().getBots().values()) { + if (botIterator.getName().equalsIgnoreCase(bot)) { b = botIterator; } } - // there should be one or no bot available (we will remove instance in a later version) - if(b!=null){ + // there should be one or no bot available (we will remove instance in a later + // version) + if (b != null) { ArrayList messageInfos = new ArrayList(); boolean found = false; for (Messenger m : b.getMessengers().values()) { - if(m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator){ - + if (m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator) { + RESTfulChatMediator chatMediator = (RESTfulChatMediator) m.getChatMediator(); JSONParser p = new JSONParser(); JSONObject bodyInput = (JSONObject) p.parse(input); String orgChannel = organization + "-" + channel; channelToMessenger.put(orgChannel, m); String msgtext = bodyInput.getAsString("message"); - if(msgtext==null || msgtext.equals("")){ + if (msgtext == null || msgtext.equals("")) { return Response.status(Status.BAD_REQUEST).entity("No message provided.").build(); } ChatMessage msg = new ChatMessage(orgChannel, orgChannel, msgtext); @@ -2913,38 +3138,43 @@ public Response handleRESTfulChat(@PathParam("bot") String bot, @PathParam("orga functionPath = body.getAsString("functionPath"); sf = b.getBotServiceFunctions().get(messageInfo.getTriggeredFunctionId()); body.put("email", email); - body.put("organization",organization); + body.put("organization", organization); sf.setMessengerName(messageInfo.getMessengerName()); performTrigger(config, sf, botAgent, functionPath, functionPath, body); RESTfulChatResponse oldAnswerMsg = answerMsg; answerMsg = chatMediator.getMessageForChannel(orgChannel); - if((oldAnswerMsg.getMessage() != answerMsg.getMessage()) || (answerMsg.getMessage().contains(oldAnswerMsg.getMessage()))){ - //answerMsg.setMessage(oldAnswerMsg.getMessage() + "\n" + answerMsg.getMessage()); + if ((oldAnswerMsg.getMessage() != answerMsg.getMessage()) + || (answerMsg.getMessage().contains(oldAnswerMsg.getMessage()))) { + // answerMsg.setMessage(oldAnswerMsg.getMessage() + "\n" + + // answerMsg.getMessage()); } answerMsg.setReqBody(body); - if(body.containsKey("resBody") && ((JSONObject)body.get("resBody")).containsKey("interactiveElements")){ - List ils = (List) ((JSONObject)body.get("resBody")).get("interactiveElements"); - answerMsg.setInteractiveElements(ils);; + if (body.containsKey("resBody") && ((JSONObject) body.get("resBody")) + .containsKey("interactiveElements")) { + List ils = (List) ((JSONObject) body.get("resBody")) + .get("interactiveElements"); + answerMsg.setInteractiveElements(ils); + ; } } } catch (Exception e) { - + } } // chatMediator.sendMessageToChannel(orgChannel, "msgtext", new // HashMap(), "text", null); - + found = true; } } - if(!found){ - return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot "+bot+".").build(); + if (!found) { + return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot " + bot + ".") + .build(); } - }else{ - return Response.status(Status.NOT_FOUND).entity("Bot "+bot+" not found.").build(); + } else { + return Response.status(Status.NOT_FOUND).entity("Bot " + bot + " not found.").build(); } - } catch (Exception e) { e.printStackTrace(); @@ -2966,130 +3196,131 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA Messenger m = bot.getMessenger(messengerID); HashMap headers = new HashMap(); JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE); - try { - File f = null; - if (triggeredBody.containsKey("fileBody")) { - byte[] decodedBytes = java.util.Base64.getDecoder() - .decode(triggeredBody.getAsString("fileBody")); - f = new File(triggeredBody.getAsString("fileName") + "." - + triggeredBody.getAsString("fileType")); - /* - * if(fileType.equals("")){ - * file = new File(fileName); - * } - */ - try { - FileUtils.writeByteArrayToFile(f, decodedBytes); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + try { + File f = null; + if (triggeredBody.containsKey("fileBody")) { + byte[] decodedBytes = java.util.Base64.getDecoder() + .decode(triggeredBody.getAsString("fileBody")); + f = new File(triggeredBody.getAsString("fileName") + "." + + triggeredBody.getAsString("fileType")); + /* + * if(fileType.equals("")){ + * file = new File(fileName); + * } + */ + try { + FileUtils.writeByteArrayToFile(f, decodedBytes); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + } - String channel = triggeredBody.getAsString("channel"); - Client textClient = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); - functionPath = functionPath.replace("[channel]", channel); - functionPath = functionPath.replace("[email]", email); - functionPath = functionPath.replace("[organization]", triggeredBody.getAsString("organization")); - functionPath = functionPath.replace("[intent]", triggeredBody.getAsString("intent")); - functionPath = m.replaceVariables(channel, functionPath); - JSONObject entities = (JSONObject) triggeredBody.get("entities"); - for(String eName : entities.keySet()){; - if(functionPath.toLowerCase().contains("["+eName+"]")){ - functionPath = functionPath.replace("["+eName+"]",((JSONObject) entities.get(eName)).get("value").toString()); - } + String channel = triggeredBody.getAsString("channel"); + Client textClient = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); + functionPath = functionPath.replace("[channel]", channel); + functionPath = functionPath.replace("[email]", email); + functionPath = functionPath.replace("[organization]", triggeredBody.getAsString("organization")); + functionPath = functionPath.replace("[intent]", triggeredBody.getAsString("intent")); + functionPath = m.replaceVariables(channel, functionPath); + JSONObject entities = (JSONObject) triggeredBody.get("entities"); + for (String eName : entities.keySet()) { + ; + if (functionPath.toLowerCase().contains("[" + eName + "]")) { + functionPath = functionPath.replace("[" + eName + "]", + ((JSONObject) entities.get(eName)).get("value").toString()); } - JSONObject form = (JSONObject) triggeredBody.get("form"); - FormDataMultiPart mp = new FormDataMultiPart(); - String queryParams = "?"; - if(form != null){ - for (String key : form.keySet()) { - if(sf.getHttpMethod().equals("get")){ - if (form.getAsString(key).equals("[channel]")) { - queryParams+=key+"="+channel+"&"; - } else if (form.getAsString(key).equals("[email]")) { - queryParams+=key+"="+email+"&"; - } else if (form.getAsString(key).equals("[organization]")) { - queryParams+=key+"="+triggeredBody.getAsString("organization")+"&"; - } else { - queryParams+=key+"="+form.getAsString(key)+"&"; - } + } + JSONObject form = (JSONObject) triggeredBody.get("form"); + FormDataMultiPart mp = new FormDataMultiPart(); + String queryParams = "?"; + if (form != null) { + for (String key : form.keySet()) { + if (sf.getHttpMethod().equals("get")) { + if (form.getAsString(key).equals("[channel]")) { + queryParams += key + "=" + channel + "&"; + } else if (form.getAsString(key).equals("[email]")) { + queryParams += key + "=" + email + "&"; + } else if (form.getAsString(key).equals("[organization]")) { + queryParams += key + "=" + triggeredBody.getAsString("organization") + "&"; } else { - if (form.getAsString(key).equals("[channel]")) { - mp = mp.field(key, channel); - } else if (form.getAsString(key).equals("[email]")) { - mp = mp.field(key, email); - } else if (form.getAsString(key).equals("[organization]")) { - mp = mp.field(key, triggeredBody.get("organization").toString()); - } else if(form.getAsString(key).contains("[")) { - for(String eName : entities.keySet()){ - if(form.getAsString(key).toLowerCase().contains(eName)){ - mp = mp.field(key, ((JSONObject) entities.get(eName)).get("value").toString()); - } + queryParams += key + "=" + form.getAsString(key) + "&"; + } + } else { + if (form.getAsString(key).equals("[channel]")) { + mp = mp.field(key, channel); + } else if (form.getAsString(key).equals("[email]")) { + mp = mp.field(key, email); + } else if (form.getAsString(key).equals("[organization]")) { + mp = mp.field(key, triggeredBody.get("organization").toString()); + } else if (form.getAsString(key).contains("[")) { + for (String eName : entities.keySet()) { + if (form.getAsString(key).toLowerCase().contains(eName)) { + mp = mp.field(key, + ((JSONObject) entities.get(eName)).get("value").toString()); } - } else { - mp = mp.field(key, form.getAsString(key)); } + } else { + mp = mp.field(key, form.getAsString(key)); } } - } - System.out.println("Calling following URL: " + sf.getServiceName() +functionPath+ queryParams); - WebTarget target = textClient - .target(sf.getServiceName() +functionPath+ queryParams); - if (f != null && f.exists()) { - FileDataBodyPart filePart = new FileDataBodyPart("file", f); - mp.bodyPart(filePart); } + } + System.out.println("Calling following URL: " + sf.getServiceName() + functionPath + queryParams); + WebTarget target = textClient + .target(sf.getServiceName() + functionPath + queryParams); + if (f != null && f.exists()) { + FileDataBodyPart filePart = new FileDataBodyPart("file", f); + mp.bodyPart(filePart); + } - Response response = null; - if(sf.getHttpMethod().equals("get")){ - response = target.request().get(); - } else { - response = target.request() + Response response = null; + if (sf.getHttpMethod().equals("get")) { + response = target.request().get(); + } else { + response = target.request() .post(javax.ws.rs.client.Entity.entity(mp, mp.getMediaType())); - } - - String test = response.readEntity(String.class); - mp.close(); - try { - java.nio.file.Files.deleteIfExists(Paths.get(triggeredBody.getAsString("fileName") + "." - + triggeredBody.getAsString("fileType"))); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - /* triggeredBody = new JSONObject(); - triggeredBody.put("channel", channel); - triggeredBody.put("text", test); - */ - JSONObject jsonResponse = (JSONObject) parser.parse(test); - for (String key : jsonResponse.keySet()) { - bot.getMessenger(messengerID).addVariable(channel, key, jsonResponse.getAsString(key)); - } - System.out.println("Finished Bot Action Call"); - bot.getMessenger(messengerID).setContextToBasic(channel, - userId); - triggeredBody.put("resBody", jsonResponse); - // triggerChat(chat, triggeredBody); - return; - - } catch (Exception e) { - System.out.println(e.getMessage()); + } + String test = response.readEntity(String.class); + mp.close(); + try { + java.nio.file.Files.deleteIfExists(Paths.get(triggeredBody.getAsString("fileName") + "." + + triggeredBody.getAsString("fileType"))); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + /* + * triggeredBody = new JSONObject(); + * triggeredBody.put("channel", channel); + * triggeredBody.put("text", test); + */ + JSONObject jsonResponse = (JSONObject) parser.parse(test); + for (String key : jsonResponse.keySet()) { + bot.getMessenger(messengerID).addVariable(channel, key, jsonResponse.getAsString(key)); } - + bot.getMessenger(messengerID).setContextToBasic(channel, + userId); + triggeredBody.put("resBody", jsonResponse); + // triggerChat(chat, triggeredBody); + return; + + } catch (Exception e) { + System.out.println(e.getMessage()); + } } } /** * Handle RESTful chat file. * - * @param bot the bot name - * @param organization the organization name - * @param channel the channel name + * @param bot the bot name + * @param organization the organization name + * @param channel the channel name * @param uploadedInputStream the uploaded input stream - * @param fileDetail the file detail + * @param fileDetail the file detail * @return the response */ @POST @@ -3097,34 +3328,38 @@ private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotA @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Uploads a file to the RESTful chat bot and channel", notes = "Provides a service to upload a file to the specified bot and channel through a RESTful API endpoint") - @ApiResponses(value = {@ApiResponse(code = 200, message = "File successfully uploaded"), @ApiResponse(code = 500, message = "Internal server error"), @ApiResponse(code = 400, message = "Bad request, required parameters not provided")}) - public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, - @FormDataParam("file") InputStream uploadedInputStream, - @FormDataParam("file") FormDataContentDisposition fileDetail) { - RESTfulChatResponse answerMsg = new RESTfulChatResponse(""); + @ApiResponses(value = { @ApiResponse(code = 200, message = "File successfully uploaded"), + @ApiResponse(code = 500, message = "Internal server error"), + @ApiResponse(code = 400, message = "Bad request, required parameters not provided") }) + public Response handleRESTfulChatFile(@PathParam("bot") String bot, + @PathParam("organization") String organization, @PathParam("channel") String channel, + @FormDataParam("file") InputStream uploadedInputStream, + @FormDataParam("file") FormDataContentDisposition fileDetail) { + RESTfulChatResponse answerMsg = new RESTfulChatResponse(""); try { Bot b = null; - String addr = service.address; - for(Bot botIterator: getConfig().getBots().values()){ - if(botIterator.getName().equalsIgnoreCase(bot)){ + String addr = this.service.webconnectorUrl; + for (Bot botIterator : getConfig().getBots().values()) { + if (botIterator.getName().equalsIgnoreCase(bot)) { b = botIterator; } } - // there should be one or no bot available (we will remove instance in a later version) - if(b!=null){ + // there should be one or no bot available (we will remove instance in a later + // version) + if (b != null) { ArrayList messageInfos = new ArrayList(); boolean found = false; boolean err = false; for (Messenger m : b.getMessengers().values()) { - if(m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator){ + if (m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator) { byte[] bytes = toBytes(uploadedInputStream); String encoded = Base64.getEncoder().encodeToString(bytes); RESTfulChatMediator chatMediator = (RESTfulChatMediator) m.getChatMediator(); String fname = fileDetail.getFileName(); String ftype = getFileType(uploadedInputStream); - - RESTfulChatMessageCollector msgcollector = (RESTfulChatMessageCollector) chatMediator.getMessageCollector(); + RESTfulChatMessageCollector msgcollector = (RESTfulChatMessageCollector) chatMediator + .getMessageCollector(); String orgChannel = organization + "-" + channel; msgcollector.handle(encoded, fname, ftype, orgChannel); m.handleMessages(messageInfos, b); @@ -3132,14 +3367,14 @@ public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam(" String email = ""; for (MessageInfo messageInfo : messageInfos) { try { - try{ + try { UserAgent userAgent = (UserAgent) Context.getCurrent().getMainAgent(); email = userAgent.getEmail(); - emailToChannel.put(email, organization+"-"+channel); - } catch (Exception e){ + emailToChannel.put(email, organization + "-" + channel); + } catch (Exception e) { e.printStackTrace(); - for(String mail : emailToChannel.keySet()){ - if(emailToChannel.get(mail).equals(organization+"-"+channel)){ + for (String mail : emailToChannel.keySet()) { + if (emailToChannel.get(mail).equals(organization + "-" + channel)) { email = mail; break; } @@ -3156,28 +3391,31 @@ public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam(" JSONObject body = new JSONObject(); BotAgent botAgent = getBotAgents().get(b.getName()); ServiceFunction sf = new ServiceFunction(); - service.prepareRequestParameters(config, botAgent, messageInfo, functionPath, body, + this.service.prepareRequestParameters(config, botAgent, messageInfo, functionPath, + body, sf); if (body.containsKey("functionPath")) { functionPath = body.getAsString("functionPath"); sf = b.getBotServiceFunctions().get(messageInfo.getTriggeredFunctionId()); body.put("email", email); - body.put("organization",organization); + body.put("organization", organization); sf.setMessengerName(messageInfo.getMessengerName()); performTrigger(config, sf, botAgent, functionPath, functionPath, body); RESTfulChatResponse oldAnswerMsg = answerMsg; answerMsg = chatMediator.getMessageForChannel(orgChannel); body.remove("fileBody"); - for(String key : body.keySet()){ - if(body.get(key) != null && body.get(key).toString().equals("[channel]")){ + for (String key : body.keySet()) { + if (body.get(key) != null && body.get(key).toString().equals("[channel]")) { body.put(key, messageInfo.getMessage().getChannel()); } - if(body.get(key) != null && body.get(key).toString().contains("[")&& body.get(key).toString().contains("]") && !key.equals("form")){ - body.put(key, m.replaceVariables(orgChannel,body.get(key).toString())); + if (body.get(key) != null && body.get(key).toString().contains("[") + && body.get(key).toString().contains("]") && !key.equals("form")) { + body.put(key, m.replaceVariables(orgChannel, body.get(key).toString())); } } - if(oldAnswerMsg.getMessage() != answerMsg.getMessage()){ - // answerMsg.setMessage(oldAnswerMsg.getMessage() + "\n" + answerMsg.getMessage()); + if (oldAnswerMsg.getMessage() != answerMsg.getMessage()) { + // answerMsg.setMessage(oldAnswerMsg.getMessage() + "\n" + + // answerMsg.getMessage()); } answerMsg.setReqBody(body); } @@ -3188,33 +3426,35 @@ public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam(" found = true; // start to perform bot action in case it is triggered - - /*MiniClient client = new MiniClient(); - System.out.println("Addr: "+addr); - client.setConnectorEndpoint(addr); - HashMap headers = new HashMap(); - for (MessageInfo mInfo : messageInfos) { - try { - Gson gson = new Gson(); - ClientResponse result = client.sendRequest("POST", - "SBFManager/bots/" + mInfo.getBotName() + "/trigger/intent", gson.toJson(mInfo), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - System.out.println(result.getResponse()); - } catch (Exception e) { - e.printStackTrace(); - } - } - */ + /* + * MiniClient client = new MiniClient(); + * System.out.println("Addr: "+addr); + * client.setConnectorEndpoint(addr); + * + * HashMap headers = new HashMap(); + * for (MessageInfo mInfo : messageInfos) { + * try { + * Gson gson = new Gson(); + * ClientResponse result = client.sendRequest("POST", + * "SBFManager/bots/" + mInfo.getBotName() + "/trigger/intent", + * gson.toJson(mInfo), + * MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); + * System.out.println(result.getResponse()); + * } catch (Exception e) { + * e.printStackTrace(); + * } + * } + */ } } - if(!found){ - return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot "+bot+".").build(); + if (!found) { + return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot " + bot + ".") + .build(); } - }else{ - return Response.status(Status.NOT_FOUND).entity("Bot "+bot+" not found.").build(); + } else { + return Response.status(Status.NOT_FOUND).entity("Bot " + bot + " not found.").build(); } - } catch (Exception e) { e.printStackTrace(); @@ -3223,64 +3463,69 @@ public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam(" Gson gson = new Gson(); return Response.ok().entity(gson.toJson(answerMsg)).build(); } - + @GET @Path("/{bot}/{organization}/{channel}/file/{fileId}") @Produces(MediaType.APPLICATION_OCTET_STREAM) @ApiOperation(value = "Download file", produces = MediaType.APPLICATION_OCTET_STREAM) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "File downloaded successfully"), - @ApiResponse(code = 404, message = "File not found"), - @ApiResponse(code = 500, message = "Internal server error")}) - public Response getRESTfulChatFile(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, @PathParam("fileId") String fileId) { - RESTfulChatResponse answerMsg = null; + @ApiResponses(value = { + @ApiResponse(code = 200, message = "File downloaded successfully"), + @ApiResponse(code = 404, message = "File not found"), + @ApiResponse(code = 500, message = "Internal server error") }) + public Response getRESTfulChatFile(@PathParam("bot") String bot, @PathParam("organization") String organization, + @PathParam("channel") String channel, @PathParam("fileId") String fileId) { + RESTfulChatResponse answerMsg = null; try { - String path = bot+organization+channel+"-"+fileId; + String path = bot + organization + channel + "-" + fileId; CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); - CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry); + CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), + pojoCodecRegistry); MongoClientSettings settings = MongoClientSettings.builder() .uuidRepresentation(UuidRepresentation.STANDARD) - .applyConnectionString(new ConnectionString(service.mongoUri)) + .applyConnectionString(new ConnectionString(this.service.mongoUri)) .codecRegistry(codecRegistry) .build(); - + // Create a new client and connect to the server MongoClient mongoClient = MongoClients.create(settings); - + try { - MongoDatabase database = mongoClient.getDatabase(service.mongoDB); + MongoDatabase database = mongoClient.getDatabase(this.service.mongoDB); GridFSBucket gridFSBucket = GridFSBuckets.create(database, "files"); gridFSBucket.find(Filters.empty()); ObjectId oId = new ObjectId(fileId); BsonObjectId bId = new BsonObjectId(oId); GridFSFile file = gridFSBucket.find(Filters.eq(bId)).first(); if (file == null) { - return Response.status(Response.Status.NOT_FOUND).entity("File with ID "+fileId+" not found").build(); + return Response.status(Response.Status.NOT_FOUND) + .entity("File with ID " + fileId + " not found").build(); } String extension = ""; - if(file.getFilename().contains("json")){ + if (file.getFilename().contains("json")) { extension = ".json"; - } else if (file.getFilename().contains("pdf")){ + } else if (file.getFilename().contains("pdf")) { extension = ".pdf"; } Response.ResponseBuilder response = Response.ok(file.getFilename() + extension); response.header("Content-Disposition", "attachment; filename=\"" + file.getFilename() + "\""); - if(file.getFilename().contains("json")){ + if (file.getFilename().contains("json")) { response.header("Content-Type", "application/json"); - } else if (file.getFilename().contains("pdf")){ + } else if (file.getFilename().contains("pdf")) { response.header("Content-Type", "application/pdf"); } // Download the file to a ByteArrayOutputStream String contentType = ""; - if(file.getFilename().contains("json")){ + if (file.getFilename().contains("json")) { contentType = "application/json"; - } else if (file.getFilename().contains("pdf")){ + } else if (file.getFilename().contains("pdf")) { contentType = "application/pdf"; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); gridFSBucket.downloadToStream(file.getObjectId(), baos); - return Response.ok(baos.toByteArray(), MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=\"" + file.getFilename() + "\"").build(); + return Response.ok(baos.toByteArray(), MediaType.APPLICATION_OCTET_STREAM) + .header("Content-Disposition", "attachment; filename=\"" + file.getFilename() + "\"") + .build(); } catch (MongoException me) { System.err.println(me); } finally { @@ -3288,21 +3533,20 @@ public Response getRESTfulChatFile(@PathParam("bot") String bot, @PathParam("org mongoClient.close(); } - File file = new File(path); if (!file.exists()) { return Response.status(Status.NOT_FOUND).entity("File not found.").build(); } String contentType = ""; - if(path.contains("json")){ + if (path.contains("json")) { contentType = "application/json"; - } else if (path.contains("pdf")){ + } else if (path.contains("pdf")) { contentType = "application/pdf"; } return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM) - .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"") - .header("Content-Type", contentType) - .build(); + .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"") + .header("Content-Type", contentType) + .build(); } catch (Exception e) { e.printStackTrace(); @@ -3322,26 +3566,25 @@ public Response getRESTfulChatFile(@PathParam("bot") String bot, @PathParam("org public Response getRESTfulChatFileIds(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel) { - if (userFileIds.containsKey(organization + "-" +channel)) { - JSONObject r = userFileIds.get(organization + "-" +channel); - userFileIds.remove(organization + "-" +channel); - if(r.containsKey("error")){ + if (userFileIds.containsKey(organization + "-" + channel)) { + JSONObject r = userFileIds.get(organization + "-" + channel); + userFileIds.remove(organization + "-" + channel); + if (r.containsKey("error")) { return Response.status(Status.INTERNAL_SERVER_ERROR).entity(r).build(); } JSONObject input = new JSONObject(); input.put("message", "!files"); Response response = handleRESTfulChat(bot, organization, channel, input.toString()); JSONParser p = new JSONParser(0); - try{ + try { JSONObject answer = (JSONObject) p.parse(response.getEntity().toString()); - answer.put("files",r); - return Response.status(Status.OK).entity(answer.toString()).build(); - } catch (Exception e ) - { + answer.put("files", r); + return Response.status(Status.OK).entity(answer.toString()).build(); + } catch (Exception e) { e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(r).build(); } - + } else { return Response.status(Status.NOT_FOUND).entity(new JSONObject()).build(); } @@ -3358,31 +3601,30 @@ public Response getRESTfulChatFileIds(@PathParam("bot") String bot, public Response updateRESTfulChatFileIds( @PathParam("channel") String channel, @FormDataParam("files") byte[] files) { String content = new String(files); - if(emailToChannel.containsKey(channel)){ + if (emailToChannel.containsKey(channel)) { // kinda abusing code here channel = emailToChannel.get(channel); } - if(content.equals(null)){ + if (content.equals(null)) { return Response.status(Status.BAD_REQUEST).entity("Something went wrong.").build(); } - try{ + try { JSONObject o = (JSONObject) (new JSONParser(JSONParser.MODE_PERMISSIVE)).parse(content); userFileIds.put(channel, o); Messenger m = channelToMessenger.get(channel); - if(m == null){ + if (m == null) { m = channelToMessenger.get(channel.split("-")[1]); } for (String key : o.keySet()) { m.addVariable(channel, key, o.getAsString(key)); } return Response.status(Status.BAD_REQUEST).entity("cool").build(); - } catch (Exception e ){ + } catch (Exception e) { e.printStackTrace(); return Response.status(Status.BAD_REQUEST).entity(new JSONObject()).build(); } } - private String getFileType(InputStream uploadedInputStream) throws IOException { Tika tika = new Tika(); return tika.detect(uploadedInputStream); diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java index 4d489ac5..db19fb6e 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java @@ -4,6 +4,7 @@ import org.json.JSONObject; import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; +import i5.las2peer.services.socialBotManagerService.nlu.Entity; import java.io.BufferedReader; import java.io.File; @@ -18,6 +19,9 @@ public abstract class ChatMediator { private ChatMessageCollector messageCollector; + // Used for storing the conversation path + //private ChatMessageCollector conversationPathCollector; + protected String authToken; public ChatMediator(String authToken) { @@ -33,7 +37,7 @@ public ChatMediator(String authToken) { * replies to it later on. * @param id An ID for the sent chat message, e.g. to be able to recognize */ - public abstract void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id); + public abstract Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id); public abstract void editMessage(String channel, String messageId, String message, Optional id); @@ -59,8 +63,8 @@ public void updateBlocksMessageToChannel(String channel, String blocks, String a * @param channel A channel ID valid for interacting with the chat service's API * @param text The content of the chat message */ - public void sendMessageToChannel(String channel, String text, String type ) { - sendMessageToChannel(channel, text, null,type); + public Boolean sendMessageToChannel(String channel, String text, String type ) { + return sendMessageToChannel(channel, text, null,type); } /** * Sends a chat message to a channel. @@ -70,8 +74,8 @@ public void sendMessageToChannel(String channel, String text, String type ) { * @param hashMap An ID for the sent chat message, e.g. to be able to recognize * replies to it later on. */ - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type) { - sendMessageToChannel(channel, text, hashMap,type,null); + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type) { + return sendMessageToChannel(channel, text, hashMap,type,null); } /** @@ -146,6 +150,14 @@ public void sendFileMessageToChannel(String channel, String fileBody, String fil */ public abstract Vector getMessages(); + /** + * Gets all messages the mediator has received or sent + * + * @return A Vector containing all ChatMessages received or sent + * + */ + //public abstract Vector getConversationPath(); + /** * Gets the IM channel ID for the user registered under the given E-Mail * address. @@ -204,7 +216,6 @@ public String getAuthToken() { // used to check whether given token is the real one public boolean checkToken(String authToken) { - System.out.println(authToken + " " + this.authToken); if (authToken.equals(this.authToken)) { return true; } else @@ -215,5 +226,9 @@ public ChatMessageCollector getMessageCollector() { return messageCollector; } + // public ChatMessageCollector getConversationPathCollector() { + // return conversationPathCollector; + // } + public abstract void close(); } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java index 7c8ab9a0..79635726 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java @@ -27,7 +27,8 @@ public ChatMessageCollector() { } public void addMessage(ChatMessage message) { - System.out.println("Message added: Channel: " + message.getChannel() + ", User: " + message.getUser()); + // System.out.println("Message added: Channel: " + message.getChannel() + ", + // User: " + message.getUser()); this.messages.add(message); } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java index 8ed7e37b..581abe8a 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java @@ -5,6 +5,10 @@ public class InteractiveChatElement { private String label; private boolean isFile; + public InteractiveChatElement(String intent, String label) { + this(intent, label, false); + } + public InteractiveChatElement(String intent, String label, boolean isFile){ this.intent = intent; this.label = label; diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java index f98dc533..0ff15e95 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java @@ -47,15 +47,18 @@ protected String getBotId() throws AuthTokenException{ } @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { HashMap args = new HashMap(); args.put("messages[0][touserid]", channel); args.put("messages[0][text]", text); + Boolean messageSent = Boolean.FALSE; try { sendRequest(domainName, "core_message_send_instant_messages", args); + messageSent = Boolean.TRUE; } catch (IOException e) { e.printStackTrace(); } + return messageSent; } @Override diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java index 677a1ff3..4e21b945 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java @@ -40,7 +40,8 @@ public MoodleForumMediator(String authToken) throws IOException, AuthTokenExcept } @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + Boolean messageSent = Boolean.FALSE; try { // Get sequence IDs and find origin post HashMap args = new HashMap(); @@ -79,11 +80,13 @@ public void sendMessageToChannel(String channel, String text, HashMap statements) { diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java index 7f60bcd7..93011d26 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java @@ -2,7 +2,6 @@ import java.io.File; import java.util.HashMap; -import java.util.List; import java.util.Optional; import java.util.Vector; @@ -23,9 +22,10 @@ public RESTfulChatMediator(String authToken) { } @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { RESTfulChatResponse rcr = new RESTfulChatResponse(text, hashMap,type); chatsession.put(channel, rcr); + return Boolean.TRUE; } @Override diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java index 5d1727b3..640edba9 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java @@ -25,7 +25,6 @@ public void handle(String fileBody, String fileName, String fileType, //cm.setDomain(this.getDomain()); this.addMessage(cm); - System.out.println("Message added."); } catch (Exception e) { e.printStackTrace(); } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java index 81e429f8..c82f9091 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java @@ -15,7 +15,6 @@ import java.util.*; import java.util.logging.Level; -import javax.print.attribute.standard.Media; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; @@ -60,9 +59,6 @@ import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; import i5.las2peer.services.socialBotManagerService.nlu.RasaNlu; - -import javax.ws.rs.core.MediaType; - public class RocketChatMediator extends ChatMediator implements ConnectListener, LoginListener, RoomListener.GetRoomListener, SubscribeListener, GetSubscriptionListener, SubscriptionListener { @@ -73,6 +69,7 @@ public class RocketChatMediator extends ChatMediator implements ConnectListener, private String password; private String token; private RocketChatMessageCollector messageCollector = new RocketChatMessageCollector(); + //private RocketChatMessageCollector conversationPathCollector = new RocketChatMessageCollector(); private HashSet activeSubscriptions = null; private RasaNlu rasa; private SQLDatabase database; @@ -106,6 +103,7 @@ public RocketChatMediator(String authToken, SQLDatabase database, RasaNlu rasa) RocketChatAPI.LOGGER.setLevel(Level.OFF); this.rasa = rasa; messageCollector.setDomain(url); + //conversationPathCollector.setDomain(url); } public RocketChatMediator(String authToken, SQLDatabase database) { @@ -121,6 +119,7 @@ public RocketChatMediator(String authToken, SQLDatabase database) { client.connect(this); RocketChatAPI.LOGGER.setLevel(Level.OFF); messageCollector.setDomain(url); + //conversationPathCollector.setDomain(url); } private void setAuthData(String authToken){ @@ -150,7 +149,7 @@ public void sendFileMessageToChannel(String channel, File f, String text, Option .bodyPart(filePart); Response response = target.request().header("X-User-Id", client.getMyUserId()).header("X-Auth-Token", token) .post(Entity.entity(multipart, multipart.getMediaType())); - System.out.println(response.getEntity().toString()); + // System.out.println(response.getEntity().toString()); mp.close(); multipart.close(); try { @@ -186,10 +185,10 @@ public void sendFileMessageToChannel(String channel, String fileBody, String fil } @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { System.out.println(text); ChatRoom room = client.getChatRoomFactory().getChatRoomById(channel); - System.out.println("Sending Message to : " + room.getRoomData().getRoomId()); + Boolean messageSent = Boolean.FALSE; if (sendingMessage.get(channel) != null) { while (sendingMessage.get(channel) == true) { @@ -263,6 +262,9 @@ public void onUploadComplete(int arg0, com.rocketchat.core.model.FileObject arg1 } } else { room.sendMessage(newText); + //messageSent = Boolean.TRUE; + //ChatMessage botMessage = new ChatMessage(channel, "assistant", newText); + //conversationPathCollector.addMessage(botMessage); sendingMessage.put(channel, false); } } catch (Exception e) { @@ -273,7 +275,8 @@ public void onUploadComplete(int arg0, com.rocketchat.core.model.FileObject arg1 } }); - + messageSent = Boolean.TRUE; + return messageSent; } @Override @@ -282,6 +285,12 @@ public Vector getMessages() { return messages; } + // @Override + // public Vector getConversationPath() { + // Vector messages = this.conversationPathCollector.getMessages(); + // return messages; + // } + @Override public String getChannelByEmail(String email) { List users = client.getDbManager().getUserCollection().getData(); @@ -505,7 +514,6 @@ protected String getStudentEmail(String userName) { textClientHeader.put("X-Auth-Token", token); ClientResponse r = textClient.sendRequest("GET", "api/v1/users.info?username=" + userName, "", MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, textClientHeader); - System.out.println("response is" + r.getResponse()); JSONObject userObject = new JSONObject(r.getResponse()); JSONArray emails = userObject.getJSONObject("user").getJSONArray("emails"); return emails.getJSONObject(0).getString("address"); @@ -526,12 +534,10 @@ public void onMessage(String arg0, RocketChatMessage message) { synchronized (room) { if (!message.getSender().getUserId().equals(client.getMyUserId())) { String email = getStudentEmail(message.getSender().getUserName()); - System.out.println("Email: " + email); - System.out.println("Message: " + message.getMessage()); Type type = message.getMsgType(); if (type.equals(Type.ATTACHMENT)) { - System.out.println("Handling attachement"); + JSONObject j = message.getRawJsonObject(); String fileType = j.getJSONObject("file").getString("type"); String fileName = j.getJSONObject("file").getString("name"); @@ -544,11 +550,15 @@ public void onMessage(String arg0, RocketChatMessage message) { String fileBody = getFileBase64(client.getMyUserId(), file); messageCollector.handle(message, fileBody, fileName, fileType, 0, getStudentEmail(message.getSender().getUserName())); + //conversationPathCollector.handle(message, fileBody, fileName, fileType, 0, + // getStudentEmail(message.getSender().getUserName())); } else { messageCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); + //conversationPathCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); } } else { messageCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); + //conversationPathCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); } } } @@ -578,6 +588,10 @@ public RocketChatMessageCollector getMessageCollector() { return messageCollector; } + // public RocketChatMessageCollector getConversationPathCollector() { + // return conversationPathCollector; + // } + @Override public void close() { shouldCheckRooms = false; diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java index 91a25241..a5c58101 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java @@ -1,10 +1,5 @@ package i5.las2peer.services.socialBotManagerService.chat; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.Instant; -import java.util.TimeZone; - import org.json.JSONArray; import com.rocketchat.core.model.RocketChatMessage; @@ -17,7 +12,6 @@ public void handle(RocketChatMessage message) { if (type != null) { if (type.equals(Type.TEXT)) { try { - System.out.println("Handling text."); JSONArray emails = message.getSender().getEmails(); // System.out.println(emails.toString()); String rid = message.getRoomId(); @@ -30,7 +24,6 @@ public void handle(RocketChatMessage message) { cm.setDomain(this.getDomain()); this.addMessage(cm); - System.out.println("Message added."); } catch (Exception e) { e.printStackTrace(); } @@ -47,14 +40,12 @@ public void handle(RocketChatMessage message, int role, String email) { if (type != null) { if (type.equals(Type.TEXT)) { try { - System.out.println("Handling text."); JSONArray emails = message.getSender().getEmails(); // System.out.println(emails.toString()); String rid = message.getRoomId(); String user = message.getSender().getUserName(); String msg = replaceUmlaute(message.getMessage()); ChatMessage cm = new ChatMessage(rid, user, msg); - System.out.println("Email of user is " + email); cm.setEmail(email); cm.setRole(role); // timestamp @@ -63,20 +54,18 @@ public void handle(RocketChatMessage message, int role, String email) { cm.setDomain(this.getDomain()); this.addMessage(cm); - System.out.println("Message added."); } catch (Exception e) { e.printStackTrace(); } }else if(type.equals(Type.MESSAGE_EDITED)){ try { - System.out.println("Handling edited message."); + JSONArray emails = message.getSender().getEmails(); // System.out.println(emails.toString()); String rid = message.getRoomId(); String user = message.getSender().getUserName(); String msg = replaceUmlaute(message.getMessage()); ChatMessage cm = new ChatMessage(rid, user, msg); - System.out.println("Email of user is " + email); cm.setEmail(email); cm.setRole(role); // timestamp @@ -85,7 +74,6 @@ public void handle(RocketChatMessage message, int role, String email) { cm.setDomain(this.getDomain()); this.addMessage(cm); - System.out.println("Edited message added."); } catch (Exception e) { e.printStackTrace(); } @@ -104,15 +92,15 @@ public void handle(RocketChatMessage message, String fileBody, String fileName, if (type != null) { if (type.equals(Type.ATTACHMENT)) { try { - System.out.println("Handling Attachment."); + JSONArray emails = message.getSender().getEmails(); - System.out.println("rcket message is " + message); + String rid = message.getRoomId(); System.out.println(rid); String user = message.getSender().getUserName(); String msg = replaceUmlaute(fileName); ChatMessage cm = new ChatMessage(rid, user, msg, fileName, fileType, fileBody); - System.out.println("Email of user is " + email); + cm.setEmail(email); cm.setRole(role); @@ -123,7 +111,6 @@ public void handle(RocketChatMessage message, String fileBody, String fileName, cm.setDomain(this.getDomain()); this.addMessage(cm); - System.out.println("Message added."); } catch (Exception e) { e.printStackTrace(); } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java index 1cde8f44..0eb6c83a 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java @@ -40,8 +40,6 @@ import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import com.slack.api.methods.request.bots.*; - import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; @@ -139,8 +137,9 @@ public void updateBlocksMessageToChannel(String channel, String blocks, String a } @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { MessageBuilder msg = Message.builder().id(System.currentTimeMillis()).channel(channel).text(text); + Boolean messageSent = Boolean.FALSE; if (id.isPresent()) { msg.id(Long.parseLong(id.get())); } @@ -156,6 +155,7 @@ public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { System.out.println("send plain message to telegram channel " + channel + ", size: " + text.length()); assert channel != null; @@ -210,7 +207,8 @@ public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { + public Boolean sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { String repositoryFullName = channel.split("#")[0]; int number = Integer.parseInt(channel.split("#")[1]); + Boolean messageSent = Boolean.FALSE; try { GitHub instance = this.gitHubAppHelper.getGitHubInstance(repositoryFullName); if (instance != null) { // post comment (in GitHub a pull request also seems to be an issue) instance.getRepository(repositoryFullName).getIssue(number).comment(text); + messageSent = Boolean.TRUE; } } catch (IOException e) { e.printStackTrace(); } + return messageSent; } @Override diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ConversationMessage.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ConversationMessage.java new file mode 100644 index 00000000..8d4bb666 --- /dev/null +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ConversationMessage.java @@ -0,0 +1,32 @@ +package i5.las2peer.services.socialBotManagerService.model; + +public class ConversationMessage { + String conversationId; + String role; + String content; + + public ConversationMessage(String conversationId, String role, String content) { + this.conversationId = conversationId; + this.role = role; + this.content = content; + } + + public String getConversationId() { + return conversationId; + } + public void setConversationId(String conversationId) { + this.conversationId = conversationId; + } + public String getRole() { + return role; + } + public void setRole(String role) { + this.role = role; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } +} diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java index e236509a..e8ef1fa1 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java @@ -3,26 +3,41 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Random; +import java.util.UUID; public class IncomingMessage { String intentKeyword; String intentLabel; String followupMessageType; String entityKeyword; - String NluID; - boolean containsFile; + String NluID; + boolean containsFile; String triggeredFunctionId; - HashMap triggerEntity; + HashMap triggerEntity; String fileURL; String errorMessage; String type; + boolean openAIEnhance; + boolean freezeMessageSend; + + /** + * Conversation Id for the message + * A conversation is a sequence of messages between the bot and the user. A + * conversation ends if there are no followup messages + */ + UUID conversationId; ArrayList responses; - // Intent keywords used as keys + /* + * List of followup messages. Followup messages are messages that are connected + * to + * the current message via a leadsTo relation. + * The key is the intent keyword that triggers the + * followup message. + */ HashMap followupMessages; - private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, { new String("ö"), "oe" }, { new String("ß"), "ss" } }; @@ -38,28 +53,39 @@ public static String replaceUmlaute(String orig) { } - public IncomingMessage(String intent, String NluID, Boolean containsFile,ArrayList responses, String fileURL, String errorMessage, String type,String intentLabel, String followupType) { - if(intent != "") { + public IncomingMessage(String intent, String NluID, Boolean containsFile, ArrayList responses, + String fileURL, String errorMessage, String type, String intentLabel, String followupType) { + if (intent != "") { this.intentKeyword = replaceUmlaute(intent); - } else intentKeyword = ""; + } else + intentKeyword = ""; this.followupMessages = new HashMap(); this.responses = responses; this.containsFile = containsFile; - if (intentKeyword.equals("0") && containsFile){ + if (intentKeyword.equals("0") && containsFile) { intentKeyword = "anyFile"; } - if(NluID == ""){ - this.NluID = ""; - } else this.NluID = NluID; + if (NluID == "") { + this.NluID = ""; + } else + this.NluID = NluID; this.fileURL = fileURL; - this.errorMessage = errorMessage; - this.triggerEntity = new HashMap(); + this.errorMessage = errorMessage; + this.triggerEntity = new HashMap(); this.type = type; this.followupMessageType = followupType; this.intentLabel = intentLabel; } + public UUID getConversationId() { + return conversationId; + } + + public void setConversationId(UUID conversationId) { + this.conversationId = conversationId; + } + public String getIntentKeyword() { return intentKeyword; } @@ -71,19 +97,32 @@ public String getEntityKeyword() { public void setEntityKeyword(String entityKeyword) { this.entityKeyword = entityKeyword; } - + public String getNluID() { return NluID; } - + + /** + * Followup messages are messages that are connected + * to the current message via a leadsTo relation. + * + * @return A HashMap of followup messages. The key is the intent keyword that + * triggers the followup message. + */ public HashMap getFollowingMessages() { return followupMessages; } + /** + * Adds a followup message to the list of followup messages. The intentKeyword + * + * @param intentKeyword The intent keyword that triggers the followup message + * @param msg The followup message + */ public void addFollowupMessage(String intentKeyword, IncomingMessage msg) { String[] intentList = intentKeyword.split(","); for (String intent : intentList) { - if (intent.equals("") && msg.containsFile){ + if (intent.equals("") && msg.containsFile) { this.followupMessages.put(replaceUmlaute(intent).replaceAll("\\s+", "") + "anyFile", msg); } else { this.followupMessages.put(replaceUmlaute(intent).replaceAll("\\s+", ""), msg); @@ -92,7 +131,6 @@ public void addFollowupMessage(String intentKeyword, IncomingMessage msg) { // (this.followupMessages.put(replaceUmlaute(intentKeyword), msg); } - public String getResponse(Random random) { if (responses.isEmpty()) { return null; @@ -100,7 +138,7 @@ public String getResponse(Random random) { return responses.get(random.nextInt(responses.size())); } } - + public ArrayList getResponseArray() { if (responses.isEmpty()) { return null; @@ -120,26 +158,34 @@ public String getTriggeredFunctionId() { public boolean expectsFile() { return this.containsFile; } - + public String getFileURL() { return fileURL; } + + public boolean getOpenAIEnhance() { + return this.openAIEnhance; + } + + public void setOpenAIEnhance(boolean flag) { + this.openAIEnhance = flag; + } public String getErrorMessage() { return errorMessage; } - - public void setTriggeredFunctionId(String functionId){ - this.triggeredFunctionId = functionId; - } - + public String getTriggerEntity(IncomingMessage m){ - return this.triggerEntity.get(m); - } + return this.triggerEntity.get(m); + } + + public void setTriggeredFunctionId(String functionId) { + this.triggeredFunctionId = functionId; + } - public void addTriggerEntity(IncomingMessage m,String triggerEntity){ - this.triggerEntity.put(m, triggerEntity); - } + public void addTriggerEntity(IncomingMessage m, String triggerEntity) { + this.triggerEntity.put(m, triggerEntity); + } public String getType() { return type; @@ -153,18 +199,19 @@ public String getIntentLabel() { return intentLabel; } - public void setIntentLabel(String intentLabel) { this.intentLabel = intentLabel; } - public String getFollowupMessageType() { return followupMessageType; } - public void setFollowupMessageType(String followupMessageType) { this.followupMessageType = followupMessageType; } + + public void setFreezeMessageSend(boolean flag) { + this.freezeMessageSend = flag; + } } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java index 17b47a98..170851cb 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java @@ -1,6 +1,7 @@ package i5.las2peer.services.socialBotManagerService.model; import java.util.Collection; +import java.util.UUID; import i5.las2peer.services.socialBotManagerService.chat.ChatMessage; import i5.las2peer.services.socialBotManagerService.nlu.Intent; @@ -14,6 +15,7 @@ public class MessageInfo { String serviceAlias; boolean contextWithService; Collection recognizedEntities; + String conversationId; String messengerName = ""; @@ -41,6 +43,20 @@ public MessageInfo(ChatMessage message, Intent intent, String triggeredFunctionI this.messengerName = messengerName; } + public MessageInfo(ChatMessage message, Intent intent, String triggeredFunctionId, String botName, + String serviceAlias, boolean contextWithService, Collection recognizedEntities, + String messengerName, UUID conversationId) { + this.message = message; + this.intent = intent; + this.triggeredFunctionId = triggeredFunctionId; + this.botName = botName; + this.serviceAlias = serviceAlias; + this.contextWithService = contextWithService; + this.recognizedEntities = recognizedEntities; + this.messengerName = messengerName; + this.conversationId = conversationId.toString(); + } + public ChatMessage getMessage() { return this.message; } @@ -77,6 +93,10 @@ public String getMessengerName() { return messengerName; } + public String getConversationId() { + return conversationId; + } + public void setMessengerName(String messengerName) { this.messengerName = messengerName; } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java index 0852cdc9..95938174 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java @@ -18,11 +18,10 @@ import java.util.Optional; import java.util.Random; import java.util.Vector; - import javax.websocket.DeploymentException; - -import com.google.gson.Gson; - +import i5.las2peer.api.Context; +import i5.las2peer.api.logging.MonitoringEvent; +import i5.las2peer.services.socialBotManagerService.SocialBotManagerService; import i5.las2peer.services.socialBotManagerService.chat.*; import i5.las2peer.services.socialBotManagerService.chat.github.GitHubAppHelper; import i5.las2peer.services.socialBotManagerService.chat.github.GitHubIssueMediator; @@ -32,6 +31,9 @@ import i5.las2peer.services.socialBotManagerService.nlu.Intent; import i5.las2peer.services.socialBotManagerService.nlu.RasaNlu; import i5.las2peer.services.socialBotManagerService.parser.ParseBotException; +import net.minidev.json.JSONObject; + +import java.util.UUID; public class Messenger { private String name; @@ -46,43 +48,90 @@ public class Messenger { */ private ChatService chatService; - // Key: intent keyword - private HashMap knownIntents; + /** + * Contains all IncomingMessages that are reachable from the start state + * Key: intent keyword + * Value: IncomingMessage object + */ + private HashMap rootChildren; + + /** + * Used for keeping conversation state per channel + * Key: channel ID + * Value: current state of the conversation (last IncomingMessage) + * + */ + private HashMap> conversationMap; // Used for keeping conversation state per channel private HashMap stateMap; - // Used for keeping remembering entities during conversation state per channel + + /** + * Used to determine if a new conversation was started. A new conversation + * starts + * if no followup messages are found for the current state and the context of + * the last function call is closed. + * (Note that the bot might stay infinitely long in the same state if the + * context is not closed) + */ + private HashMap previousStateInConversation = new HashMap<>(); + private HashMap previousStateInConversationBackup = new HashMap<>(); + + /** + * Used for keeping remembering entities during conversation state per channel + * Key: channel ID + * Value: Collection of entities that were recognized during the conversation + */ private HashMap> recognizedEntities; - // Used for keeping context between assessment and non-assessment states - // Key is the channelId + /** + * Used for keeping context between assessment and non-assessment states + * Key: channel ID + * Value: current NLU model ID + */ private HashMap currentNluModel; - // Used to know to which Function the received intents/messages are to be sent - // Is additionally used to check if we are currently communicating with a - // service(if set, then yes otherwise no) + /** + * Used to know to which Function the received intents/messages are to be sent + * Is additionally used to check if we are currently communicating with a + * service(if set, then yes otherwise no) + * Key: channel ID + * Value: current triggered function name + */ private HashMap triggeredFunction; - // Keep up with how many times a default message was given out in a conversation - // state - private HashMap defaultAnswered; - + /** + * Key: channel ID + * Value: number of times a default message was given out in a conversation + * state + */ + private HashMap defaultAnswerCount; + /** + * Used to store the current state of the conversation in case a command is + * triggered. Whenever this happens the current state is stored in this map and + * we jump into the command's conversation path. After the command is finished + * the state is restored. + * Key: channel ID + * Value: current state of the conversation (last IncomingMessage) + */ private HashMap storedSession; - private HashMap> userVariables; + private HashMap> userVariables; + private Context l2pContext; private Random random; private SQLDatabase db; - public Messenger(String id, String chatService, String token, SQLDatabase database) + public Messenger(String id, String chatService, String token, SQLDatabase database, Context l2pContext) throws IOException, DeploymentException, ParseBotException, AuthTokenException { + this.l2pContext = l2pContext; -// this.rasa = new RasaNlu(rasaUrl); -// this.rasaAssessment = new RasaNlu(rasaAssessmentUrl); + // this.rasa = new RasaNlu(rasaUrl); + // this.rasaAssessment = new RasaNlu(rasaAssessmentUrl); this.db = database; // Chat Mediator this.chatService = ChatService.fromString(chatService); - switch (this.chatService) { + switch (this.chatService) { case SLACK: this.chatMediator = new SlackChatMediator(token); break; @@ -117,24 +166,24 @@ public Messenger(String id, String chatService, String token, SQLDatabase databa break; case RESTful_Chat: this.chatMediator = new RESTfulChatMediator(token); - System.out.println("RESTful Chat selected"); + break; default: throw new ParseBotException("Unimplemented chat service: " + chatService); - } - System.out.println("no exceptions"); + } this.name = id; - this.knownIntents = new HashMap(); + this.rootChildren = new HashMap(); + this.conversationMap = new HashMap>(); this.stateMap = new HashMap(); this.recognizedEntities = new HashMap>(); this.random = new Random(); // Initialize the assessment setup this.currentNluModel = new HashMap(); this.triggeredFunction = new HashMap(); - this.defaultAnswered = new HashMap(); + this.defaultAnswerCount = new HashMap(); this.storedSession = new HashMap(); - this.userVariables = new HashMap>(); + this.userVariables = new HashMap>(); } public String getName() { @@ -145,15 +194,27 @@ public ChatService getChatService() { return chatService; } + public HashMap> getConversationMap() { + return conversationMap; + } + + public HashMap getStateMap() { + return stateMap; + } + + public void updateConversationInConversationMap(String channel, Collection conversation) { + conversationMap.put(channel, conversation); + } + public void addMessage(IncomingMessage msg) { if (msg.getIntentKeyword().contains("defaultX")) { - this.knownIntents.put("defaultX", msg); + this.rootChildren.put("defaultX", msg); } else - this.knownIntents.put(msg.getIntentKeyword(), msg); + this.rootChildren.put(msg.getIntentKeyword(), msg); } - public HashMap getKnownIntents() { - return this.knownIntents; + public HashMap getRootChildren() { + return this.rootChildren; } public ChatMediator getChatMediator() { @@ -161,16 +222,16 @@ public ChatMediator getChatMediator() { } public IncomingMessage checkDefault(IncomingMessage state, ChatMessage message) { - if (this.knownIntents.get("defaultX") != null && Integer.valueOf( - this.knownIntents.get("defaultX").getIntentKeyword().split("defaultX")[1]) > this.defaultAnswered + if (this.rootChildren.get("defaultX") != null && Integer.valueOf( + this.rootChildren.get("defaultX").getIntentKeyword().split("defaultX")[1]) > this.defaultAnswerCount .get(message.getChannel())) { - IncomingMessage newState = this.knownIntents.get("defaultX"); + IncomingMessage newState = this.rootChildren.get("defaultX"); newState.followupMessages = state.followupMessages; state = newState; - this.defaultAnswered.put(message.getChannel(), this.defaultAnswered.get(message.getChannel()) + 1); + this.defaultAnswerCount.put(message.getChannel(), this.defaultAnswerCount.get(message.getChannel()) + 1); } else { - state = this.knownIntents.get("default"); - this.defaultAnswered.put(message.getChannel(), 0); + state = this.rootChildren.get("default"); + this.defaultAnswerCount.put(message.getChannel(), 0); } return state; } @@ -178,7 +239,7 @@ public IncomingMessage checkDefault(IncomingMessage state, ChatMessage message) private void addEntityToRecognizedList(String channel, Collection entities) { Collection recognizedEntitiesNew = recognizedEntities.get(channel); - if(recognizedEntitiesNew != null){ + if (recognizedEntitiesNew != null) { for (Entity entity : entities) { recognizedEntitiesNew.add(entity); } @@ -199,59 +260,50 @@ private void addEntityToRecognizedList(String channel, Collection entiti */ public void setContextToBasic(String channel, String userid) { + triggeredFunction.remove(channel); IncomingMessage state = this.stateMap.get(channel); - for(String key : state.getFollowingMessages().keySet()){ - System.out.println(key); + this.previousStateInConversationBackup.remove(channel); + + if (state == null) { + this.previousStateInConversation.remove(channel); + return; } - if (state != null) { - if (state.getFollowingMessages() == null || state.getFollowingMessages().size() == 0) { - System.out.println("Conversation flow ended now"); - if(storedSession.containsKey(channel)){ - stateMap.put(channel, storedSession.get(channel)); - state = storedSession.get(channel); - storedSession.remove(channel); - System.out.println("Restoring session"); - String response = state.getResponse(random); - if (response != null && !response.equals("")) { - System.out.println("Found old message"); - - this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, response), "text"); - } - } - } else if (state.getFollowingMessages().get("") != null) { - // check whether bot action needs to be triggered without user input - System.out.println("Triggering next message as empty leadsTo found"); - state = state.getFollowingMessages().get(""); - stateMap.put(channel, state); - if(!state.getResponse(random).equals("")){ - if(this.chatService == ChatService.RESTful_Chat && state.getFollowingMessages() != null && !state.getFollowingMessages().isEmpty() ){ - this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, state.getResponse(random)), state.getFollowingMessages(),state.getFollowupMessageType()); - - } else { - this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, state.getResponse(random)), "text"); - - } - } - /* if (state.getResponse(random).triggeredFunctionId != null - && !state.getResponse(random).triggeredFunctionId.equals("")) { - ChatMessage chatMsg = new ChatMessage(channel, userid, "Empty Message"); - this.triggeredFunction.put(channel, state.getResponse(random).triggeredFunctionId); - this.chatMediator.getMessageCollector().addMessage(chatMsg); - }*/ - } else { - // If only message to be sent + + if (state.getFollowingMessages() == null || state.getFollowingMessages().size() == 0) { + // no other messages to follow + System.out.println("No following messages"); + if (storedSession.containsKey(channel)) { + stateMap.put(channel, storedSession.get(channel)); + state = storedSession.get(channel); + storedSession.remove(channel); + String response = state.getResponse(random); - if( response != null && !response.equals("")) - { // actually not necessary, as the message contained in the incoming message should have been sent before the service call, thus not after the call is done - // this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, response), state.getFollowingMessages(), state.getFollowupMessageType(),Optional.of(userid)); - } - if(state.getFollowingMessages().size()== 0){ - this.stateMap.remove(channel); + if (response != null && !response.equals("") && !state.getOpenAIEnhance()) { + this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, response), + state.getFollowingMessages(), state.getFollowupMessageType(), Optional.of(userid)); } + } else { + System.out.println("No session state found"); + this.stateMap.remove(channel); + this.previousStateInConversation.remove(channel); } } else { + + // If only message to be sent + String response = state.getResponse(random); + if (response != null && !response.equals("") && !state.freezeMessageSend) { + this.chatMediator.sendMessageToChannel(channel, replaceVariables(channel, response), + state.getFollowingMessages(), state.getFollowupMessageType(), Optional.of(userid)); + state.setFreezeMessageSend(false); + } + if (state.getFollowingMessages().size() == 0) { + // no other messages to follow + this.stateMap.remove(channel); + this.previousStateInConversation.remove(channel); + + } } } @@ -279,19 +331,19 @@ public void addVariable(String channel, String key, String value) { public String replaceVariables(String channel, String text) { HashMap variables = this.getUserVariables().get(channel); - if(variables != null ){ - for (String key : variables.keySet()){ - String composed = "["+key+"]"; + if (variables != null) { + for (String key : variables.keySet()) { + String composed = "[" + key + "]"; text = text.replace(composed, variables.get(key)); } } String split[] = text.split("\\["); - for (int i = 1; i < split.length ; i++){ + for (int i = 1; i < split.length; i++) { String name = split[i].split("\\]")[0]; String val = getEntityValue(channel, name); - if(!val.equals("")){ - String composed = "["+name+"]"; + if (!val.equals("")) { + String composed = "[" + name + "]"; text = text.replace(composed, val); } @@ -307,193 +359,161 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { try { // // If a channel/user pair still isn't assigned to a state, assign it to null // if (this.stateMap.get(message.getChannel()) == null) { - // HashMap initMap = new HashMap(); - // initMap.put(message.getUser(), null); - // this.stateMap.put(message.getChannel(), initMap); + // HashMap initMap = new HashMap(); + // initMap.put(message.getUser(), null); + // this.stateMap.put(message.getChannel(), initMap); // } - - // If a channel/user pair still isn't assigned to a NLU Model, assign it to the Model 0 + + // If a channel/user pair still isn't assigned to a NLU Model, assign it to the + // Model 0 if (this.currentNluModel.get(message.getChannel()) == null) { this.currentNluModel.put(message.getChannel(), "0"); } - - // If channel/user pair is not assigned to a triggered function, assign it to null -// if (this.triggeredFunction.get(message.getChannel()) == null) { -// HashMap initMap = new HashMap(); -// initMap.put(message.getUser(), null); -// this.triggeredFunction.put(message.getChannel(), initMap); -// } - + + // If channel/user pair is not assigned to a triggered function, assign it to + // null + // if (this.triggeredFunction.get(message.getChannel()) == null) { + // HashMap initMap = new HashMap(); + // initMap.put(message.getUser(), null); + // this.triggeredFunction.put(message.getChannel(), initMap); + // } + UUID conversationId = null; + Boolean messageSent = Boolean.FALSE; + String botMessage = ""; if (!this.userVariables.containsKey(message.getChannel())) { - this.userVariables.put(message.getChannel(), new HashMap()); - } - - if (this.defaultAnswered.get(message.getChannel()) == null) { - this.defaultAnswered.put(message.getChannel(), 0); + this.userVariables.put(message.getChannel(), new HashMap()); } - Intent intent = null; - // Special case: `!` commands - if (message.getText().startsWith("!")) { - - // Split at first occurring whitespace - - String splitMessage[] = message.getText().split("\\s+", 2); - // First word without '!' prefix - String intentKeyword = splitMessage[0].substring(1); - IncomingMessage incMsg = this.knownIntents.get(intentKeyword); - // TODO: Log this? (`!` command with unknown intent / keyword) - if (incMsg == null && !intentKeyword.toLowerCase().equals("exit")) { - if (this.currentNluModel.get(message.getChannel()) == "0") { - continue; - } else { - ArrayList empty = new ArrayList(); - empty.add(""); - incMsg = new IncomingMessage(intentKeyword, "", false,empty,null,"",null, "","text"); - if(splitMessage.length > 1){ - incMsg.setEntityKeyword(incMsg.getIntentKeyword()); - } else { - incMsg.setEntityKeyword("newEntity"); - } - - } - } - if(splitMessage.length > 1){ - incMsg.setEntityKeyword(incMsg.getIntentKeyword()); - } else { - incMsg.setEntityKeyword("newEntity"); - } - String entityKeyword = incMsg.getEntityKeyword(); - String entityValue = null; - // Entity value is the rest of the message. The whole rest - // is in the second element, since we only split it into two parts. - if (splitMessage.length > 1) { - entityValue = splitMessage[1]; - } - - intent = new Intent(intentKeyword, entityKeyword, entityValue); - } else { - if (bot.getRasaServer(currentNluModel.get(message.getChannel())) != null) { - intent = bot.getRasaServer(currentNluModel.get(message.getChannel())) - .getIntent(Intent.replaceUmlaute(message.getText())); - } else { - // if the given id is not fit to any server, pick the first one. (In case - // someone specifies only - // one server and does not give an ID) - intent = bot.getFirstRasaServer().getIntent(Intent.replaceUmlaute(message.getText())); - } + if (this.defaultAnswerCount.get(message.getChannel()) == null) { + this.defaultAnswerCount.put(message.getChannel(), 0); } - System.out.println("found following intent: " + intent.getKeyword()); - try{ - safeEntities(message,bot, intent); + Intent intent = this.determineIntent(message, bot); + try { + safeEntities(message, bot, intent); - } catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); } - + + String encryptedUser = SocialBotManagerService.encryptThisString(message.getUser()); String triggeredFunctionId = null; IncomingMessage state = this.stateMap.get(message.getChannel()); - if(state==null){ - System.out.println("No current state, we will start from scratch."); - if(message.getText().startsWith("!") && this.knownIntents.get(intent.getKeyword()) == null){ - // in case a command is triggered which does not exist - this.chatMediator.sendMessageToChannel(message.getChannel(),"", new HashMap(),"text"); - return; - } - }else{ - System.out.println("Current state: " + state.getIntentKeyword()); + JSONObject remarks = new JSONObject(); + remarks.put("user", encryptedUser); + + conversationId = this.determineConversationId(message.getChannel()); + + remarks.put("in-service-context", this.triggeredFunction.containsKey(message.getChannel())); + + this.l2pContext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_1, remarks.toJSONString(), + conversationId.toString(), + intent.getKeyword(), + bot.getId(), "bot", "start", System.currentTimeMillis()); + this.l2pContext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_1, remarks.toJSONString(), + conversationId.toString(), + intent.getKeyword(), + bot.getId(), "bot", "complete", System.currentTimeMillis()); + + // ________________ start modification of state machine__________________ + + if (state == null && message.getText().startsWith("!") + && this.rootChildren.get(intent.getKeyword()) == null) { + // in case a command is triggered which does not exist + this.chatMediator.sendMessageToChannel(message.getChannel(), "", + new HashMap(), "text"); + return; } - if (state != null && message.getText().startsWith("!") && !state.getFollowingMessages().keySet().contains(intent.getKeyword())) { - if(this.knownIntents.get(intent.getKeyword()) == null){ + + if (state != null && message.getText().startsWith("!") + && !state.getFollowingMessages().keySet().contains(intent.getKeyword())) { + if (this.rootChildren.get(intent.getKeyword()) == null) { // in case a command is triggered which does not exist - this.chatMediator.sendMessageToChannel(message.getChannel(),"", new HashMap(),"text"); - return; + this.chatMediator.sendMessageToChannel(message.getChannel(), "", + new HashMap(), "text"); + return; } if (!intent.getKeyword().equals("exit")) { storedSession.put(message.getChannel(), state); state = null; - } - } + } + } if (state != null && message.getText().startsWith("!") && storedSession.containsKey(message.getChannel())) { - //think about something else to do here - // this.chatMediator.sendMessageToChannel(message.getChannel(),"Dont start command inside command lol","text"); + // think about something else to do here + // this.chatMediator.sendMessageToChannel(message.getChannel(),"Dont start + // command inside command lol","text"); } - - // No conversation state present, starting from scratch + // TODO: Tweak this if (!this.triggeredFunction.containsKey(message.getChannel())) { + // we are not in a function context if (intent.getKeyword().equals("exit")) { recognizedEntities.remove(message.getChannel()); - state = this.knownIntents.get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); + state = this.rootChildren.get(intent.getKeyword()); + this.updateConversationState(message.getChannel(), state, conversationId); if (storedSession.containsKey(message.getCurrMessage())) { storedSession.remove(message.getChannel()); } - } else - // add file case to default if part - if (intent.getConfidence() >= 0.40 || message.getFileName() != null) { + } else if (intent.getConfidence() >= 0.40 || message.getFileName() != null) { // add file case to + // default if part + if (state == null) { + recognizedEntities.put(message.getChannel(), new ArrayList()); + conversationMap.put(message.getChannel(), new ArrayList()); if (message.getFileName() != null) { // check whether incoming message with intent expects file or without intent, // such that // you can send a file regardless the intent - if (this.knownIntents.get(intent.getKeyword()) != null - && this.knownIntents.get(intent.getKeyword()).expectsFile()) { - state = this.knownIntents.get(intent.getKeyword()); + if (this.rootChildren.get(intent.getKeyword()) != null + && this.rootChildren.get(intent.getKeyword()).expectsFile()) { + state = this.rootChildren.get(intent.getKeyword()); // get("0") refers to an empty intent that is accessible from the start state - } else if (this.knownIntents.get("anyFile") != null) { - state = this.knownIntents.get("anyFile"); + } else if (this.rootChildren.get("anyFile") != null) { + state = this.rootChildren.get("anyFile"); } else { - state = this.knownIntents.get("default"); + state = this.rootChildren.get("default"); } - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); recognizedEntities.put(message.getChannel(), intent.getEntities()); } else { - state = this.knownIntents.get(intent.getKeyword()); + state = this.rootChildren.get(intent.getKeyword()); // Incoming Message which expects file should not be chosen when no file was // sent if (state == null || state.expectsFile()) { - if(this.knownIntents.get("0") != null){ - state = this.knownIntents.get("0"); - } else { - if(intent.getEntitieValues().size() > 0){ - state = this.knownIntents.get(intent.getEntitieValues().get(0)); - if(state == null){ - state = this.knownIntents.get("default"); + if (this.rootChildren.get("0") != null) { + state = this.rootChildren.get("0"); + } else { + if (intent.getEntitieValues().size() > 0) { + state = this.rootChildren.get(intent.getEntitieValues().get(0)); + if (state == null) { + state = this.rootChildren.get("default"); } } else { - state = this.knownIntents.get("default"); + state = this.rootChildren.get("default"); } - + } } - System.out.println(intent.getKeyword() + " detected with " + intent.getConfidence() - + " confidence."); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } } else { - // any is a static forward - // TODO include entities of intents - // If there is no next state, stay in the same state if (state.getFollowingMessages() == null || state.getFollowingMessages().isEmpty()) { - System.out.println("no follow up messages"); - state = this.knownIntents.get(intent.getKeyword()); + state = this.rootChildren.get(intent.getKeyword()); // set to the first matching state + // from start state (might be null + // // if none is found) this.currentNluModel.put(message.getChannel(), "0"); - System.out.println(intent.getKeyword() + " detected with " + intent.getConfidence() - + " confidence."); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else if (state.getFollowingMessages().get(intent.getKeyword()) != null) { - System.out.println("try follow up message"); // check if a file was received during a conversation and search for a follow up // incoming message which expects a file. if (message.getFileBody() != null) { if (state.getFollowingMessages().get(intent.getKeyword()).expectsFile()) { state = state.getFollowingMessages().get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else { state = checkDefault(state, message); @@ -502,56 +522,62 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { state = checkDefault(state, message); } else { state = state.getFollowingMessages().get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } - } else if (intent.getEntitieValues().size() > 0 && state.getFollowingMessages().get(intent.getEntitieValues().get(0)) != null) { - System.out.println("try follow up message with entity"); + } else if (intent.getEntitieValues().size() > 0 + && state.getFollowingMessages().get(intent.getEntitieValues().get(0)) != null) { + // check if a file was received during a conversation and search for a follow up // incoming message which expects a file. if (message.getFileBody() != null) { - if (state.getFollowingMessages().get(intent.getEntitieValues().get(0)).expectsFile()) { + if (state.getFollowingMessages().get(intent.getEntitieValues().get(0)) + .expectsFile()) { state = state.getFollowingMessages().get(intent.getEntitieValues().get(0)); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else { state = checkDefault(state, message); } - } else if (state.getFollowingMessages().get(intent.getEntitieValues().get(0)).expectsFile()) { + } else if (state.getFollowingMessages().get(intent.getEntitieValues().get(0)) + .expectsFile()) { state = checkDefault(state, message); } else { state = state.getFollowingMessages().get(intent.getEntitieValues().get(0)); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } } else { - //System.out.println("\u001B[33mDebug --- Followups: " + state.getFollowingMessages() + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- Emptiness: " + state.getFollowingMessages().keySet().isEmpty() + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- State: " + state.getIntentKeyword() + "\u001B[0m"); - System.out.println(intent.getKeyword() + " not found in state map. Confidence: " - + intent.getConfidence() + " confidence."); + // System.out.println("\u001B[33mDebug --- Followups: " + + // state.getFollowingMessages() + "\u001B[0m"); + // System.out.println("\u001B[33mDebug --- Emptiness: " + + // state.getFollowingMessages().keySet().isEmpty() + "\u001B[0m"); + // System.out.println("\u001B[33mDebug --- State: " + state.getIntentKeyword() + + // "\u001B[0m"); + // try any - + if (state.getFollowingMessages().get("any") != null) { state = state.getFollowingMessages().get("any"); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); // In a conversation state, if no fitting intent was found and an empty leadsTo // label is found - } else if(state.getFollowingMessages().get("") != null || state.getFollowingMessages().get("anyFile") != null){ - if (message.getFileBody() != null ) { + } else if (state.getFollowingMessages().get("") != null + || state.getFollowingMessages().get("anyFile") != null) { + if (message.getFileBody() != null) { if (state.getFollowingMessages().get("anyFile") != null) { state = state.getFollowingMessages().get("anyFile"); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else { - state = this.knownIntents.get("default"); + state = this.rootChildren.get("default"); } } else { if (state.getFollowingMessages().get("") != null) { state = state.getFollowingMessages().get(""); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else { state = checkDefault(state, message); @@ -561,11 +587,11 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { && !this.triggeredFunction.containsKey(message.getChannel())) { Collection entities = intent.getEntities(); for (Entity e : entities) { - state = this.knownIntents.get(e.getEntityName()); + state = this.rootChildren.get(e.getEntityName()); // Dont fully understand the point of this, maybe I added it and forgot... // Added return for a quick fix, will need to check more in detail if (state != null) { - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); return; } } @@ -586,7 +612,7 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { } else { if (!state.getFollowingMessages().get("").expectsFile()) { state = state.getFollowingMessages().get(""); - stateMap.put(message.getChannel(), state); + this.updateConversationState(message.getChannel(), state, conversationId); addEntityToRecognizedList(message.getChannel(), intent.getEntities()); } else { state = checkDefault(state, message); @@ -596,9 +622,7 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { if (state != null) { state = checkDefault(state, message); } else { - System.out.println(intent.getKeyword() + " not detected with " + intent.getConfidence() - + " confidence."); - state = this.knownIntents.get("default"); + state = this.rootChildren.get("default"); } } // System.out.println(state.getIntentKeyword() + " set"); @@ -607,8 +631,8 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { // then intent // extraction will still be done, but the result ignored in this case } else if (message.getFileName() != null) { - if (this.knownIntents.get("0").expectsFile()) { - state = this.knownIntents.get("0"); + if (this.rootChildren.get("0").expectsFile()) { + state = this.rootChildren.get("0"); // System.out.println(state.getResponse(random)); } else { // if no Incoming Message is fitting, return default message @@ -627,14 +651,17 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { } else { // check if skip is wished or not if (state != null) { - System.out.println("Getting response for: "+state.intentKeyword); + if (state.getFollowingMessages().get("skip") != null) { state = state.getFollowingMessages().get("skip"); } - + String response = state.getResponse(random); - if (state.getTriggeredFunctionId() != "" && state.getTriggeredFunctionId() != null) { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); + triggeredFunctionId = state.getTriggeredFunctionId() == null + || state.getTriggeredFunctionId().equals("") ? null + : state.getTriggeredFunctionId(); + if (triggeredFunctionId != null && triggeredFunctionId != "") { + this.triggeredFunction.put(message.getChannel(), triggeredFunctionId); contextOn = true; } @@ -655,9 +682,11 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { entitySplit2.add(entitySplit1[i].split("\\]")[0]); } for (String entityName : entitySplit2) { - if(recognizedEntities != null && recognizedEntities.get(message.getChannel()) != null){ + if (recognizedEntities != null + && recognizedEntities.get(message.getChannel()) != null) { for (Entity entity : recognizedEntities.get(message.getChannel())) { - if (entityName.equals(entity.getEntityName()) && entity.getValue() != null) { + if (entityName.equals(entity.getEntityName()) + && entity.getValue() != null) { String replace = "[" + entity.getEntityName() + "]"; split = split.replace(replace, entity.getValue()); } @@ -666,11 +695,33 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { } } + String activityName = state.getIntentKeyword() + ":response"; + this.l2pContext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_2, + remarks.toJSONString(), + conversationId.toString(), activityName, bot.getId(), "bot", "start", + System.currentTimeMillis()); + this.l2pContext.monitorXESEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_2, + remarks.toJSONString(), + conversationId.toString(), activityName, bot.getId(), "bot", "complete", + System.currentTimeMillis()); // check if message parses buttons or is simple text - if(state.getType().equals("Interactive Message")){ - this.chatMediator.sendBlocksMessageToChannel(message.getChannel(), split, this.chatMediator.getAuthToken(), state.getFollowingMessages(), java.util.Optional.empty()); - } else{ - this.chatMediator.sendMessageToChannel(message.getChannel(), replaceVariables(message.getChannel(), split), state.getFollowingMessages(),state.followupMessageType); + if (state.getType().equals("Interactive Message")) { + this.chatMediator.sendBlocksMessageToChannel(message.getChannel(), split, + this.chatMediator.getAuthToken(), state.getFollowingMessages(), + java.util.Optional.empty()); + } else { + // TODO: Block sending message to channel if the service is replacing the bot + // message with its own message + if (state.getOpenAIEnhance()) { + messageSent = true; + } else { + messageSent = this.chatMediator.sendMessageToChannel(message.getChannel(), + replaceVariables(message.getChannel(), split), + state.getFollowingMessages(), state.followupMessageType); + } + if (messageSent) { + botMessage = replaceVariables(message.getChannel(), split); + } } // check whether a file url is attached to the chat response and try to send it // to @@ -727,16 +778,18 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { e.printStackTrace(); java.nio.file.Files.deleteIfExists(Paths.get(fileName)); this.chatMediator.sendMessageToChannel(message.getChannel(), - state.getErrorMessage(),state.getFollowupMessageType()); + state.getErrorMessage(), state.getFollowupMessageType()); } } - if (state.getTriggeredFunctionId() != null) { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); + if (triggeredFunctionId != null) { + this.triggeredFunction.put(message.getChannel(), + triggeredFunctionId); contextOn = true; } } else { - if (state.getTriggeredFunctionId() != "") { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); + if (triggeredFunctionId != null) { + this.triggeredFunction.put(message.getChannel(), + triggeredFunctionId); contextOn = true; } else { System.out.println("No Bot Action was given to the Response"); @@ -746,28 +799,61 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { if (this.triggeredFunction.containsKey(message.getChannel())) { triggeredFunctionId = this.triggeredFunction.get(message.getChannel()); } else - triggeredFunctionId = state.getTriggeredFunctionId(); // If conversation flow is terminated, reset state if (state.getFollowingMessages().isEmpty()) { + System.out.println("No following messages"); this.stateMap.remove(message.getChannel()); - if (storedSession.containsKey(message.getChannel()) - && !this.triggeredFunction.containsKey(message.getChannel())) { - - stateMap.put(message.getChannel(), storedSession.get(message.getChannel())); - storedSession.remove(message.getChannel()); - } else if (storedSession.containsKey(message.getChannel()) - && this.triggeredFunction.containsKey(message.getChannel())) { - this.stateMap.put(message.getChannel(), state); + this.previousStateInConversationBackup.put(message.getChannel(), state); // backup state in + // case we have + // to restore it + // later on + this.previousStateInConversation.remove(message.getChannel()); + if (storedSession.containsKey(message.getChannel())) { + + if (this.triggeredFunction.containsKey(message.getChannel())) { + + this.updateConversationState(message.getChannel(), + storedSession.get(message.getChannel()), conversationId); + storedSession.remove(message.getChannel()); + } else if (this.triggeredFunction.containsKey(message.getChannel())) { + + this.updateConversationState(message.getChannel(), state, conversationId); + } } + this.recognizedEntities.remove(message.getChannel()); } } } if (state == null || !state.getIntentKeyword().contains("defaultX")) { - this.defaultAnswered.put(message.getChannel(), 0); + this.defaultAnswerCount.put(message.getChannel(), 0); } messageInfos.add(new MessageInfo(message, intent, triggeredFunctionId, bot.getName(), - "", contextOn, recognizedEntities.get(message.getChannel()),this.getName())); + "", contextOn, recognizedEntities.get(message.getChannel()), this.getName(), conversationId)); + // Chain bot action with openai, add another message info with same message info + // but with the openai trigger function + // if (state != null && state.getTriggeredFunctionIds().size() > 1) { + // messageInfos + // .add(new MessageInfo(message, intent, state.getTriggeredFunctionIds().get(1), bot.getName(), + // "", contextOn, recognizedEntities.get(message.getChannel()), this.getName(), + // conversationId)); + // } + // ConversationMessage conversationMsg = new + // ConversationMessage(message.getConversationId(), "user", message.getText()); + ConversationMessage userConvMsg = new ConversationMessage("", "user", message.getText()); + Collection conversation = conversationMap.get(message.getChannel()); + conversation.add(userConvMsg); + conversationMap.put(message.getChannel(), conversation); + + // if message was sent to channel, then add to conversation path here after the + // user message + if (messageSent = Boolean.TRUE) { + ConversationMessage botConvMsg = new ConversationMessage("", "assistant", botMessage); + conversation.add(botConvMsg); + conversationMap.put(message.getChannel(), conversation); + + } + } catch (Exception e) { e.printStackTrace(); } @@ -775,10 +861,57 @@ public void handleMessages(ArrayList messageInfos, Bot bot) { } + /** + * Determines the conversation id for a given channel. This depends on the + * current state, the last user message and whether we + * are in a service context. + * + * @param channelId + * @return + */ + private UUID determineConversationId(String channelId) { + boolean currentlyInServiceContext = this.triggeredFunction.containsKey(channelId); + IncomingMessage lastUserMessage = this.previousStateInConversation.get(channelId); + IncomingMessage state = this.stateMap.get(channelId); + UUID conversationId = null; + System.out.println("currentlyInServiceContext: " + currentlyInServiceContext); + + if (lastUserMessage != null) + System.out.println("lastUserMessage is : " + lastUserMessage.getIntentKeyword()); + if (state != null) + System.out.println("state: " + state.getIntentKeyword()); + + if (currentlyInServiceContext) { + System.out.println( + "currentlyInServiceContext: true. Thus state takes precedence over lastUserMessage."); + if (state == null) { + state = this.previousStateInConversationBackup.get(channelId); + } + if (state != null) { + System.out.println( + ". state intent is: " + + state.getIntentKeyword()); + conversationId = state.getConversationId(); + } + } else if (lastUserMessage != null) { + System.out.println("using lastUserMessage intent: " + lastUserMessage.getIntentKeyword()); + conversationId = lastUserMessage.getConversationId(); + } else if (state != null) { + System.out.println("lastUserMessage is null. using state intent: " + state.getIntentKeyword()); + conversationId = state.getConversationId(); + } + + if (conversationId == null) { + System.out.println("conversationId: null. generated new one"); + conversationId = UUID.randomUUID(); + + } + return conversationId; + } + public void setUrl(String Url) throws AuthTokenException { this.url = Url; if (this.chatMediator instanceof TelegramChatMediator) { - ((TelegramChatMediator) this.chatMediator).settingWebhook(Url); } } @@ -786,7 +919,7 @@ public void close() { chatMediator.close(); } - public String getEntityValue(String channel, String entityName){ + public String getEntityValue(String channel, String entityName) { String val = ""; PreparedStatement stmt = null; Connection conn = null; @@ -798,16 +931,16 @@ public String getEntityValue(String channel, String entityName){ stmt.setString(1, channel); stmt.setString(2, entityName); rs = stmt.executeQuery(); - if(rs.next()){ + if (rs.next()) { val = rs.getString("value"); - if(val == null){ + if (val == null) { val = ""; } } - } catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); - } + } try { if (rs != null) @@ -831,21 +964,21 @@ public String getEntityValue(String channel, String entityName){ } return val; - + } - private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ + private void safeEntities(ChatMessage msg, Bot bot, Intent intent) { String user = msg.getUser(); String channel = msg.getChannel(); String b = bot.getId(); - if(intent.getEntities() == null){ + if (intent.getEntities() == null) { return; } - if(intent.getEntitieValues() == null){ + if (intent.getEntitieValues() == null) { return; } - intent.getEntities().forEach((entity) -> { - if(entity.getValue()==null){ + intent.getEntities().forEach((entity) -> { + if (entity.getValue() == null) { return; } String k = entity.getEntityName(); @@ -856,7 +989,8 @@ private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ ResultSet rs = null; try { conn = db.getDataSource().getConnection(); - stmt = conn.prepareStatement("SELECT id FROM attributes WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); + stmt = conn.prepareStatement( + "SELECT id FROM attributes WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); stmt.setString(1, b); stmt.setString(2, channel); stmt.setString(3, user); @@ -865,18 +999,20 @@ private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ boolean f = false; while (rs.next()) f = true; - if(f){ + if (f) { // Update - stmt2 = conn.prepareStatement("UPDATE attributes SET `value`=? WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); + stmt2 = conn.prepareStatement( + "UPDATE attributes SET `value`=? WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); stmt2.setString(1, v); stmt2.setString(2, b); stmt2.setString(3, channel); stmt2.setString(4, user); stmt2.setString(5, k); stmt2.executeUpdate(); - }else{ + } else { // Insert - stmt2 = conn.prepareStatement("INSERT INTO attributes (`bot`, `channel`, `user`, `key`, `value`) VALUES (?,?,?,?,?)"); + stmt2 = conn.prepareStatement( + "INSERT INTO attributes (`bot`, `channel`, `user`, `key`, `value`) VALUES (?,?,?,?,?)"); stmt2.setString(1, b); stmt2.setString(2, channel); stmt2.setString(3, user); @@ -901,8 +1037,7 @@ private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); - } - catch (Exception e1) { + } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } @@ -931,6 +1066,94 @@ private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ } ; } - }); + }); + } + + private Intent determineIntent(ChatMessage message, Bot bot) { + Intent intent = null; + + // Special case: `!` commands + if (message.getText().startsWith("!")) { + + // Split at first occurring whitespace + + String splitMessage[] = message.getText().split("\\s+", 2); + // First word without '!' prefix + String intentKeyword = splitMessage[0].substring(1); + IncomingMessage incMsg = this.rootChildren.get(intentKeyword); + // TODO: Log this? (`!` command with unknown intent / keyword) + if (incMsg == null && !intentKeyword.toLowerCase().equals("exit")) { + if (this.currentNluModel.get(message.getChannel()) == "0") { + return null; + } else { + ArrayList empty = new ArrayList(); + empty.add(""); + incMsg = new IncomingMessage(intentKeyword, "", false, empty, null, "", null, "", "text"); + if (splitMessage.length > 1) { + incMsg.setEntityKeyword(incMsg.getIntentKeyword()); + } else { + incMsg.setEntityKeyword("newEntity"); + } + + } + } + if (splitMessage.length > 1) { + incMsg.setEntityKeyword(incMsg.getIntentKeyword()); + } else { + incMsg.setEntityKeyword("newEntity"); + } + String entityKeyword = incMsg.getEntityKeyword(); + String entityValue = null; + // Entity value is the rest of the message. The whole rest + // is in the second element, since we only split it into two parts. + if (splitMessage.length > 1) { + entityValue = splitMessage[1]; + } + + intent = new Intent(intentKeyword, entityKeyword, entityValue); + } else { + if (bot.getRasaServer(currentNluModel.get(message.getChannel())) != null) { + intent = bot.getRasaServer(currentNluModel.get(message.getChannel())) + .getIntent(Intent.replaceUmlaute(message.getText())); + } else { + // if the given id is not fit to any server, pick the first one. (In case + // someone specifies only + // one server and does not give an ID) + intent = bot.getFirstRasaServer().getIntent(Intent.replaceUmlaute(message.getText())); + } + + } + return intent; + } + + /** + * Updates the state of the conversation for the given channel. + * Also sets the conversation id for the given state. + * + * @param channelId The channel id for which the state should be updated. + * @param state The new state of the conversation. + * @param conversationId The conversation id to set. + */ + private void updateConversationState(String channelId, IncomingMessage state, UUID conversationId) { + if (state == null) { + System.out.println("State is null. Resetting state for channel " + channelId); + this.stateMap.remove(channelId); + this.previousStateInConversationBackup.put(channelId, state); + this.previousStateInConversation.remove(channelId); + } else { + state.setConversationId(conversationId); + this.previousStateInConversation.put(channelId, state); + this.stateMap.put(channelId, state); + } + + } + + public void restoreConversationState(String channelId) { + IncomingMessage state = this.previousStateInConversationBackup.get(channelId); + if (state != null) { + this.previousStateInConversation.put(channelId, state); + // System.out.println("Restored state for channel " + channelId + " to " + + // state.getIntentKeyword()); + } } } \ No newline at end of file diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java index 060cff1b..eaa7658d 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java @@ -17,11 +17,15 @@ public class ServiceFunction extends TriggerFunction{ private HashSet trigger; private HashMap onStart; + private HashMap leadsTo; + + public ServiceFunction() { setAttributes(new HashSet()); setBots(new HashSet()); setTrigger(new HashSet()); this.onStart = new HashMap(); + this.leadsTo = new HashMap(); } public String getId() { @@ -149,5 +153,13 @@ public void setTrigger(HashSet trigger) { public void addTrigger(Trigger t) { this.trigger.add(t); } + + public HashMap getLeadsTo(){ + return this.leadsTo; + } + + public void addLeadsTo(IncomingMessage m, String triggerEntity) { + this.leadsTo.put(m, triggerEntity); + } } diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java index 6e6463ef..f2025acd 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java @@ -50,7 +50,6 @@ public ArrayList getChildAttributes() { public void addChildAttribute(ServiceFunctionAttribute childAttribute) { this.childAttributes.add(childAttribute); - System.out.println("My child is" + childAttribute); } public String getId() { @@ -122,8 +121,8 @@ public ServiceFunctionAttribute getParent() { } public void setParent(ServiceFunctionAttribute parent) { - System.out.println("My parent is" +parent); this.parent = parent; + System.out.println("My parent is " + parent); } public IfThenBlock getItb() { diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java index 8ddbf6d5..259c8021 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java @@ -56,7 +56,6 @@ private JSONObject getIntentJSON(String input) throws IOException, ParseExceptio HashMap headers = new HashMap(); ClientResponse response = client.sendRequest("POST", "model/parse", inputJSON.toString(), MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, headers); - System.out.println("Result: " + response.getResponse()); JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); return (JSONObject) p.parse(response.getResponse()); } catch (Exception e) { diff --git a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java index 8338c51b..d9464f25 100644 --- a/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java +++ b/social-bot-manager/src/main/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java @@ -11,14 +11,9 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map.Entry; - import javax.websocket.DeploymentException; -import javax.ws.rs.core.MediaType; - import com.google.gson.Gson; - import i5.las2peer.api.Context; -import i5.las2peer.api.Service; import i5.las2peer.api.logging.MonitoringEvent; import i5.las2peer.api.security.AgentException; import i5.las2peer.api.security.AgentNotFoundException; @@ -54,6 +49,7 @@ public class BotParser { private static BotParser instance = null; private static final String botPass = "actingAgent"; + private static Context l2pContext; protected BotParser() { } @@ -64,6 +60,13 @@ public static BotParser getInstance() { } return instance; } + public static BotParser getInstance(Context context) { + l2pContext = context; + if (instance == null) { + instance = new BotParser(); + } + return instance; + } public void parseNodesAndEdges(BotConfiguration config, HashMap botAgents, LinkedHashMap nodes, LinkedHashMap edges, SQLDatabase database, String address) @@ -197,7 +200,9 @@ public void parseNodesAndEdges(BotConfiguration config, HashMap botAgents) { botAgent.setLoginName(botName); System.out.println(botName); Context.getCurrent().storeAgent(botAgent); - System.out.println("Here?"); } botAgent.unlock(botPass); Context.getCurrent().registerReceiver(botAgent); @@ -573,7 +603,12 @@ private Bot addBot(BotModelNode elem, HashMap botAgents) { e2.printStackTrace(); throw new IllegalArgumentException(e2); } + JSONObject monitoringMessage = new JSONObject(); + monitoringMessage.put("botName", botName); + monitoringMessage.put("agentId", botAgent.getIdentifier()); // runningAt = botAgent.getRunningAtNode(); + Context.getCurrent().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_3, + monitoringMessage.toJSONString()); System.out.println("Bot " + botName + " registered at: " + botAgent.getRunningAtNode().getNodeId()); // config.addBot(botAgent.getIdentifier(), botAgent.getLoginName()); @@ -757,7 +792,6 @@ private JSONArray swaggerHelperFunction(Bot b) { allFunctions.putAll(b.getBotServiceFunctions()); for (ServiceFunction s : allFunctions.values()) { // try to get swagger information - if (b.getServiceInformation().get(s.getServiceName()) == null /*&& s.getActionType().equals(ActionType.SERVICE)*/ ) { try { @@ -765,12 +799,10 @@ private JSONArray swaggerHelperFunction(Bot b) { System.out.println("Service name is:" + s.getServiceName() + "\nBot is : " + b.getName()); if (s.getActionType().equals(ActionType.OPENAPI)) { JSONObject j = readJsonFromUrl(s.getFunctionPath() + "/swagger.json"); - System.out.println("Information is: " + j); b.addServiceInformation(s.getServiceName(), j); } else { JSONObject j = readJsonFromUrl( - b.getAddress() + "/" + s.getServiceName() + "/swagger.json"); - System.out.println("Information is: " + j); + b.getAddress() + "/" + s.getServiceName() + "/swagger.json"); b.addServiceInformation(s.getServiceName(), j); } @@ -781,7 +813,9 @@ private JSONArray swaggerHelperFunction(Bot b) { if (b.getServiceInformation().get(s.getServiceName()) != null && s.getFunctionName() != null) { addServiceInformation(s, b.getServiceInformation().get(s.getServiceName())); } - if(s.getOnStart().containsKey(b.getId())){ + + + if (s.getOnStart().containsKey(b.getId())){ MiniClient client = new MiniClient(); // client.setLogin(, password); if(s.getActionType() == ActionType.SERVICE){ @@ -796,7 +830,12 @@ private JSONArray swaggerHelperFunction(Bot b) { body.put("botId", b.getId()); body.put("botName", b.getName()); for(ServiceFunctionAttribute a : s.getAttributes()){ - body.put(a.getName(), a.getContent()); + if (a.getContent().isEmpty()){ + JSONArray jsonArray = new JSONArray(); + body.put(a.getName(), jsonArray); + } else { + body.put(a.getName(), a.getContent()); + } } ClientResponse result = client.sendRequest(s.getHttpMethod().toUpperCase(), "", body.toString(), s.getConsumes(), s.getProduces(), headers); diff --git a/social-bot-manager/src/test/i5/las2peer/services/socialBotManagerService/ServiceTest.java b/social-bot-manager/src/test/java/i5/las2peer/services/socialBotManagerService/ServiceTest.java similarity index 100% rename from social-bot-manager/src/test/i5/las2peer/services/socialBotManagerService/ServiceTest.java rename to social-bot-manager/src/test/java/i5/las2peer/services/socialBotManagerService/ServiceTest.java diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java deleted file mode 100644 index 5d121c0d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/SocialBotManagerService.java +++ /dev/null @@ -1,2718 +0,0 @@ -package i5.las2peer.services.socialBotManagerService; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.io.*; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.sql.Blob; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; -import javax.websocket.DeploymentException; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import com.slack.api.Slack; - -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; - -import org.apache.tika.Tika; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.google.gson.Gson; - -import i5.las2peer.api.Context; -import i5.las2peer.api.ManualDeployment; -import i5.las2peer.api.ServiceException; -import i5.las2peer.api.execution.InternalServiceException; -import i5.las2peer.api.execution.ServiceAccessDeniedException; -import i5.las2peer.api.execution.ServiceInvocationFailedException; -import i5.las2peer.api.execution.ServiceMethodNotFoundException; -import i5.las2peer.api.execution.ServiceNotAuthorizedException; -import i5.las2peer.api.execution.ServiceNotAvailableException; -import i5.las2peer.api.execution.ServiceNotFoundException; -import i5.las2peer.api.logging.MonitoringEvent; -import i5.las2peer.api.persistency.Envelope; -import i5.las2peer.api.persistency.EnvelopeAccessDeniedException; -import i5.las2peer.api.persistency.EnvelopeNotFoundException; -import i5.las2peer.api.persistency.EnvelopeOperationFailedException; -import i5.las2peer.api.security.AgentAccessDeniedException; -import i5.las2peer.api.security.AgentAlreadyExistsException; -import i5.las2peer.api.security.AgentException; -import i5.las2peer.api.security.AgentLockedException; -import i5.las2peer.api.security.AgentNotFoundException; -import i5.las2peer.api.security.AgentOperationFailedException; -import i5.las2peer.api.security.UserAgent; -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import i5.las2peer.logging.L2pLogger; -import i5.las2peer.logging.bot.BotMessage; -import i5.las2peer.restMapper.RESTService; -import i5.las2peer.restMapper.annotations.ServicePath; -import i5.las2peer.security.BotAgent; -import i5.las2peer.services.socialBotManagerService.chat.*; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubWebhookReceiver; -import i5.las2peer.services.socialBotManagerService.chat.xAPI.ChatStatement; -import i5.las2peer.services.socialBotManagerService.database.SQLDatabase; -import i5.las2peer.services.socialBotManagerService.database.SQLDatabaseType; -import i5.las2peer.services.socialBotManagerService.model.ActionType; -import i5.las2peer.services.socialBotManagerService.model.Bot; -import i5.las2peer.services.socialBotManagerService.model.BotConfiguration; -import i5.las2peer.services.socialBotManagerService.model.BotModel; -import i5.las2peer.services.socialBotManagerService.model.BotModelEdge; -import i5.las2peer.services.socialBotManagerService.model.BotModelNode; -import i5.las2peer.services.socialBotManagerService.model.BotModelNodeAttribute; -import i5.las2peer.services.socialBotManagerService.model.BotModelValue; -import i5.las2peer.services.socialBotManagerService.model.IfThenBlock; -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import i5.las2peer.services.socialBotManagerService.model.MessageInfo; -import i5.las2peer.services.socialBotManagerService.model.Messenger; -import i5.las2peer.services.socialBotManagerService.model.ServiceFunction; -import i5.las2peer.services.socialBotManagerService.model.ServiceFunctionAttribute; -import i5.las2peer.services.socialBotManagerService.model.Trigger; -import i5.las2peer.services.socialBotManagerService.model.TriggerFunction; -import i5.las2peer.services.socialBotManagerService.model.BotRoutine; -import i5.las2peer.services.socialBotManagerService.model.Messenger; -import i5.las2peer.services.socialBotManagerService.nlu.Entity; -import i5.las2peer.services.socialBotManagerService.nlu.TrainingHelper; -import i5.las2peer.services.socialBotManagerService.parser.BotParser; -import i5.las2peer.services.socialBotManagerService.parser.ParseBotException; -import i5.las2peer.tools.CryptoException; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Contact; -import io.swagger.annotations.Info; -import io.swagger.annotations.License; -import io.swagger.annotations.SwaggerDefinition; -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -import com.mongodb.ConnectionString; -import com.mongodb.MongoClientSettings; -import com.mongodb.MongoException; -import com.mongodb.ServerApi; -import com.mongodb.ServerApiVersion; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.gridfs.GridFSBucket; -import com.mongodb.client.gridfs.GridFSBuckets; -import com.mongodb.client.gridfs.model.GridFSFile; -import com.mongodb.client.model.Filters; -import org.bson.Document; -import org.bson.UuidRepresentation; -import org.bson.codecs.configuration.CodecRegistry; -import org.bson.codecs.pojo.PojoCodecProvider; -import org.bson.BsonDocument; -import org.bson.BsonInt64; -import org.bson.conversions.Bson; -import org.bson.types.ObjectId; -import static org.bson.codecs.configuration.CodecRegistries.fromProviders; -import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; - - -/** - * las2peer-SocialBotManager-Service - * - * A REST service that manages social bots in a las2peer network. - * - */ -@Api(value = "test") -@SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.6.0", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "BSD 3-Clause License", url = "https://raw.githubusercontent.com/rwth-acis/las2peer-social-bot-manager-service/master/LICENSE"))) - -@ServicePath("/SBFManager") -@ManualDeployment -public class SocialBotManagerService extends RESTService { - - private String databaseName; - private int databaseTypeInt = 1; // See SQLDatabaseType for more information - private SQLDatabaseType databaseType; - private String databaseHost; - private int databasePort; - private String databaseUser; - private String databasePassword; - private SQLDatabase database; // The database instance to write to. - private String address; // address of running webconnector - private String restarterBotName; // name of restarterBot - private static String restarterBotNameStatic; - private String restarterBotPW; // PW of restarterBot - private static String restarterBotPWStatic; // PW of restarterBot - - private String mongoHost; - private String mongoUser; - private String mongoPassword; - private String mongoDB; - private String mongoUri; - private String mongoAuth = "admin"; - - - private static final String ENVELOPE_MODEL = "SBF_MODELLIST"; - - private static HashMap botIsActive = new HashMap(); - private static HashMap rasaIntents = new HashMap(); - private static HashMap courseMap = null; - - private static BotConfiguration config; - - private static HashMap botAgents; - private static final String botPass = "actingAgent"; - - private static ScheduledExecutorService rt = null; - - private int BOT_ROUTINE_PERIOD = 5; // 1 second - - private TrainingHelper nluTrain = null; - private Thread nluTrainThread = null; - private static final L2pLogger logger = L2pLogger.getInstance(SocialBotManagerService.class.getName()); - private Context l2pcontext = null; - private static BotAgent restarterBot = null; - - public Context getL2pcontext() { - return l2pcontext; - } - - public void setL2pcontext(Context l2pcontext) { - this.l2pcontext = l2pcontext; - } - - public SocialBotManagerService() { - super(); - setFieldValues(); // This sets the values of the configuration file - restarterBotNameStatic = restarterBotName; - restarterBotPWStatic = restarterBotPW; - TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - @Override - public void checkClientTrusted(X509Certificate[] certs, String authType) { - } - - @Override - public void checkServerTrusted(X509Certificate[] certs, String authType) { - } - } }; - - // Install the all-trusting trust manager - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, trustAllCerts, new SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } catch (Exception e) { - ; - } - if (getConfig() == null) { - setConfig(new BotConfiguration()); - getConfig().setBotConfiguration(new HashMap()); - } - if (getBotAgents() == null) { - setBotAgents(new HashMap()); - } - - this.databaseType = SQLDatabaseType.getSQLDatabaseType(databaseTypeInt); - this.database = new SQLDatabase(this.databaseType, this.databaseUser, this.databasePassword, this.databaseName, - this.databaseHost, this.databasePort); - try { - Connection con = database.getDataSource().getConnection(); - con.close(); - } catch (SQLException e) { - System.out.println("Failed to Connect: " + e.getMessage()); - } - - // mongo db connection for exchanging files - mongoUri = "mongodb://"+mongoUser+":"+mongoPassword+"@"+mongoHost+"/?authSource="+mongoAuth; - // Construct a ServerApi instance using the ServerApi.builder() method - CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); - CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry); - MongoClientSettings settings = MongoClientSettings.builder() - .uuidRepresentation(UuidRepresentation.STANDARD) - .applyConnectionString(new ConnectionString(mongoUri)) - .codecRegistry(codecRegistry) - .build(); - - // Create a new client and connect to the server - MongoClient mongoClient = MongoClients.create(settings); - // Create a new client and connect to the server - try { - MongoDatabase database = mongoClient.getDatabase(mongoDB); - // Send a ping to confirm a successful connection - Bson command = new BsonDocument("ping", new BsonInt64(1)); - Document commandResult = database.runCommand(command); - System.out.println("Pinged your deployment. You successfully connected to MongoDB!"); - } catch (MongoException me) { - System.err.println(me); - } finally{ - mongoClient.close(); - } - - if (rt == null) { - rt = Executors.newSingleThreadScheduledExecutor(); - rt.scheduleAtFixedRate(new RoutineThread(), 0, BOT_ROUTINE_PERIOD, TimeUnit.SECONDS); - } - L2pLogger.setGlobalConsoleLevel(Level.WARNING); - } - - @Override - protected void initResources() { - getResourceConfig().register(BotResource.class); - getResourceConfig().register(BotModelResource.class); - getResourceConfig().register(TrainingResource.class); - getResourceConfig().register(this); - getResourceConfig().register(GitHubWebhookReceiver.class); - getResourceConfig().register(RESTfulChatResource.class); - } - - @POST - @Path("/trainAndLoad") - @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8") - @ApiOperation(value = "Trains and loads an NLU model on the given Rasa NLU server instance.", notes = "") - // TODO: Just an adapter, since the Rasa server doesn't support - // "Access-Control-Expose-Headers" - // and the model file name is returned as a response header... Remove and just - // use Rasa's - // API directly once that's fixed. The whole `TrainingHelper` class can be - // deleted then as well. - public Response trainAndLoad(String body) { - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - if (this.nluTrainThread != null && this.nluTrainThread.isAlive()) { - return Response.status(Status.SERVICE_UNAVAILABLE).entity("Training still in progress.").build(); - } - try { - JSONObject bodyJson = (JSONObject) p.parse(body); - String url = bodyJson.getAsString("url"); - String config = bodyJson.getAsString("config"); - String markdownTrainingData = bodyJson.getAsString("markdownTrainingData"); - String intents = bodyJson.getAsString("intents"); - // added to have a way to access the intents of the rasa server - this.rasaIntents.put(url.split("://")[1], intents); - this.nluTrain = new TrainingHelper(url, config, markdownTrainingData); - this.nluTrainThread = new Thread(this.nluTrain); - this.nluTrainThread.start(); - // TODO: Create a member for this thread, make another REST method to check - // whether - // training was successful. - } catch (ParseException e) { - e.printStackTrace(); - } - - // Doesn't signal that training and loading was successful, but that it was - // started. - return Response.ok("Training started.").build(); - } - - @GET - @Path("/trainAndLoadStatus") - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Returns information about the training process started by the last invocation of `/trainAndLoad`.", notes = "") - // TODO: Just an adapter, since the Rasa server doesn't support - // "Access-Control-Expose-Headers" - // and the model file name is returned as a response header... Remove and just - // use Rasa's - // API directly once that's fixed. The whole `TrainingHelper` class can be - // deleted then as well. - public Response trainAndLoadStatus(String body) { - if (this.nluTrainThread == null) { - return Response.ok("No training process was started yet.").build(); - } else if (this.nluTrainThread.isAlive()) { - return Response.ok("Training still in progress.").build(); - } else if (this.nluTrain.getSuccess()) { - return Response.ok("Training was successful.").build(); - } else { - return Response.ok("Training failed.").build(); - } - } - - @GET - @Path("/{rasaUrl}/intents") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Returns the intents of a current Rasa Model.", notes = "") - public Response getIntents(@PathParam("rasaUrl") String url) { - if (this.rasaIntents.get(url) == null) { - return Response.ok("failed.").build(); - } else { - String intents = this.rasaIntents.get(url); - JSONObject ex = new JSONObject(); - ex.put("intents", intents); - return Response.ok().entity(ex).build(); - - } - } - - @Api(value = "Bot Resource") - @SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.0.13", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "", url = ""))) - @Path("/bots") - public static class BotResource { - SocialBotManagerService sbfservice = (SocialBotManagerService) Context.get().getService(); - - @GET - @Path("/restart") - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "List of bots") }) - @ApiOperation(value = "Restart all bots automatically", notes = "Returns a list of all registered bots.") - public Response restartBots() { - // works only after service start - if (restarterBot == null) { - try { - try { - System.out.println( - "Fetching restarter bot"); - restarterBot = (BotAgent) Context.getCurrent().fetchAgent( - Context.getCurrent().getUserAgentIdentifierByLoginName(restarterBotNameStatic)); - // if bot didn't exist before, no need to try to restart the previous bots, as - // the bot will have no way of accessing the envelope - restarterBot.unlock(restarterBotPWStatic); - Envelope env = null; - HashMap models = null; - try { - // try to add project to project list (with service group agent) - env = Context.get().requestEnvelope(restarterBotNameStatic, restarterBot); - - models = (HashMap) env.getContent(); - for (Entry entry : models.entrySet()) { - init(entry.getValue()); - } - - System.out.println("Restarting bots completed"); - } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException - | EnvelopeOperationFailedException e) { - System.out.println("no bot models found in storage"); - } - - } catch (Exception e) { - System.out.println("error: " + e.toString()); - // here, we assume that this is the first time the service is started - restarterBot = BotAgent.createBotAgent(restarterBotPWStatic); - restarterBot.unlock(restarterBotPWStatic); - restarterBot.setLoginName(restarterBotNameStatic); - Context.getCurrent().storeAgent(restarterBot); - System.out.println("Restarter bot stored"); - } - // restarterBot.unlock("123"); - // Context.getCurrent().registerReceiver(restarterBot); - } catch (AgentException | CryptoException e2) { - // TODO Errorhandling - e2.printStackTrace(); - } catch (Exception e3){ - e3.printStackTrace(); - } - } - return Response.ok().entity("Bots restarted").build(); - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "List of bots") }) - @ApiOperation(value = "Get all bots", notes = "Returns a list of all registered bots.") - public Response getBots() { - JSONObject botList = new JSONObject(); - // Iterate through VLEs - Gson g = new Gson(); - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - for (Entry botEntry : getConfig().getBots().entrySet()) { - String botName = botEntry.getKey(); - Bot b = botEntry.getValue(); - // Iterate bots - JSONObject jb = new JSONObject(); - JSONObject ac = new JSONObject(); - ac.putAll(b.getActive()); - jb.put("active", ac); - jb.put("id", b.getId()); - jb.put("name", b.getName()); - jb.put("version", b.getVersion()); - try { - jb.put("nlu", p.parse(g.toJson(b.getRasaServers()))); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - botList.put(botName, jb); - } - return Response.ok().entity(botList).build(); - } - - @GET - @Path("/{botName}") - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Returns bot information") }) - @ApiOperation(value = "Retrieve bot by name", notes = "Returns bot information by the given name.") - public Response getBotsForVLE(@PathParam("botName") String name) { - Bot b = getConfig().getBots().get(name); - if (b==null){ - return Response.status(Status.NOT_FOUND).entity("Bot "+name+" not found.").build(); - } - JSONObject bot = new JSONObject(); - JSONObject ac = new JSONObject(); - ac.putAll(b.getActive()); - bot.put("active", ac); - bot.put("id", b.getId()); - bot.put("name", b.getName()); - bot.put("version", b.getVersion()); - return Response.ok().entity(bot).build(); - } - - /** - * Initialize a bot. - * - * @param botModel Model of a bot - * - * @return Returns an HTTP response with plain text string content. - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Init successful.") }) - @ApiOperation(value = "Init Bot", notes = "Reads the configuration file.") - public Response init(BotModel botModel) { - sbfservice.setL2pcontext(Context.getCurrent()); - BotParser bp = BotParser.getInstance(); - - String returnString = ""; - LinkedHashMap nodes = botModel.getNodes(); - LinkedHashMap edges = botModel.getEdges(); - // System.out.println(SocialBotManagerService.getBotAgents().keySet()); - Set list = SocialBotManagerService.getBotAgents().keySet(); - ArrayList oldArray = new ArrayList(); - // do agentid here maybe instead of loginname, as some people use the same login - // name - for (String entry : list) { - oldArray.add(entry); - } - String botToken = ""; - for (Entry entry : nodes.entrySet()) { - if (entry.getValue().getType().equals("Messenger")) { - for (Entry subEntry : entry.getValue().getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - if (subVal.getName().equals("Authentication Token")) { - botToken = subVal.getValue(); - } - } - } - } - if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") - && !restarterBotPWStatic.equals("")) { - try { - restarterBot = (BotAgent) Context.getCurrent() - .fetchAgent(Context.getCurrent().getUserAgentIdentifierByLoginName(restarterBotNameStatic)); - restarterBot.unlock(restarterBotPWStatic); - } catch (Exception e) { - e.printStackTrace(); - } - } - - Envelope env = null; - HashMap old = null; - try { - bp.parseNodesAndEdges(SocialBotManagerService.getConfig(), SocialBotManagerService.getBotAgents(), - nodes, edges, sbfservice.database); - } catch (ParseBotException | IllegalArgumentException | IOException | DeploymentException - | AuthTokenException e) { - e.printStackTrace(); - if (e.toString().toLowerCase().contains("login name longer")) { - return Response.status(Status.BAD_REQUEST).entity("Bot Name needs to have at least 4 characters!") - .build(); - } - return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } - // initialized = true; - JSONObject logData = new JSONObject(); - logData.put("status", "initialized"); - env = null; - old = null; - if (restarterBotNameStatic != null && restarterBotPWStatic != null && !restarterBotNameStatic.equals("") - && !restarterBotPWStatic.equals("")) { - try { - // try to add project to project list (with service group agent) - env = Context.get().requestEnvelope(restarterBotNameStatic, restarterBot); - old = (HashMap) env.getContent(); - old.put(botToken, botModel); - env.setContent(old); - Context.get().storeEnvelope(env, restarterBot); - } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException - | EnvelopeOperationFailedException e) { - System.out.println(e); - try { - env = Context.get().createEnvelope(restarterBotNameStatic, restarterBot); - env.setPublic(); - old = new HashMap(); - old.put(botToken, botModel); - // System.out.println(botToken); - env.setContent(old); - Context.get().storeEnvelope(env, restarterBot); - } catch (EnvelopeOperationFailedException | EnvelopeAccessDeniedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (Exception e2) { - e2.printStackTrace(); - } - - } - } - Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_1, logData.toString()); - - return Response.ok().entity(returnString).build(); - } - - /** - * Join function - * - * @param body TODO - * @param botName TODO - * @return Returns an HTTP response with plain text string content derived from - * the path input param. - */ - @POST - @Path("/{botName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Bot activated") }) - @ApiOperation(value = "Activate Bot", notes = "Has the capability to join the digital space to get rights.") - public Response join(String body, @PathParam("botName") String botName) { - String returnString = ""; - try { - BotAgent botAgent = getBotAgents().get(botName); - if (botAgent == null) { - return Response.status(Status.NOT_FOUND).entity("Botagent " + botName + " not found").build(); - } - body = body.replace("$botId", botAgent.getIdentifier()); - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject j = (JSONObject) p.parse(body); - String basePath = (String) j.get("basePath"); - Bot bot = getConfig().getBot(botName); - - if (bot == null) { - return Response.status(Status.NOT_FOUND).entity("Bot " + botName + " not found").build(); - } - - if (j.get("directJoin") == null) { - String joinPath = (String) j.get("joinPath"); - - joinPath.replace("$botId", botAgent.getIdentifier()); - - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(basePath); - client.setLogin(botAgent.getLoginName(), botPass); - //client.setLogin("alice", "pwalice"); - - j.remove("joinPath"); - j.remove("basePath"); - j.remove("uid"); - ClientResponse result = client.sendRequest("POST", joinPath, j.toJSONString(), "application/json", - "text/html", new HashMap()); - } - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return Response.ok().entity(returnString).build(); - } - - /** - * Endpoint that handles incoming webhook calls. - * @param body JSONObject - * @param botName Name of the bot. - * @return HTTP response - */ - @POST - @Path("/{botName}/webhook") - @Consumes(MediaType.APPLICATION_JSON) - @ApiResponses(value = { - @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Successfully handled webhook call."), - @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Bot not found."), - @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = "Parse exception, field event is missing or event is unsupported.") - }) - @ApiOperation(value = "Handle webhook calls", notes = "Handles incoming webhook calls.") - public Response webhook(String body, @PathParam("botName") String botName) { - // check if bot exists - Bot bot = getConfig().getBot(botName); - - if (bot == null) - return Response.status(HttpURLConnection.HTTP_NOT_FOUND).entity("Bot " + botName + " not found.").build(); - - try { - // parse body - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject parsedBody = (JSONObject) p.parse(body); - - // all webhook calls need to include the "event" property - if(!parsedBody.containsKey("event")) - return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).entity("Field event is missing.").build(); - - String event = parsedBody.getAsString("event"); - // handle webhook depending on the event (currently only chat_message supported) - if(event.equals("chat_message")) { - String messenger = parsedBody.getAsString("messenger"); - ChatMediator chat = bot.getMessenger(messenger).getChatMediator(); - - // send message - JSONObject chatBody = new JSONObject(); - chatBody.put("channel", parsedBody.getAsString("channel")); - chatBody.put("text", parsedBody.getAsString("message")); - this.sbfservice.triggerChat(chat, chatBody); - - return Response.status(HttpURLConnection.HTTP_OK).build(); - } - return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).entity("Unsupported event.").build(); - } catch (ParseException e) { - return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).entity("Body parse exception.").build(); - } - } - - @POST - @Path("/{botName}/trigger/service") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Trigger bot by service function", notes = "Service Function triggers bot") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Bot triggered") }) - public Response trigger(String body, @PathParam("botName") String name) { - String returnString = ""; - try { - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject parsedBody = (JSONObject) p.parse(body); - String service = (String) parsedBody.get("serviceAlias"); - String triggerFunctionName = parsedBody.getAsString("functionName"); - String triggerUID = parsedBody.getAsString("uid"); - - for (BotAgent botAgent : getBotAgents().values()) { - try { - this.sbfservice.checkTriggerBot(config, parsedBody, botAgent, triggerUID, triggerFunctionName); - } catch (Exception e) { - e.printStackTrace(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return Response.ok().entity(returnString).build(); - } - - @POST - @Path("/{botName}/trigger/routine") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Trigger bot by routine", notes = "Routine triggers bot") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Bot triggered") }) - public Response triggerRoutine(String body, @PathParam("botName") String name) { - String returnString = "Routine is running."; - SocialBotManagerService sbf = this.sbfservice; - String addr = sbf.address; - new Thread(new Runnable() { - @Override - public void run() { - try { - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - - JSONObject j = (JSONObject) p.parse(body); - String service = (String) j.get("serviceAlias"); - - JSONObject context = new JSONObject(); - context.put("addr", addr); - - String botFunctionId = j.getAsString("function"); - BotAgent botAgent = getBotAgents().get(j.getAsString("bot")); - - try { - sbf.checkRoutineTrigger(config, j, botAgent, botFunctionId, context); - // checkTriggerBot(vle, j, botAgent, "", f); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println("Routine finished."); - } - }).start(); - return Response.ok().entity(returnString).build(); - } - - @POST - @Path("/{botName}/appRequestURL/{instanceAlias}/{intent}/{token}") - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Used as an slack app request url to send button clicks") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "") }) - public Response triggerButton(String body, @PathParam("botName") String name, - @PathParam("instanceAlias") String instanceAlias, @PathParam("intent") String expectedIntent, - @PathParam("token") String token) { - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - System.out.println("name " + name + " , instance alias " + instanceAlias); - - try { - String result = java.net.URLDecoder.decode(body, StandardCharsets.UTF_8.name()); - - // slack adds payload= in front of the result, so deleting that to parse it to - // json - result = result.substring(8); - - System.out.println("Handling message..."); - JSONObject bodyInput = (JSONObject) p.parse(result); - System.out.println("Parsed json: " + bodyInput); - - String channel = ""; - String text = ""; - String user = ""; - String ts = ""; - JSONObject actionInfoJson = new JSONObject(); - - if (bodyInput.getAsString("type").equals("view_submission")) { - // handle modal submission - // the channel should be added in "{"private_metadata":{"channel": "channel_id", - // ...}}" - // you can add other infos in private_metadata, it would be sent to the channel - // and sent back after submission - // info in private_metadata would not be shown in the channel - JSONObject view = (JSONObject) p.parse(bodyInput.getAsString("view")); - channel = ((JSONObject) p.parse(view.getAsString("private_metadata"))).getAsString("channel"); - user = ((JSONObject) p.parse(bodyInput.getAsString("user"))).getAsString("id"); - ts = "view_submission"; - text = "view_submission"; - // use callback_id to recognize which kind of view have been submitted - actionInfoJson.put("actionId", view.getAsString("callback_id")); - actionInfoJson.put("value", view.getAsString("state")); - } else { - String actionId = ""; - StringBuilder value = new StringBuilder(); - JSONObject containerJson = (JSONObject) p.parse(bodyInput.getAsString("container")); - ts = containerJson.getAsString("message_ts"); - JSONObject channelJson = (JSONObject) p.parse(bodyInput.getAsString("channel")); - channel = channelJson.getAsString("id"); - JSONObject userJson = (JSONObject) p.parse(bodyInput.getAsString("user")); - user = userJson.getAsString("id"); - - JSONArray actions = (JSONArray) p.parse(bodyInput.getAsString("actions")); - // this for loop only executed once - for (Object actionsObject : actions) { - String selectedOptionsString = ((JSONObject) actionsObject).getAsString("selected_options"); - String selectedOptionString = ((JSONObject) actionsObject).getAsString("selected_option"); - actionId = ((JSONObject) actionsObject).getAsString("action_id"); - if (selectedOptionsString != null) { - // multiple choice with one or more than one selected option - // System.out.println("selected options string: " + selectedOptionsString); - JSONArray selectedOptionsJson = (JSONArray) p.parse(selectedOptionsString); - text = selectedOptionsJson.toString(); - value.append("["); - for (Object singleOptionJson : selectedOptionsJson) { - value.append(((JSONObject) singleOptionJson).getAsString("value")).append(','); - } - value.append("]"); - - } else if (selectedOptionString != null) { - // single choice with one selected option (possible) - // System.out.println("selected option: " + selectedOptionString); - JSONObject selectedOptionJson = (JSONObject) p.parse(selectedOptionString); - - String textString = selectedOptionJson.getAsString("text"); - JSONObject textJson = (JSONObject) p.parse(textString); - text += textJson.getAsString("text"); - value.append(((JSONObject) actionsObject).getAsString("value")); - - } else { - // System.out.println("No selectedOption and no selectedOptions."); - // System.out.println("No selectedOption and no selectedOptions. Just a normal - // button press."); - - String textString = ((JSONObject) actionsObject).getAsString("text"); - JSONObject textJson = (JSONObject) p.parse(textString); - text += textJson.getAsString("text"); - value.append(((JSONObject) actionsObject).getAsString("value")); - } - } - - System.out.println("Text from triggerButton is: " + text); - // remove the last "," - if ((String.valueOf(text.charAt(text.length() - 1)).equals(","))) { - text = text.substring(0, text.length() - 1); - } - - actionInfoJson.put("actionId", actionId); - actionInfoJson.put("value", value.toString()); - } - actionInfoJson.put("triggerId", bodyInput.getAsString("trigger_id")); - - ChatMessage chatMessage = new ChatMessage(channel, user, text, ts, actionInfoJson.toString()); - JSONObject intentJO = new JSONObject(); - JSONObject innerIntent = new JSONObject(); - innerIntent.put("name", expectedIntent); - innerIntent.put("confidence", 1.0); - intentJO.put("intent", innerIntent); - JSONArray ja = new JSONArray(); - intentJO.put("entities", ja); - i5.las2peer.services.socialBotManagerService.nlu.Intent intent = new i5.las2peer.services.socialBotManagerService.nlu.Intent( - intentJO); - // set email, since it is not passed on in body - chatMessage.setEmail(user); - // adjust triggered function id - MessageInfo messageInfo = new MessageInfo(chatMessage, intent, "", name, instanceAlias, true, - new ArrayList<>()); - - // this.triggeredFunction.get(message.getChannel()); - System.out.println( - "Got info: " + messageInfo.getMessage().getText() + " " + messageInfo.getTriggeredFunctionId()); - Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, body); - - SocialBotManagerService sbf = this.sbfservice; - new Thread(new Runnable() { - @Override - public void run() { - try { - BotAgent botAgent = getBotAgents().get(messageInfo.getBotName()); - String service = messageInfo.getServiceAlias(); - - // get triggered function id, by getting bot, the messengers and then the intent - // hash map - HashMap botsHM = getConfig().getBots(); - // System.out.println("botsHM: " + botsHM); - String triggerdFunctionId = ""; - for (Bot bot : botsHM.values()) { - // System.out.println(bot); - HashMap messengers = bot - .getMessengers(); - for (Messenger m : messengers.values()) { - // System.out.println("messenger: " + m); - HashMap intentsHM = m - .getKnownIntents(); - // System.out.println("intentsHM: " + intentsHM); - for (String s : intentsHM.keySet()) { - if (s.equals(expectedIntent)) { - i5.las2peer.services.socialBotManagerService.model.IncomingMessage incomingMessage = intentsHM - .get(s); - i5.las2peer.services.socialBotManagerService.model.IncomingMessage chatResponses = incomingMessage - .getResponse(new Random()); - // System.out.println(chatResponses); - // System.out.println(chatResponses.getTriggeredFunctionId()); - triggerdFunctionId = chatResponses.getTriggeredFunctionId(); - } - } - } - } - MessageInfo newMessageInfo = new MessageInfo(chatMessage, intent, triggerdFunctionId, name, - instanceAlias, true, new ArrayList<>()); - System.out.println("Got 2nd info: " + newMessageInfo.getMessage().getText() + " " - + newMessageInfo.getTriggeredFunctionId()); - try { - sbf.performIntentTrigger(getConfig(), botAgent, newMessageInfo); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println("Intent processing finished."); - } - }).start(); - return Response.ok().build(); - - } catch (Exception e) { - e.printStackTrace(); - } - - return Response.ok().build(); - } - - @POST - @Path("/{botName}/appRequestURL/{instanceAlias}/{token}") - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Used as an slack app request url to send button clicks") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "") }) - public Response triggerButton(String body, @PathParam("botName") String name, - @PathParam("instanceAlias") String instanceAlias, - @PathParam("token") String token) { - - new Thread(new Runnable() { - @Override - public void run() { - - // Identify bot - Bot bot = null; - - for (Bot b : getConfig().getBots().values()) { - if (bot.getMessenger(ChatService.SLACK) != null) { - ChatMediator mediator = bot.getMessenger(ChatService.SLACK) - .getChatMediator(); - if (mediator.hasToken(token)) - bot = b; - } - } - - if (bot == null) - System.out.println("cannot relate slack action to a bot with token: " + token); - System.out.println("slack action: bot identified: " + bot.getName()); - - // Handle action - Messenger messenger = bot.getMessenger(ChatService.SLACK); - SlackChatMediator mediator = (SlackChatMediator) messenger.getChatMediator(); - JSONParser jsonParser = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject parsedBody; - try { - parsedBody = (JSONObject) jsonParser - .parse(java.net.URLDecoder.decode(body, StandardCharsets.UTF_8.name()).substring(8)); - mediator.handleEvent(parsedBody); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); - return Response.ok().build(); - } - - @POST - @Path("/{botName}/trigger/intent") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Log message to MobSOS and trigger bot by intent if necessary") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "") }) - public Response triggerIntent(String body, @PathParam("botName") String name) { - Gson gson = new Gson(); - MessageInfo m = gson.fromJson(body, MessageInfo.class); - JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE); - try { - JSONObject message = (JSONObject) parser.parse(body); - JSONObject cleanedJson = (JSONObject) message.get("message"); - cleanedJson.put("user", encryptThisString(cleanedJson.getAsString("user"))); - if (cleanedJson.containsKey("email")) { - cleanedJson.put("email", encryptThisString(cleanedJson.getAsString("email"))); - } - System.out.println("Got info: " + m.getMessage().getText() + " " + m.getTriggeredFunctionId()); - Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, cleanedJson.toString()); - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println("Got info: " + m.getMessage().getText() + " " + m.getTriggeredFunctionId()); - Context.get().monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_80, body); - // If no action should be triggered, just return - if (m.getTriggeredFunctionId() == null) { - return Response.ok().build(); - } - - SocialBotManagerService sbf = this.sbfservice; - new Thread(new Runnable() { - @Override - public void run() { - try { - BotAgent botAgent = getBotAgents().get(m.getBotName()); - try { - sbf.performIntentTrigger(config, botAgent, m); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println("Intent processing finished."); - } - }).start(); - return Response.ok().build(); - } - - @DELETE - @Path("/{botName}/{unit}") - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Bot deactivated") }) - @ApiOperation(value = "Deactivate bot for unit", notes = "Deactivates a bot for a unit.") - public Response deactivateBot(@PathParam("botName") String bot, @PathParam("unit") String unit) { - Bot b = getConfig().getBots().get(bot); - if (b != null) { - b.setIdActive(unit, false); - return Response.ok().entity(bot + " deactivated.").build(); - } - - return Response.status(Status.NOT_FOUND).entity(bot + " not found.").build(); - } - - // the body needs to contain the names of all the messenger elements which the - // bot uses with "messengerNames" as the attribute name - @DELETE - @Path("/{botAgentId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Bot deactivated"), - @ApiResponse(code = HttpURLConnection.HTTP_NOT_ACCEPTABLE, message = "Messenger names do not all match!") }) - @ApiOperation(value = "Deactivate bot for unit", notes = "Deactivates a bot for a unit.") - public Response deactivateBotAll(@PathParam("botAgentId") String bot, JSONObject body) { - Bot b = getConfig().getBot(bot); - if (b != null) { - ArrayList messengers = (ArrayList) body.get("messengers"); - if (b.deactivateAllWithCheck(messengers)) { - getConfig().removeBot(bot); - if (restarterBot != null) { - Envelope env = null; - HashMap old = null; - if (restarterBotNameStatic != null && restarterBotPWStatic != null - && !restarterBotNameStatic.equals("") && !restarterBotPWStatic.equals("")) { - try { - restarterBot = (BotAgent) Context.getCurrent().fetchAgent(Context.getCurrent() - .getUserAgentIdentifierByLoginName(restarterBotNameStatic)); - restarterBot.unlock(restarterBotPWStatic); - } catch (Exception e) { - e.printStackTrace(); - } - } - try { - // try to add project to project list (with service group agent) - env = Context.get().requestEnvelope(restarterBotNameStatic, restarterBot); - old = (HashMap) env.getContent(); - for (Object object : messengers) { - HashMap jsonObject = (HashMap) object; - if (old.containsKey(jsonObject.get("authToken"))) { - old.remove(jsonObject.get("authToken")); - } - } - env.setContent(old); - Context.get().storeEnvelope(env, restarterBot); - } catch (EnvelopeNotFoundException | EnvelopeAccessDeniedException - | EnvelopeOperationFailedException e) { - e.printStackTrace(); - } - } - return Response.ok().entity(bot + " deactivated.").build(); - } else { - return Response.status(HttpURLConnection.HTTP_NOT_ACCEPTABLE).entity(bot + " not deactivated.") - .build(); - } - } - - return Response.status(Status.NOT_FOUND).entity(bot + " not found.").build(); - } - - @POST - @Path("/events/telegram/{token}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Receive an Telegram event") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "") }) - public Response telegramEvent(String body, @PathParam("token") String token) { - - new Thread(new Runnable() { - @Override - public void run() { - - // Identify bot - Bot bot = null; - - for (Bot b : getConfig().getBots().values()) { - if (b.getMessenger(ChatService.TELEGRAM) != null) { - bot = b; - } - } - if (bot == null) - System.out.println("cannot relate telegram event to a bot with token: " + token); - System.out.println("telegram event: bot identified: " + bot.getName()); - - // Handle event - Messenger messenger = bot.getMessenger(ChatService.TELEGRAM); - EventChatMediator mediator = (EventChatMediator) messenger.getChatMediator(); - JSONParser jsonParser = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject parsedBody; - try { - parsedBody = (JSONObject) jsonParser.parse(body); - mediator.handleEvent(parsedBody); - } catch (ParseException e) { - e.printStackTrace(); - } - } - }).start(); - - return Response.status(200).build(); - } - } - - public void checkRoutineTrigger(BotConfiguration botConfig, JSONObject j, BotAgent botAgent, String botFunctionId, JSONObject context) - throws ServiceNotFoundException, ServiceNotAvailableException, InternalServiceException, - ServiceMethodNotFoundException, ServiceInvocationFailedException, ServiceAccessDeniedException, - ServiceNotAuthorizedException, ParseBotException, AgentNotFoundException, AgentOperationFailedException { - String botId = botAgent.getIdentifier(); - Bot bot = botConfig.getBots().get(botId); - if (bot != null) { - System.out.println("Bot " + botAgent.getLoginName() + " triggered:"); - ServiceFunction botFunction = bot.getBotServiceFunctions().get(botFunctionId); - String functionPath = ""; - if (botFunction.getActionType().equals(ActionType.SERVICE)) - functionPath = botFunction.getFunctionPath(); - JSONObject body = new JSONObject(); - HashMap attlist = new HashMap(); - - JSONObject triggerAttributes = (JSONObject) j.get("attributes"); - for (ServiceFunctionAttribute sfa : botFunction.getAttributes()) { - formAttributes(botConfig, sfa, bot, body, functionPath, attlist, triggerAttributes); - } - performTrigger(botConfig, botFunction, botAgent, functionPath, "", body); - } - } - - // TODO: Use entity value, handle environment separator, handle other things - // than static content - public void performIntentTrigger(BotConfiguration botConfig, BotAgent botAgent, MessageInfo messageInfo) - throws ServiceNotFoundException, ServiceNotAvailableException, InternalServiceException, - ServiceMethodNotFoundException, ServiceInvocationFailedException, ServiceAccessDeniedException, - ServiceNotAuthorizedException, ParseBotException, AgentNotFoundException, AgentOperationFailedException { - String botId = botAgent.getIdentifier(); - Bot bot = botConfig.getBots().get(botId); - if (bot != null) { - System.out.println("Bot " + botAgent.getLoginName() + " triggered:"); - ServiceFunction botFunction = bot.getBotServiceFunctions().get(messageInfo.getTriggeredFunctionId()); - String functionPath = ""; - if (botFunction.getActionType().equals(ActionType.SERVICE)) { - functionPath = botFunction.getFunctionPath(); - } else if (botFunction.getActionType().equals(ActionType.OPENAPI)) { - functionPath = botFunction.getFunctionPath(); - } - JSONObject body = new JSONObject(); - HashMap attlist = new HashMap(); - JSONObject triggerAttributes = new JSONObject(); - System.out.println(botFunction.getAttributes()); - for (ServiceFunctionAttribute sfa : botFunction.getAttributes()) { - formAttributes(botConfig, sfa, bot, body, functionPath, attlist, triggerAttributes); - } - // Patch attributes so that if a chat message is sent, it is sent - // to the same channel the action was triggered from. - // TODO: Handle multiple messengers - System.out.println(messageInfo.getMessage().getEmail()); - String mail = messageInfo.getMessage().getEmail(); - if(mail==null) mail = ""; - body.put("email", messageInfo.getMessage().getEmail()); - body.put("channel", messageInfo.getMessage().getChannel()); - body.put("user", messageInfo.getMessage().getUser()); - body.put("intent", messageInfo.getIntent().getKeyword()); - body.put("time", messageInfo.getMessage().getTime()); - if (messageInfo.getMessage().getMessageId() != null) { - body.put("message_id", messageInfo.getMessage().getMessageId()); - // actionInfo needed for citbot... - body.put("actionInfo", messageInfo.getMessage().getMessageId()); - } - if (messageInfo.getMessage().getFileBody() != null) { - body.put("fileBody", messageInfo.getMessage().getFileBody()); - body.put("fileName", messageInfo.getMessage().getFileName()); - body.put("fileType", messageInfo.getMessage().getFileType()); - } - if (messageInfo.getMessage().getActionInfo() != null) { - body.put("actionInfo", messageInfo.getMessage().getActionInfo()); - } - - // Insert entities detected from the message - JSONObject entities = new JSONObject(); - for (Entity entityName : messageInfo.getIntent().getEntities()) { - body.put(entityName.getEntityName(), entityName.getValue());// Kept for compatibility reasons - JSONObject entity = new JSONObject(); - entity.put("value", entityName.getValue()); - entity.put("confidence", entityName.getConfidence()); - entities.put(entityName.getEntityName(), entity); - } - - // Insert entities that was passed over from previous message - if (messageInfo.getRecognizedEntities() != null) { - for (Entity entityName : messageInfo.getRecognizedEntities()) { - JSONObject entity = new JSONObject(); - entity.put("value", entityName.getValue()); - entity.put("confidence", entityName.getConfidence()); - entities.put(entityName.getEntityName(), entity); - } - } - if ((messageInfo.getMessage().getPreviousMessage() != null) - && (messageInfo.getMessage().getCurrMessage() != null)) { - // if a message has been edited - body.put("previousMessage", messageInfo.getMessage().getPreviousMessage()); - body.put("currMessage", messageInfo.getMessage().getCurrMessage()); - } - - body.put("entities", entities); - body.put("msg", messageInfo.getMessage().getText()); - body.put("contextOn", messageInfo.contextActive()); - performTrigger(botConfig, botFunction, botAgent, functionPath, "", body); - } - } - - public void checkTriggerBot(BotConfiguration botConfig, JSONObject body, BotAgent botAgent, String triggerUID, - String triggerFunctionName) throws AgentNotFoundException, AgentOperationFailedException, - ServiceNotFoundException, ServiceNotAvailableException, InternalServiceException, - ServiceMethodNotFoundException, ServiceInvocationFailedException, ServiceAccessDeniedException, - ServiceNotAuthorizedException, ParseBotException { - String botId = botAgent.getIdentifier(); - - Bot bot = botConfig.getBots().get(botId); - if (bot != null && !(triggerUID.toLowerCase().equals(botAgent.getIdentifier().toLowerCase()))) { - - // get all triggers of the bot - Set tlist = bot.getTriggerList(); - for (Trigger trigger : tlist) { - TriggerFunction tf = trigger.getTriggerFunction(); - // in this function we only handle service functions - if (tf instanceof ServiceFunction) { - ServiceFunction sf = (ServiceFunction) tf; - // check if the function name we got equals the service function name - if (sf.getFunctionName().equals(triggerFunctionName)) { - ServiceFunction triggeredFunction = trigger.getTriggeredFunction(); - - String functionPath = ""; - // add path if the triggered function is a service function - if (triggeredFunction.getActionType().equals(ActionType.SERVICE)) - functionPath = triggeredFunction.getFunctionPath(); - JSONObject triggeredBody = new JSONObject(); - HashMap attlist = new HashMap(); - for (ServiceFunction bsf : bot.getBotServiceFunctions().values()) { - for (ServiceFunctionAttribute bsfa : bsf.getAttributes()) { - attlist.put(bsfa.getId(), bsfa); - } - } - - JSONObject triggerAttributes = (JSONObject) body.get("attributes"); - for (ServiceFunctionAttribute triggeredFunctionAttribute : triggeredFunction.getAttributes()) { - formAttributes(botConfig, triggeredFunctionAttribute, bot, triggeredBody, functionPath, attlist, - triggerAttributes); - } - - System.out.println("Performing..."); - performTrigger(botConfig, triggeredFunction, botAgent, functionPath, triggerUID, triggeredBody); - } - } - } - - } else { - // TODO - } - } - - // Aaron : if name of body is empty add as part of an array of contents ? - private void formAttributes(BotConfiguration botConfig, ServiceFunctionAttribute triggeredFunctionAttribute, Bot bot, - JSONObject triggeredBody, String functionPath, HashMap attlist, - JSONObject triggerAttributes) throws ServiceNotFoundException, ServiceNotAvailableException, - InternalServiceException, ServiceMethodNotFoundException, ServiceInvocationFailedException, - ServiceAccessDeniedException, ServiceNotAuthorizedException, ParseBotException { - // Attributes of the triggered function - if (triggeredFunctionAttribute.isSameAsTrigger()) { - mapAttributes(triggeredBody, triggeredFunctionAttribute, functionPath, attlist, triggerAttributes); - } else if (triggeredFunctionAttribute.getName() == "body") { - JSONObject triggerBody = (JSONObject) triggerAttributes.get("body"); - for (ServiceFunctionAttribute subsfa : triggeredFunctionAttribute.getChildAttributes()) { - if (subsfa.isSameAsTrigger()) { - ServiceFunctionAttribute mappedTo = subsfa.getMappedTo(); - if (triggerBody.get(mappedTo.getName()) != null) { - triggeredBody.put(subsfa.getName(), triggerBody.get(mappedTo.getName())); - } else - triggeredBody.put(subsfa.getName(), triggerAttributes.get(mappedTo.getName())); - } else { - if (triggeredFunctionAttribute.getItb() != null) { - mapWithIfThen(triggeredFunctionAttribute.getItb(), triggeredFunctionAttribute, - triggeredBody, attlist, triggerAttributes, functionPath); - } else { - if (subsfa.hasStaticContent()) { - mapWithStaticContent(subsfa, triggeredBody); - } else { - // TODO no match! - } - } - - } - - } - } else { - System.out.println(triggeredFunctionAttribute.getName()); - if (triggeredFunctionAttribute.getItb() != null) { - mapWithIfThen(triggeredFunctionAttribute.getItb(), triggeredFunctionAttribute, triggeredBody, - attlist, triggerAttributes, functionPath); - } else { - if (triggeredFunctionAttribute.hasStaticContent()) { - mapWithStaticContent(triggeredFunctionAttribute, triggeredBody); - } else { - // TODO - System.out.println("Unknown mapping"); - } - } - } - } - - private void mapWithIfThen(IfThenBlock itb, ServiceFunctionAttribute triggeredFunctionAttribute, - JSONObject triggeredBody, HashMap attlist, JSONObject triggerAttributes, - String functionPath) { - IfThenBlock ifThenIterator = itb; - while (ifThenIterator.getPrev() != null) { - ifThenIterator = ifThenIterator.getPrev(); - } - System.out.println(triggerAttributes.toJSONString()); - ServiceFunctionAttribute triggerAttribute = ifThenIterator.getSourceAttribute(); - JSONObject triggerBody = (JSONObject) triggerAttributes.get("body"); - String source = ""; - if (triggerBody != null && triggerBody.containsKey(triggerAttribute.getName())) { - source = triggerBody.getAsString(triggerAttribute.getName()); - } else if (triggerAttributes.containsKey(triggerAttribute.getName())) { - source = triggerAttributes.getAsString(triggerAttribute.getName()); - } - - do { - if (checkIfCondition(ifThenIterator, source)) { - source = manipulateString(ifThenIterator, source); - } - ifThenIterator = ifThenIterator.getNext(); - } while (ifThenIterator != null); - triggeredBody.put(triggeredFunctionAttribute.getName(), source); - } - - private void mapWithStaticContent(ServiceFunctionAttribute triggeredFunctionAttribute, JSONObject triggeredBody) { - if (triggeredFunctionAttribute.getContent().length() > 0) { - if (triggeredBody.containsKey(triggeredFunctionAttribute.getName())) { - JSONArray array = new JSONArray(); - array.add(triggeredBody.get(triggeredFunctionAttribute.getName())); - array.add(triggeredFunctionAttribute.getContent()); - triggeredBody.put(triggeredFunctionAttribute.getName(), array); - } else - triggeredBody.put(triggeredFunctionAttribute.getName(), triggeredFunctionAttribute.getContent()); - - } - if (triggeredFunctionAttribute.getContentURL().length() > 0) { - URL url; - String body = ""; - try { - url = new URL(triggeredFunctionAttribute.getContentURL()); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setDoOutput(true); - con.setDoInput(true); - - StringBuilder sb = new StringBuilder(); - BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); - String line = null; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - br.close(); - - body = sb.toString(); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - triggeredBody.put(triggeredFunctionAttribute.getName(), body); - } - } - - private void mapAttributes(JSONObject b, ServiceFunctionAttribute sfa, String functionPath, - HashMap attlist, JSONObject triggerAttributes) { - // get id of the trigger function - ServiceFunctionAttribute mappedTo = sfa.getMappedTo(); - // attributes of the function that triggered the bot - JSONObject triggerBody = (JSONObject) triggerAttributes.get("body"); - System.out.println("Aray now"); - if (triggerAttributes.containsKey(mappedTo.getName())) { - String replaceWith = triggerAttributes.getAsString(mappedTo.getName()); - if (functionPath.contains("{" + sfa.getName() + "}")) { - functionPath = functionPath.replace("{" + sfa.getName() + "}", replaceWith); - } else { - b.put(sfa.getName(), replaceWith); - } - } else if (triggerBody != null && triggerBody.containsKey(mappedTo.getName())) { - String replaceWith = triggerBody.getAsString(mappedTo.getName()); - if (functionPath.contains("{" + sfa.getName() + "}")) { - functionPath = functionPath.replace("{" + sfa.getName() + "}", replaceWith); - } else { - b.put(sfa.getName(), replaceWith); - } - } else { - // TODO Error could not map attributes - } - } - - private void performTrigger(BotConfiguration botConfig, ServiceFunction sf, BotAgent botAgent, String functionPath, String triggerUID, - JSONObject triggeredBody) throws AgentNotFoundException, AgentOperationFailedException { - if (sf.getActionType().equals(ActionType.SERVICE) || sf.getActionType().equals(ActionType.OPENAPI)) { - MiniClient client = new MiniClient(); - if (sf.getActionType().equals(ActionType.SERVICE)) { - client.setConnectorEndpoint(address); - } else if (sf.getActionType().equals(ActionType.OPENAPI)) { - client.setConnectorEndpoint(sf.getServiceName() + functionPath); - } - //client.setLogin("alice", "pwalice"); - client.setLogin(botAgent.getLoginName(), botPass); - - Bot bot = botConfig.getBots().get(botAgent.getIdentifier()); - String messengerID = sf.getMessengerName(); - triggeredBody.put("messenger", bot.getMessenger(messengerID).getChatService().toString()); - triggeredBody.put("botName", botAgent.getIdentifier()); - - HashMap headers = new HashMap(); - System.out.println(sf.getServiceName() + functionPath + " ; " + triggeredBody.toJSONString() + " " - + sf.getConsumes() + " " + sf.getProduces() + " My string is" + ":" + triggeredBody.toJSONString()); - ClientResponse r = null; - if (sf.getActionType().equals(ActionType.SERVICE)) { - r = client.sendRequest(sf.getHttpMethod().toUpperCase(), sf.getServiceName() + functionPath, - triggeredBody.toJSONString(), sf.getConsumes(), sf.getProduces(), headers); - } else if (sf.getActionType().equals(ActionType.OPENAPI)) { - r = client.sendRequest(sf.getHttpMethod().toUpperCase(), "", triggeredBody.toJSONString(), - sf.getConsumes(), sf.getProduces(), headers); - } - System.out.println("Connect Success"); - System.out.println(r.getResponse()); - if (Boolean.parseBoolean(triggeredBody.getAsString("contextOn"))) { - JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE); - try { - JSONObject response = (JSONObject) parser.parse(r.getResponse()); - System.out.println(response); - triggeredBody.put("text", response.getAsString("text")); - ChatMediator chat = bot.getMessenger(messengerID).getChatMediator(); - if (response.containsKey("fileBody")) { - triggeredBody.put("fileBody", response.getAsString("fileBody")); - triggeredBody.put("fileName", response.getAsString("fileName")); - triggeredBody.put("fileType", response.getAsString("fileType")); - } else - triggeredBody.remove("fileBody"); - if (response.containsKey("contactList")) { - triggeredBody.put("contactList", response.getAsString("contactList")); - } - if (response.containsKey("contactText")) { - triggeredBody.put("contactText", response.getAsString("contactText")); - } - if (response.containsKey("blocks")) { - triggeredBody.put("blocks", response.getAsString("blocks")); - if (response.containsKey("updateBlock")) { - triggeredBody.put("updateBlock", response.getAsString("updateBlock")); - if (response.containsKey("ts")) { - triggeredBody.put("ts", response.getAsString("ts")); - } - } - } - triggerChat(chat, triggeredBody); - if (response.get("closeContext") == null || Boolean.valueOf(response.getAsString("closeContext"))) { - System.out.println("Closed Context"); - bot.getMessenger(messengerID).setContextToBasic(triggeredBody.getAsString("channel"), - triggeredBody.getAsString("user")); - } - } catch (ParseException e) { - e.printStackTrace(); - } - } - - } else if (sf.getActionType().equals(ActionType.SENDMESSAGE)) { - Bot bot = botConfig.getBots().get(botAgent.getIdentifier()); - if (triggeredBody.get("channel") == null && triggeredBody.get("email") == null) { - // TODO Anonymous agent error - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(bot.getAddress()); - HashMap headers = new HashMap(); - ClientResponse result = client.sendRequest("GET", "SBFManager/email/" + triggerUID, "", - MediaType.TEXT_HTML, MediaType.TEXT_HTML, headers); - String mail = result.getResponse().trim(); - triggeredBody.put("email", mail); - } - String messengerID = sf.getMessengerName(); - if (messengerID == null || bot.getMessenger(messengerID) == null) { - System.out.println("Bot Action is missing Messenger"); - return; - } - - ChatMediator chat = bot.getMessenger(messengerID).getChatMediator(); - triggerChat(chat, triggeredBody); - } - } - - public void triggerChat(ChatMediator chat, JSONObject body) { - String text = body.getAsString("text"); - String blocks = body.getAsString("blocks"); - String channel = null; - String user = ""; - JSONObject monitorEvent42 = new JSONObject(); - final long start = System.currentTimeMillis(); - monitorEvent42.put("task", "Send message"); - - System.out.println(body); - if (body.containsKey("contactList")) { - // Send normal message to users on contactlist - String email = body.getAsString("contactList"); - monitorEvent42.put("email", email); - System.out.println("Goes to pick channel(s) by provided email(s)"); - String[] emailArray = email.split(","); - - if (body.containsKey("contactText")) { - // specific text at position 1 should be sent to person on contactlist at pos 1 - String ctext = body.getAsString("contactText"); - System.out.println("Goes to send text from contextText"); - String[] textArray = ctext.split(","); - int i = 0; - for (String s : emailArray) { - channel = chat.getChannelByEmail(s); - - if (textArray[i] != null) { - chat.sendMessageToChannel(channel, textArray[i],"text"); - } - i++; - } - } else { - // if no specific text, send the regular text - for (String s : emailArray) { - System.out.println(s); - channel = chat.getChannelByEmail(s); - - if (text != null && channel != null) { - chat.sendMessageToChannel(channel, text,"text"); - } - - } - } - monitorEvent42.put("time", System.currentTimeMillis() - start); - if (body.containsKey("channel")) { - channel = body.getAsString("channel"); - } else if (body.containsKey("email")) { - email = body.getAsString("email"); - channel = chat.getChannelByEmail(email); - } - chat.sendMessageToChannel(channel, "ContactList contacted.","text"); - - }else { - if (body.containsKey("channel")) { - channel = body.getAsString("channel"); - } else if (body.containsKey("email")) { - String email = body.getAsString("email"); - monitorEvent42.put("email", email); - channel = chat.getChannelByEmail(email); - } - System.out.println(channel); - if (text != null && !body.containsKey("fileBody")) { - chat.sendMessageToChannel(channel, text,"text"); - } - if (body.containsKey("blocks")) { - System.out.println("Body has blocks"); - if (body.containsKey("updateBlock") && Boolean.parseBoolean(body.getAsString("updateBlock"))) { - if (body.containsKey("ts")) { - System.out.println("A block would be updated"); - chat.updateBlocksMessageToChannel(channel, blocks, chat.getAuthToken(), body.getAsString("ts")); - } else { - System.out.println( - "No ts information is available. No block would be updated, a new block will be sent instead."); - } - - } else { - chat.sendBlocksMessageToChannel(channel, blocks, chat.getAuthToken()); - } - } - if (body.containsKey("fileBody")) { - if (text == null) { - - text = ""; - } - System.out.println("text is sss" + text); - chat.sendFileMessageToChannel(channel, body.getAsString("fileBody"), body.getAsString("fileName"), - body.getAsString("fileType"), text); - } - monitorEvent42.put("time", System.currentTimeMillis() - start); - } - if (l2pcontext!=null){ - l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_42,monitorEvent42.toString()); - } - } - - @Api(value = "Model Resource") - @SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.0.13", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "", url = ""))) - @Path("/models") - public static class BotModelResource { - SocialBotManagerService service = (SocialBotManagerService) Context.get().getService(); - - /** - * Put Model function. - * - * @param name name of the model - * @param body content of the model - * @return Returns an HTTP response with plain text string content derived from - * the path input param. - */ - @POST - @Path("/{name}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Model stored") }) - @ApiOperation(value = "Save BotModel", notes = "Stores the BotModel in the shared storage.") - public Response putModel(@PathParam("name") String name, BotModel body) { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - // Write serialised model in Blob - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bOut); - out.writeObject(body); - Blob blob = con.createBlob(); - blob.setBytes(1, bOut.toByteArray()); - - // Check if model with given name already exists in database. If yes, update it. - // Else, insert it - ps = con.prepareStatement("SELECT * FROM models WHERE name = ?"); - ps.setString(1, name); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - ps.close(); - ps = con.prepareStatement("UPDATE models SET model = ? WHERE name = ?"); - ps.setBlob(1, blob); - ps.setString(2, name); - ps.executeUpdate(); - } else { - ps.close(); - ps = con.prepareStatement("INSERT INTO models(name, model) VALUES (?, ?)"); - ps.setString(1, name); - ps.setBlob(2, blob); - ps.executeUpdate(); - } - - resp = Response.ok().entity("Model stored.").build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } catch (IOException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - - return resp; - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "List of BotModels") }) - @ApiOperation(value = "Retrieve BotModels", notes = "Get all stored BotModels.") - public Response getModels() { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - ps = con.prepareStatement("SELECT name FROM models"); - ResultSet rs = ps.executeQuery(); - - // Fetch all model names in the database - JSONArray models = new JSONArray(); - while (rs.next()) { - models.add(rs.getString("name")); - } - - resp = Response.ok().entity(models.toJSONString()).build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - - return resp; - } - - @GET - @Path("/{name}") - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Return BotModel") }) - @ApiOperation(value = "Get BotModel by name", notes = "Returns the BotModel for the given name.") - public Response getModelByName(@PathParam("name") String name) { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - // Fetch model with given name - ps = con.prepareStatement("SELECT * FROM models WHERE name = ?"); - ps.setString(1, name); - ResultSet rs = ps.executeQuery(); - rs.next(); - - // Write serialised model in Blob - Blob b = rs.getBlob("model"); - InputStream stream = b.getBinaryStream(); - ObjectInputStream in = new ObjectInputStream(stream); - BotModel model = (BotModel) in.readObject(); - - resp = Response.ok().entity(model).build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } catch (IOException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - return resp; - } - } - - public boolean getMessages(ArrayList messages) { - System.out.println("Bot: Got " + messages.size() + " bot messages!"); - for (BotMessage m : messages) { - BotResource br = new BotResource(); - br.trigger(m.getRemarks(), ""); - } - return true; - } - - public void setCourseMap(JSONObject map) { - if (courseMap == null) { - courseMap = new HashMap(); - } - for (String key : map.keySet()) { - courseMap.put(key, map.getAsString(key)); - } - System.out.println("Bot: Got courses: " + courseMap.toString()); - } - - public void getXapiStatements(ArrayList statements) { - System.out.println("Bot: Got " + statements.size() + " statements!"); - System.out.println(statements.toString()); - - HashMap> statementsPerCourse = new HashMap>(); - Collections.reverse(statements); - for (String statementObj : statements) { - try { - JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject obj = (JSONObject) parser.parse(statementObj); - JSONObject statement = (JSONObject) obj.get("statement"); - JSONObject context = (JSONObject) statement.get("context"); - JSONObject extensions = (JSONObject) context.get("extensions"); - JSONObject courseInfo = (JSONObject) extensions - .get("https://tech4comp.de/xapi/context/extensions/courseInfo"); - String courseid = Integer.toString(courseInfo.getAsNumber("courseid").intValue()); - - if (!statementsPerCourse.containsKey(courseid)) { - statementsPerCourse.put(courseid, new ArrayList()); - } - statementsPerCourse.get(courseid).add(statement.toString()); - } catch (Exception e) { - e.printStackTrace(); - } - } - System.out.println("\u001B[33mDebug --- Partition: " + statementsPerCourse.toString() + "\u001B[0m"); - - // Check if any bots take xAPI statements first - HashMap bots = config.getBots(); - - for (Entry botEntry : bots.entrySet()) { - HashMap messengers = botEntry.getValue().getMessengers(); - String botName = botEntry.getValue().getName(); - for (Entry messengerEntry : messengers.entrySet()) { - ChatMediator mediator = messengerEntry.getValue().getChatMediator(); - if (mediator instanceof MoodleForumMediator) { - MoodleForumMediator moodleMediator = (MoodleForumMediator) mediator; - if (courseMap != null && courseMap.containsKey(botName)) { - if (statementsPerCourse.containsKey(courseMap.get(botName))) { - System.out.println("\u001B[33mDebug --- Statement: " - + statementsPerCourse.get(courseMap.get(botName)) + "\u001B[0m"); - moodleMediator.handle(statementsPerCourse.get(courseMap.get(botName))); - } - } else { - moodleMediator.handle(statements); - } - } - } - } - } - - private boolean checkIfCondition(IfThenBlock itb, String text) { - String conditionType = itb.getConditionType(); - if (conditionType.equals("Contains")) { - return text.contains(itb.getConditionValueA()); - } else if (conditionType.equals("Equals")) { - return text.equals(itb.getConditionValueA()); - } else if (conditionType.equals("True")) { - return true; - } else if (conditionType.equals("Less Than")) { - return text.length() < Integer.parseInt(itb.getConditionValueA()); - } else if (conditionType.equals("Greater Than")) { - return text.length() > Integer.parseInt(itb.getConditionValueA()); - } - // TODO implement more - return false; - } - - private String manipulateString(IfThenBlock itb, String text) { - String manipulationType = itb.getStatementType(); - if (manipulationType.equals("Return")) { - text = itb.getStatementValueA(); - } else if (manipulationType.equals("Replace")) { - text = text.replace(itb.getStatementValueA(), itb.getStatementValueB()); - } else if (manipulationType.equals("Append")) { - text = text + itb.getStatementValueA(); - } else if (manipulationType.equals("Prepend")) { - text = itb.getStatementValueA() + text; - } - return text; - } - - public static BotConfiguration getConfig() { - return config; - } - - public static void setConfig(BotConfiguration config) { - SocialBotManagerService.config = config; - } - - public static HashMap getBotAgents() { - return botAgents; - } - - public static void setBotAgents(HashMap botAgents) { - SocialBotManagerService.botAgents = botAgents; - } - - private class RoutineThread implements Runnable { - @Override - public void run() { - - // System.out.println("bob is " + restarterBot); - - if (restarterBot == null) { - MiniClient clientRestart = new MiniClient(); - System.out.println(address); - clientRestart.setConnectorEndpoint(address); - clientRestart.setLogin("alice", "pwalice"); - HashMap headers = new HashMap(); - try { - if (restarterBotName != null && restarterBotPW != null && !restarterBotName.equals("") - && !restarterBotPW.equals("")) { - ClientResponse result2 = clientRestart.sendRequest("GET", "SBFManager/bots/restart", "", - headers); - if (result2 != null) { - restarterBot = BotAgent.createBotAgent("restarterBot"); - } - } else { - restarterBot = BotAgent.createBotAgent("restarterBot"); - } - } catch (Exception e) { - restarterBot = null; - e.printStackTrace(); - } - - } - SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); - SimpleDateFormat df2 = new SimpleDateFormat("HH:mm"); - Gson gson = new Gson(); - for (Bot bot : getConfig().getBots().values()) { - ArrayList messageInfos = new ArrayList(); - for (MessageInfo m : messageInfos) { - ChatStatement chatStatement = ChatStatement.generate(m.getMessage().getUser(), m.getBotName(), - m.getMessage().getText(), m.getMessage().getTime(), m.getMessage().getDomain()); - String chatStatementJSON = gson.toJson(chatStatement); - // l2pcontext.monitorEvent(MonitoringEvent.SERVICE_CUSTOM_MESSAGE_2, chatStatementJSON); - } - bot.handleMessages(messageInfos); - - // TODO: Handle multiple environments (maybe?) - - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(address); - - HashMap headers = new HashMap(); - for (MessageInfo m : messageInfos) { - try { - ClientResponse result = client.sendRequest("POST", - "SBFManager/bots/" + m.getBotName() + "/trigger/intent", gson.toJson(m), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - System.out.println(result.getResponse()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - for (BotRoutine r : bot.getRoutines().values()) { - // current time - Calendar c = Calendar.getInstance(); - long d1 = c.getTime().getTime(); - // last time updated - long d2 = r.getLastUpdate(); - - long diffInMillies = d1 - d2; - - int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); - - boolean trigger = false; - long min = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (r.getInterval().equals("Minute")) { - if (min >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } - if (r.getInterval().equals("Hour")) { - long hour = TimeUnit.HOURS.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (hour >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } - if (r.getInterval().equals("Day")) { - long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); - if (day >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } - if (r.getInterval().equals("Month")) { - long day = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); - // TODO - day = day / 28; - if (day >= Integer.parseInt(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Working days") && dayOfWeek != Calendar.SATURDAY - && dayOfWeek != Calendar.SUNDAY) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Weekend") - && (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY)) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } else if (r.getInterval().equals("Every day")) { - if (min >= 1 && df2.format(d1).equals(r.getTime())) { - trigger = true; - r.setLastUpdate(d1); - } - } - if (trigger) { - for (Bot b : getConfig().getBots().values()) { - HashMap activeBots = b.getActive(); - HashSet tList = r.getTrigger(); - for (Trigger t : tList) { - // for (Entry entry : activeBots.entrySet()) { - // If bot is active - // if (entry.getValue()) { - - System.out.println(df.format(d1) + ": " + b.getName()); - - JSONObject body = new JSONObject(); - body.put("serviceAlias", ""); // TODO - - JSONObject atts = new JSONObject(); - - body.put("function", t.getTriggeredFunction().getId()); - body.put("bot", b.getName()); - // atts.put(vle.getEnvironmentSeparator(), entry.getKey()); - body.put("attributes", atts); - - headers = new HashMap(); - String path = "SBFManager/bots/" + b.getName() + "/trigger/routine"; - try { - path = "SBFManager/bots/" + URLEncoder.encode(b.getName(), "UTF-8") - + "/trigger/routine"; - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - ClientResponse result = client.sendRequest("POST", path, body.toJSONString(), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - System.out.println(result.getResponse()); - // } - } - } - } - - } - } - - } - - } - - @Api(value = "Training Resource") - @SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.0.13", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "", url = ""))) - @Path("/training") - public static class TrainingResource { - SocialBotManagerService service = (SocialBotManagerService) Context.get().getService(); - - /** - * Store training data in the database. - * - * @param body training data body - * - * @param name training data name - * - * @return Returns an HTTP response with plain text string content. - */ - @POST - @Path("/{dataName}") - @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.TEXT_PLAIN) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Data stored.") }) - @ApiOperation(value = "Store Training Data", notes = "Stores the current training data.") - public Response storeData(String body, @PathParam("dataName") String name) { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - // Check if data with given name already exists in database. If yes, update it. - // Else, insert it - ps = con.prepareStatement("SELECT * FROM training WHERE name = ?"); - ps.setString(1, name); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - ps.close(); - ps = con.prepareStatement("UPDATE training SET data = ? WHERE name = ?"); - ps.setString(1, body); - ps.setString(2, name); - ps.executeUpdate(); - } else { - ps.close(); - ps = con.prepareStatement("INSERT INTO training(name, data) VALUES (?, ?)"); - ps.setString(1, name); - ps.setString(2, body); - ps.executeUpdate(); - } - - resp = Response.ok().entity("Training data stored.").build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - - return resp; - } - - /** - * Retrieve training data from database. - * - * @param name training data name - * - * @return Returns an HTTP response with plain text string content. - */ - @GET - @Path("/{dataName}") - @Produces(MediaType.TEXT_PLAIN) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Data stored.") }) - @ApiOperation(value = "Fetch Training Data", notes = "Fetches the current training data.") - public Response getData(@PathParam("dataName") String name) { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - // Fetch data with given name - ps = con.prepareStatement("SELECT * FROM training WHERE name = ?"); - ps.setString(1, name); - ResultSet rs = ps.executeQuery(); - rs.next(); - - // Write serialised model in Blob - String s = rs.getString("data"); - - resp = Response.ok().entity(s).build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - return resp; - } - - /** - * Retrieve the names of all datasets in the database. - * - * - * @return Returns an HTTP response with plain text string content. - */ - @GET - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "List of datasets") }) - @ApiOperation(value = "Retrieve datasets", notes = "Get all stored datasets.") - public Response getDatasets() { - Connection con = null; - PreparedStatement ps = null; - Response resp = null; - - try { - // Open database connection - con = service.database.getDataSource().getConnection(); - - ps = con.prepareStatement("SELECT name FROM training"); - ResultSet rs = ps.executeQuery(); - - // Fetch all model names in the database - JSONArray models = new JSONArray(); - while (rs.next()) { - models.add(rs.getString("name")); - } - - resp = Response.ok().entity(models.toJSONString()).build(); - } catch (SQLException e) { - e.printStackTrace(); - resp = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } finally { - try { - if (ps != null) - ps.close(); - } catch (Exception e) { - } - ; - try { - if (con != null) - con.close(); - } catch (Exception e) { - } - ; - } - - return resp; - } - } - - public static String encryptThisString(String input) { - if (input != null) { - try { - // getInstance() method is called with algorithm SHA-384 - MessageDigest md = MessageDigest.getInstance("SHA-384"); - - // digest() method is called - // to calculate message digest of the input string - // returned as array of byte - byte[] messageDigest = md.digest(input.getBytes()); - - // Convert byte array into signum representation - BigInteger no = new BigInteger(1, messageDigest); - - // Convert message digest into hex value - String hashtext = no.toString(16); - - // Add preceding 0s to make it 32 bit - try { - while (hashtext.getBytes("UTF-16BE").length * 8 < 1536) { - hashtext = "0" + hashtext; - } - } catch (Exception e) { - System.out.println(e); - } - - // return the HashText - return hashtext; - } - - // For specifying wrong message digest algorithms - catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } else { - return null; - } - } - - @POST - @Path("/sendMessageToSlack/{token}/{email}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Trigger slack chat message to slack user with given email") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "triggered chat message") }) - public Response testRoute(@PathParam("token") String token, @PathParam("email") String email, String input) { - // This function is a proof of concept. It is not the best in terms of run time, - // but optimization would require bigger changes - // in the code structure. To make it faster, the channel could be saved in a db - // once at first access, so the expensive API do not have to be called - // everytime. - try { - SlackChatMediator chatMediator = new SlackChatMediator(token); - System.out.println("slack mediator initialized"); - - // get user id from slack - try { - // slack api call to get email for user id - JSONParser p = new JSONParser(); - JSONObject bodyInput = (JSONObject) p.parse(input); - String msgtext = bodyInput.getAsString("msg"); - System.out.println("Using token " + token); - System.out.println("Using email " + email); - - String channel = chatMediator.getChannelByEmail(email); - chatMediator.sendMessageToChannel(channel, msgtext,"text"); - - } catch (Exception e) { - e.printStackTrace(); - return Response.ok("Sending message failed.").build(); - } - - } catch (Exception e) { - e.printStackTrace(); - } - - return Response.ok().build(); - - } - - @POST - @Path("/sendMessageToRocketChat/{token}/{email}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Trigger rocket chat message to given rocket chat channel") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "triggered chat message") }) - public Response sendMessageToRocketChat(@PathParam("token") String token, @PathParam("email") String email, - String input) { - try { - RocketChatMediator chatMediator = new RocketChatMediator(token, database); - System.out.println("rocket chat mediator initialized"); - - try { - JSONParser p = new JSONParser(); - JSONObject bodyInput = (JSONObject) p.parse(input); - String msgtext = bodyInput.getAsString("msg"); - String channel = chatMediator.getChannelByEmail(email); - chatMediator.sendMessageToChannel(channel, msgtext,"text"); - - } catch (Exception e) { - e.printStackTrace(); - return Response.ok("Sending message failed.").build(); - } - - } catch (Exception e) { - e.printStackTrace(); - } - - return Response.ok().build(); - - } - - @POST - @Path("/editMessage/{token}/{email}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Edit Chat Message") - @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "triggered chat message") }) - public Response editMessage(@PathParam("token") String token, @PathParam("email") String email, - String input) { - System.out.println("received api call to edit message"); - try { - - ChatMediator chatMediator = null; - String channel = ""; - if (token.startsWith("xoxb")) { - chatMediator = (SlackChatMediator) new SlackChatMediator(token); - channel = chatMediator.getChannelByEmail(email); - } else { - chatMediator = (TelegramChatMediator) new TelegramChatMediator(token); - channel = email; - } - - try { - JSONParser p = new JSONParser(); - JSONObject bodyInput = (JSONObject) p.parse(input); - String ts = bodyInput.getAsString("ts"); - String blocks = bodyInput.getAsString("blocks"); - System.out.println("Using token " + token + " ts " + ts + " blocks " + blocks); - - chatMediator.editMessage(channel, ts, blocks, Optional.empty()); - - } catch (Exception e) { - e.printStackTrace(); - return Response.ok("Editing chat failed.").build(); - } - - } catch (Exception ex) { - ex.printStackTrace(); - } - - return Response.ok().build(); - - } - - // Should be an own resource.. this whole class needs refactoring. - @Api(value = "RESTfulChat Resource") - @SwaggerDefinition(info = @Info(title = "las2peer Bot Manager Service", version = "1.6.0", description = "A las2peer service for managing social bots.", termsOfService = "", contact = @Contact(name = "Alexander Tobias Neumann", url = "", email = "neumann@dbis.rwth-aachen.de"), license = @License(name = "BSD 3-Clause License", url = "https://raw.githubusercontent.com/rwth-acis/las2peer-social-bot-manager-service/master/LICENSE"))) - @Path("/RESTfulChat") - public static class RESTfulChatResource { - SocialBotManagerService service = (SocialBotManagerService) Context.get().getService(); - - - /** - * Handles RESTful chat requests. - * - * @param bot the name of the bot to send the message to - * @param organization the organization to send the message to - * @param channel the channel to send the message to - * @param input the input message, in JSON format - * @return the response from the bot, in plain text format - */ - @POST - @Path("/{bot}/{organization}/{channel}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Sends a message to the RESTful chat bot and channel", notes = "Provides a service to send a message to the specified bot and channel through a RESTful API endpoint") - @ApiResponses(value = {@ApiResponse(code = 200, message = "Message successfully sent"),@ApiResponse(code = 500, message = "Internal server error"),@ApiResponse(code = 400, message = "Bad request, required parameters not provided")}) - public Response handleRESTfulChat(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, - String input) { - RESTfulChatResponse answerMsg = null; - try { - Bot b = null; - for(Bot botIterator: getConfig().getBots().values()){ - if(botIterator.getName().equalsIgnoreCase(bot)){ - b = botIterator; - } - } - // there should be one or no bot available (we will remove instance in a later version) - if(b!=null){ - ArrayList messageInfos = new ArrayList(); - boolean found = false; - for (Messenger m : b.getMessengers().values()) { - if(m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator){ - RESTfulChatMediator chatMediator = (RESTfulChatMediator) m.getChatMediator(); - JSONParser p = new JSONParser(); - JSONObject bodyInput = (JSONObject) p.parse(input); - String orgChannel = organization + "-" + channel; - - String msgtext = bodyInput.getAsString("message"); - if(msgtext==null || msgtext.equals("")){ - return Response.status(Status.BAD_REQUEST).entity("No message provided.").build(); - } - ChatMessage msg = new ChatMessage(orgChannel, orgChannel, msgtext); - chatMediator.getMessageCollector().addMessage(msg); - m.handleMessages(messageInfos, b); - answerMsg = chatMediator.getMessageForChannel(orgChannel); - found = true; - } - } - if(!found){ - return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot "+bot+".").build(); - } - }else{ - return Response.status(Status.NOT_FOUND).entity("Bot "+bot+" not found.").build(); - } - - - } catch (Exception e) { - e.printStackTrace(); - } - Gson gson = new Gson(); - return Response.ok().entity(gson.toJson(answerMsg)).build(); - - } - - /** - * Handle RESTful chat file. - * - * @param bot the bot name - * @param organization the organization name - * @param channel the channel name - * @param uploadedInputStream the uploaded input stream - * @param fileDetail the file detail - * @return the response - */ - @POST - @Path("/{bot}/{organization}/{channel}/file") - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Uploads a file to the RESTful chat bot and channel", notes = "Provides a service to upload a file to the specified bot and channel through a RESTful API endpoint") - @ApiResponses(value = {@ApiResponse(code = 200, message = "File successfully uploaded"), @ApiResponse(code = 500, message = "Internal server error"), @ApiResponse(code = 400, message = "Bad request, required parameters not provided")}) - public Response handleRESTfulChatFile(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, - @FormDataParam("file") InputStream uploadedInputStream, - @FormDataParam("file") FormDataContentDisposition fileDetail) { - RESTfulChatResponse answerMsg = new RESTfulChatResponse(""); - try { - Bot b = null; - String addr = service.address; - for(Bot botIterator: getConfig().getBots().values()){ - if(botIterator.getName().equalsIgnoreCase(bot)){ - b = botIterator; - } - } - // there should be one or no bot available (we will remove instance in a later version) - if(b!=null){ - ArrayList messageInfos = new ArrayList(); - boolean found = false; - boolean err = false; - for (Messenger m : b.getMessengers().values()) { - if(m.getChatMediator() != null && m.getChatMediator() instanceof RESTfulChatMediator){ - byte[] bytes = toBytes(uploadedInputStream); - String encoded = Base64.getEncoder().encodeToString(bytes); - RESTfulChatMediator chatMediator = (RESTfulChatMediator) m.getChatMediator(); - String fname = fileDetail.getFileName(); - String ftype = getFileType(uploadedInputStream); - CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); - CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry); - MongoClientSettings settings = MongoClientSettings.builder() - .uuidRepresentation(UuidRepresentation.STANDARD) - .applyConnectionString(new ConnectionString(service.mongoUri)) - .codecRegistry(codecRegistry) - .build(); - System.out.println("Connecting to: "+service.mongoUri); - // Create a new client and connect to the server - MongoClient mongoClient = MongoClients.create(settings); - ObjectId fileId = null; - try{ - MongoDatabase database = mongoClient.getDatabase(service.mongoDB); - System.out.println("connected to "+ service.mongoDB); - GridFSBucket gridFSBucket = GridFSBuckets.create(database,"files"); - System.out.println("gridFSBucket: files"); - ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); - fileId = gridFSBucket.uploadFromStream(bot+organization+channel+"-"+fname, inputStream); - System.out.println("File uploaded successfully with ID: " + fileId.toString()); - } catch (MongoException me) { - System.err.println(me); - err = true; - } finally { - // Close the input stream and MongoDB client - try { - uploadedInputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - mongoClient.close(); - } - if(err){ - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Error uploading file.").build(); - } - - RESTfulChatMessageCollector msgcollector = (RESTfulChatMessageCollector) chatMediator.getMessageCollector(); - String orgChannel = organization + "-" + channel; - msgcollector.handle(encoded, fname, ftype, orgChannel); - m.handleMessages(messageInfos, b); - answerMsg = chatMediator.getMessageForChannel(orgChannel); - System.out.println(answerMsg.getMessage()); - if(fileId!=null) answerMsg.setFileID(fileId.toString()); - System.out.println("handling file"); - found = true; - /*MiniClient client = new MiniClient(); - System.out.println("Addr: "+addr); - client.setConnectorEndpoint(addr); - - HashMap headers = new HashMap(); - for (MessageInfo mInfo : messageInfos) { - try { - Gson gson = new Gson(); - ClientResponse result = client.sendRequest("POST", - "SBFManager/bots/" + mInfo.getBotName() + "/trigger/intent", gson.toJson(mInfo), - MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, headers); - System.out.println(result.getResponse()); - } catch (Exception e) { - e.printStackTrace(); - } - } - */ - } - } - if(!found){ - return Response.status(Status.NOT_FOUND).entity("No RESTfulChat found for Bot "+bot+".").build(); - } - }else{ - return Response.status(Status.NOT_FOUND).entity("Bot "+bot+" not found.").build(); - } - - - } catch (Exception e) { - e.printStackTrace(); - } - - Gson gson = new Gson(); - return Response.ok().entity(gson.toJson(answerMsg)).build(); - } - - @GET - @Path("/{bot}/{organization}/{channel}/file/{fileId}") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download file", produces = MediaType.APPLICATION_OCTET_STREAM) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "File downloaded successfully"), - @ApiResponse(code = 404, message = "File not found"), - @ApiResponse(code = 500, message = "Internal server error")}) - public Response getRESTfulChatFile(@PathParam("bot") String bot, @PathParam("organization") String organization, @PathParam("channel") String channel, @PathParam("fileId") String fileId) { - RESTfulChatResponse answerMsg = null; - try { - String path = bot+organization+channel+"-"+fileId; - - CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build()); - CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry); - MongoClientSettings settings = MongoClientSettings.builder() - .uuidRepresentation(UuidRepresentation.STANDARD) - .applyConnectionString(new ConnectionString(service.mongoUri)) - .codecRegistry(codecRegistry) - .build(); - - // Create a new client and connect to the server - MongoClient mongoClient = MongoClients.create(settings); - - try { - MongoDatabase database = mongoClient.getDatabase(service.mongoDB); - GridFSBucket gridFSBucket = GridFSBuckets.create(database,"files"); - GridFSFile file = gridFSBucket.find(Filters.eq("ID", fileId)).first(); - if (file == null) { - return Response.status(Response.Status.NOT_FOUND).entity("File with ID "+fileId+" not found").build(); - } - Response.ResponseBuilder response = Response.ok(file.getObjectId().toHexString()); - response.header("Content-Disposition", "attachment; filename=\"" + file.getFilename() + "\""); - - // Download the file to a ByteArrayOutputStream - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - gridFSBucket.downloadToStream(file.getObjectId(), baos); - return Response.ok(baos.toByteArray(), MediaType.APPLICATION_OCTET_STREAM).build(); - } catch (MongoException me) { - System.err.println(me); - } finally { - // Close the MongoDB client - mongoClient.close(); - } - - - File file = new File(path); - if (!file.exists()) { - return Response.status(Status.NOT_FOUND).entity("File not found.").build(); - } - - return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM) - .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"") - .build(); - - } catch (Exception e) { - e.printStackTrace(); - } - - return Response.status(Status.BAD_REQUEST).entity("Something went wrong.").build(); - } - - private String getFileType(InputStream uploadedInputStream) throws IOException { - Tika tika = new Tika(); - return tika.detect(uploadedInputStream); - } - - private byte[] toBytes(InputStream uploadedInputStream) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = uploadedInputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, len); - } - byte[] bytes = outputStream.toByteArray(); - return bytes; - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/AuthTokenException.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/AuthTokenException.java deleted file mode 100644 index 9f86bb4a..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/AuthTokenException.java +++ /dev/null @@ -1,10 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class AuthTokenException extends Exception { - - private static final long serialVersionUID = 3581207731993661888L; - - public AuthTokenException(String msg) { - super(msg); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java deleted file mode 100644 index 4d489ac5..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMediator.java +++ /dev/null @@ -1,219 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import org.apache.commons.io.FileUtils; -import org.json.JSONObject; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.*; - -public abstract class ChatMediator { - private ChatMessageCollector messageCollector; - protected String authToken; - - public ChatMediator(String authToken) { - this.authToken = authToken; - } - - /** - * Sends a chat message to a channel. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param text The content of the chat message - * @param hashMap An ID for the sent chat message, e.g. to be able to recognize - * replies to it later on. - * @param id An ID for the sent chat message, e.g. to be able to recognize - */ - public abstract void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id); - - public abstract void editMessage(String channel, String messageId, String message, Optional id); - - public void editMessage(String channel, String messageId, String message) { - editMessage(channel, messageId, message, Optional.empty()); - } - - public abstract void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id); - - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken) { - sendBlocksMessageToChannel(channel, blocks, authToken, null, Optional.empty()); - } - - public abstract void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id); - - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts) { - updateBlocksMessageToChannel(channel, blocks, authToken, ts, Optional.empty()); - } - - /** - * Sends a chat message to a channel. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param text The content of the chat message - */ - public void sendMessageToChannel(String channel, String text, String type ) { - sendMessageToChannel(channel, text, null,type); - } - /** - * Sends a chat message to a channel. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param text The content of the chat message - * @param hashMap An ID for the sent chat message, e.g. to be able to recognize - * replies to it later on. - */ - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type) { - sendMessageToChannel(channel, text, hashMap,type,null); - } - - /** - * Sends a file message to a channel as well as an optional text message. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param f A file object - * @param text Text to be sent with file - * @param id An ID for the sent chat message, e.g. to be able to recognize replies to it later on. - */ - public abstract void sendFileMessageToChannel(String channel, File f, String text, Optional id); - - /** - * Sends a file message to a channel as well as an optional text message. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param f A file object - * @param text Text to be sent with file - */ - public void sendFileMessageToChannel(String channel, File f, String text) { - sendFileMessageToChannel(channel, f, text, Optional.empty()); - } - - /** - * Sends a file message to a channel as well as an optional text message and takes care of converting base64 to a - * File object. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param fileBody Body of the file to be generated - * @param fileName Name of the file to be generated - * @param fileType Type of the file to be generated - * @param text Text to be sent with file - * @param id An ID for the sent chat message, e.g. to be able to recognize replies to it later on. - */ - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, - String text, Optional id) { - byte[] decodedBytes = java.util.Base64.getDecoder().decode(fileBody); - File file = new File(fileName + "." + fileType); - if(fileType.equals("")){ - file = new File(fileName); - } - try { - FileUtils.writeByteArrayToFile(file, decodedBytes); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sendFileMessageToChannel(channel, file, text, id); - }; - - /** - * Sends a file message to a channel as well as an optional text message and takes care of converting base64 to a - * File object. - * - * @param channel A channel ID valid for interacting with the chat service's API - * @param fileBody Body of the file to be generated - * @param fileName Name of the file to be generated - * @param fileType Type of the file to be generated - * @param text Text to be sent with file - */ - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, - String text) { - sendFileMessageToChannel(channel, fileBody, fileName, fileType, text, Optional.empty()); - } - - /** - * Gets messages the mediator received since the last time the method was - * called. - * - * @return A Vector containing the ChatMessages received since the last time the - * method was called. - */ - public abstract Vector getMessages(); - - /** - * Gets the IM channel ID for the user registered under the given E-Mail - * address. - * - * @param email The E-Mail address of the user to query - * @return If user was found, their IM channel ID, null otherwise. - */ - public abstract String getChannelByEmail(String email); - - public Boolean hasToken(String token) { - return (this.authToken.equals(token)); - } - - protected String sendRequest(String domainName, String function, HashMap args) throws IOException { - String url = domainName + "/webservice/rest/server.php" + "?wstoken=" + authToken - + "&moodlewsrestformat=json" + "&wsfunction=" + function + "&" + getDataString(args); - - //System.out.println("Debug --- URL: " + url); - - HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); - con.setRequestMethod("POST"); - - InputStream is = con.getInputStream(); - BufferedReader rd = new BufferedReader(new InputStreamReader(is)); - String line; - StringBuilder response = new StringBuilder(); - while ((line = rd.readLine()) != null) { - response.append(line); - response.append('\r'); - } - rd.close(); - - //System.out.println("Debug --- Response: " + response.toString()); - return response.toString(); - } - - protected String getDataString(HashMap params) throws UnsupportedEncodingException { - StringBuilder result = new StringBuilder(); - boolean first = true; - for (Map.Entry entry : params.entrySet()) { - if (first) { - first = false; - } else { - result.append("&"); - } - result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); - result.append("="); - result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); - } - return result.toString(); - } - - public String getAuthToken() { - return authToken; - } - - // used to check whether given token is the real one - public boolean checkToken(String authToken) { - System.out.println(authToken + " " + this.authToken); - if (authToken.equals(this.authToken)) { - return true; - } else - return false; - } - - public ChatMessageCollector getMessageCollector() { - return messageCollector; - } - - public abstract void close(); -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessage.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessage.java deleted file mode 100644 index 0dd41f7d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessage.java +++ /dev/null @@ -1,185 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import org.web3j.abi.datatypes.Bool; - -public class ChatMessage { - private String channel; - private String user; - private int role; - private String email; - private String text; - private String fileName; - private String fileType; - private String fileBody; - private String time; - private String domain; - private String previousMessage; - private String currMessage; - private String messageId; - private String actionInfo; - private InteractiveChatElementType followupMessageTypes; - - public ChatMessage(String channel, String user, String text) { - this.channel = channel; - this.user = user; - this.text = text; - } - - public ChatMessage(String channel, String user, String text, String time) { - this.channel = channel; - this.user = user; - this.text = text; - this.time = time; - } - - public ChatMessage(String channel, String user, String text, String time, String messageId) { - this.channel = channel; - this.user = user; - this.text = text; - this.time = time; - this.messageId = messageId; - } - - public ChatMessage(String channel, String user, String text, String fileName, String fileType, String body) { - this.channel = channel; - this.user = user; - this.text = text + fileName; - this.fileName = fileName; - this.fileType = fileType; - this.fileBody = body; - } - - public ChatMessage(String channel, String user, String text, String time, String messageId, String fileName, String fileType, - String body) { - this.channel = channel; - this.user = user; - this.text = text + fileName; - this.time = time; - this.messageId = messageId; - this.fileName = fileName; - this.fileType = fileType; - this.fileBody = body; - } - - public ChatMessage(String channel, String user, String text, String time, String fileName, String fileType, - String body) { - this.channel = channel; - this.user = user; - this.text = text + fileName; - this.time = time; - this.fileName = fileName; - this.fileType = fileType; - this.fileBody = body; - } - // ChatMessage for actions - public ChatMessage(String channel, String user, String text, String time, String actionInfo, boolean action) { - this.channel = channel; - this.user = user; - this.text = text; - this.time = time; - this.actionInfo = actionInfo; - } - - public String getActionInfo(){ - return this.actionInfo; - } - - public void setText(String text) { - this.text = text; - } - - public String getChannel() { - return this.channel; - } - - public String getUser() { - return this.user; - } - - public String getText() { - return this.text; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public int getRole() { - return role; - } - - public void setRole(int role) { - this.role = role; - } - - public String getMessageId() { - return messageId; - } - - public void setMessageId(String messageId) { - this.messageId = messageId; - } - - public String getFileName() { - return fileName; - } - - public String getFileType() { - return fileType; - } - - public String getFileBody() { - return fileBody; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public String getPreviousMessage() { - return previousMessage; - } - - public void setPreviousMessage(String previousMessage) { - this.previousMessage = previousMessage; - } - - public String getCurrMessage() { - return currMessage; - } - - public void setCurrMessage(String currMessage) { - this.currMessage = currMessage; - } - - public boolean hasTime(){ - if(this.getTime() != null){ - return true; - } - return false; - } - - public InteractiveChatElementType getFollowupMessageTypes() { - return followupMessageTypes; - } - - public void setFollowupMessageTypes(String followupMessageTypes) { - this.followupMessageTypes = InteractiveChatElementType.valueOf(followupMessageTypes.toUpperCase()); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java deleted file mode 100644 index 7c8ab9a0..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatMessageCollector.java +++ /dev/null @@ -1,59 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.util.Vector; - -public class ChatMessageCollector { - Vector messages; - private boolean connected; - private String domain; - - private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, - { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, { new String("ö"), "oe" }, - { new String("ß"), "ss" } }; - - public static String replaceUmlaute(String orig) { - String result = orig; - - for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) { - result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]); - } - - return result; - } - - public ChatMessageCollector() { - this.messages = new Vector(); - setConnected(true); - } - - public void addMessage(ChatMessage message) { - System.out.println("Message added: Channel: " + message.getChannel() + ", User: " + message.getUser()); - this.messages.add(message); - } - - // Copies messages in a thread-safe manner and returns the copy. - public Vector getMessages() { - Vector messages; - synchronized (this.messages) { - messages = new Vector(this.messages); - this.messages.clear(); - } - return messages; - } - - public boolean isConnected() { - return connected; - } - - public void setConnected(boolean connected) { - this.connected = connected; - } - - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatService.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatService.java deleted file mode 100644 index 5c635701..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/ChatService.java +++ /dev/null @@ -1,85 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import com.fasterxml.jackson.annotation.JsonProperty; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubIssueMediator; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubPRMediator; - -/** - * This enum lists all available messenger services. The string value has to - * match the sync meta model. - */ -public enum ChatService { - - @JsonProperty("Rocket.Chat") - ROCKET_CHAT("Rocket.Chat", RocketChatMediator.class), - - @JsonProperty("Slack") - SLACK("Slack", SlackChatMediator.class), - - @JsonProperty("Telegram") - TELEGRAM("Telegram", TelegramChatMediator.class), - - @JsonProperty("Moodle Chat") - MOODLE_CHAT("Moodle Chat", MoodleChatMediator.class), - - @JsonProperty("Moodle Forum") - MOODLE_FORUM("Moodle Forum", MoodleForumMediator.class), - - @JsonProperty("GitHub Issues") - GITHUB_ISSUES("GitHub Issues", GitHubIssueMediator.class), - - @JsonProperty("GitHub Pull Requests") - GITHUB_PR("GitHub Pull Requests", GitHubPRMediator.class), - - @JsonProperty("RESTfulChat") - RESTful_Chat("RESTfulChat", RESTfulChatMediator.class), - - UNKNOWN("", null); - - /** - * The string representation of the messenger service used by the sync meta - * model. - */ - public final String string; - - /** - * The class of the chat mediator that connects to the messenger service - */ - public final Class mediatorClass; - - ChatService(String string, Class mediatorClass) { - this.string = string; - this.mediatorClass = mediatorClass; - } - - /** - * @return The string representation - */ - @Override - public final String toString() { - return this.string; - } - - /** - * - * @param string String to be compared to the representation - * @return TRUE if string represents the chat service - */ - public final boolean isEquals(String string) { - return (this.string.equals(string)); - } - - /** - * @param string representation of a chat service - * @return the enum representation of a chat service - */ - public static ChatService fromString(String string) { - - for (ChatService service : ChatService.values()) { - if (string.equalsIgnoreCase(service.toString())) - return service; - } - return ChatService.UNKNOWN; - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/EventChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/EventChatMediator.java deleted file mode 100644 index f73450f5..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/EventChatMediator.java +++ /dev/null @@ -1,21 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import net.minidev.json.JSONObject; - -/** - * An Event Chat Mediator handles messenger services that send push messages to - * inform about incoming user activities (events). - * - */ -public abstract class EventChatMediator extends ChatMediator { - - public EventChatMediator(String authToken) { - super(authToken); - } - - /** - * @param parsedEvent JSON representation of incoming event message - */ - public abstract void handleEvent(JSONObject parsedEvent); - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java deleted file mode 100644 index ca03fc2d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElement.java +++ /dev/null @@ -1,24 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class InteractiveChatElement { - private String intent; - private String label; - - public InteractiveChatElement(String intent, String label){ - this.intent = intent; - this.label = label; - } - - public String getIntent() { - return intent; - } - public void setIntent(String intent) { - this.intent = intent; - } - public String getLabel() { - return label; - } - public void setLabel(String label) { - this.label = label; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElementType.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElementType.java deleted file mode 100644 index 9d1473a5..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InteractiveChatElementType.java +++ /dev/null @@ -1,19 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public enum InteractiveChatElementType { - BUTTON("button"), - RADIO_BUTTON("radio_button"), - CHECKBOX("checkbox"), - DROPDOWN("dropdown"), - TEXT("text"); - - private String type; - - InteractiveChatElementType(String type) { - this.type = type; - } - - public String getType() { - return this.type; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InvalidChatMessageException.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InvalidChatMessageException.java deleted file mode 100644 index beeb0ba4..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/InvalidChatMessageException.java +++ /dev/null @@ -1,13 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class InvalidChatMessageException extends Exception { - public InvalidChatMessageException(String string) { - super(string); - } - - public InvalidChatMessageException() { - - } - - private static final long serialVersionUID = 3856013136022448286L; -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MessageTree.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MessageTree.java deleted file mode 100644 index 563dcaaf..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MessageTree.java +++ /dev/null @@ -1,135 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.util.ArrayList; -import java.util.HashSet; - - -public class MessageTree { - private String postid; - private String userid; - private String originpid; // Original post ID - private String originuid; // Original user ID (both IDs form the sequence ID) - private MessageTree parent; - private boolean linked; // Tells us whether the post has a child of the same sequence - private ArrayList children; - private static HashSet ignoreIds = new HashSet(); - - public static void setIgnoreId(String id) { - ignoreIds.add(id); - } - - public static boolean hasIgnoreId(String id) { - return ignoreIds.contains(id); - } - - public String getUserId() { - return this.userid; - } - - public String getPostId() { - return this.postid; - } - - public String getOriginPid() { - return this.originpid; - } - - public String getOriginUid() { - return this.originuid; - } - - public void setLinked(boolean val) { - this.linked = val; - } - - public boolean isLinked() { - return this.linked; - } - - public MessageTree (String postid, String userid, MessageTree parent) { - this.postid = postid; - this.userid = userid; - this.parent = parent; - this.linked = false; - this.children = new ArrayList(); - this.setOrigin(); - //System.out.println("\u001B[33mDebug --- Origin: " + this.postid + " " + this.userid + "\u001B[0m"); - } - - private void setOrigin() { - if (this.parent != null) { - // If post comes from a bot or teacher - if (ignoreIds.contains(this.userid)) { - this.originpid = parent.getOriginPid(); - this.originuid = parent.getOriginUid(); - this.parent.setLinked(true); - //System.out.println("\u001B[33mDebug --- User: 1\u001B[0m"); - // If post comes from a student - } else { - // If parent is a bot or teacher and has no child in the sequence and post is made by the same user as origin, link post to its sequence - //System.out.println("\u001B[33mDebug --- Ignores: " + ignoreIds + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- Linked: " + this.parent.isLinked() + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- User: " + this.userid.equals(this.parent.getOriginUid()) + "\u001B[0m"); - if (ignoreIds.contains(this.parent.getUserId()) && !this.parent.isLinked() && this.userid.equals(this.parent.getOriginUid())) { - this.originpid = parent.getOriginPid(); - this.originuid = parent.getOriginUid(); - this.parent.setLinked(true); - // If parent is a student or already has a child in the sequence or post's user is not the origin user, post starts its own sequence - } else { - //System.out.println("\u001B[33mDebug --- User: 3\u001B[0m"); - this.originpid = this.postid; - this.originuid = this.userid; - } - } - // If post is a root (no parent), it starts its own sequence - } else { - //System.out.println("\u001B[33mDebug --- User: 4\u001B[0m"); - this.originpid = this.postid; - this.originuid = this.userid; - } - } - - private void addChild(MessageTree child) { - this.children.add(child); - } - - public MessageTree searchPost(String postid) { - if (this.postid.equals(postid)) { - return this; - } else { - for (MessageTree tree : this.children) { - MessageTree res = tree.searchPost(postid); - if (res != null) { - return res; - } - } - } - return null; - } - - public MessageTree getSequenceTail() { - for (MessageTree child : this.children) { - if (child.getOriginPid().equals(this.originpid)) { - return child.getSequenceTail(); - } - } - return this; - } - - public boolean insertPost(String postid, String userid, String parentid) { - MessageTree parentTree = this.searchPost(parentid); - if (parentTree != null) { - parentTree.addChild(new MessageTree(postid, userid, parentTree)); - System.out.println("\u001B[33mDebug --- Post inserted: " + postid + " " + userid + "\u001B[0m"); - return true; - } - else { - return false; - } - } - - public boolean containsPost(String postid) { - return searchPost(postid) != null; - } -} - diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java deleted file mode 100644 index f98dc533..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleChatMediator.java +++ /dev/null @@ -1,149 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.io.File; -import java.io.IOException; - -import java.util.HashMap; -import java.util.Optional; -import java.util.Vector; - -import java.sql.Timestamp; -import java.time.Instant; -import java.util.TimeZone; -import org.json.JSONArray; -import org.json.JSONObject; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -public class MoodleChatMediator extends ChatMediator { - private static final String domainName = "https://moodle.tech4comp.dbis.rwth-aachen.de"; - private static String botId; - private long lastUpdated; - - - public MoodleChatMediator(String authToken) throws AuthTokenException{ - super(authToken); - - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - Instant instant = timestamp.toInstant(); - lastUpdated = instant.getEpochSecond(); - botId = getBotId(); - } - - protected String getBotId() throws AuthTokenException{ - HashMap args = new HashMap(); - try { - String response = sendRequest(domainName, "core_webservice_get_site_info", args); - if(response.contains("Invalid token")){ - throw new AuthTokenException("Authentication Token is faulty!"); - } - JSONObject json = new JSONObject(response); - return Integer.toString(json.getInt("userid")); - } catch (IOException e) { - e.printStackTrace(); - } - return ""; - } - - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - HashMap args = new HashMap(); - args.put("messages[0][touserid]", channel); - args.put("messages[0][text]", text); - try { - sendRequest(domainName, "core_message_send_instant_messages", args); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - // TODO Auto-generated method stub - - } - - @Override - public Vector getMessages() { - Vector messages = new Vector(); - // Request messages received by the bot - HashMap args = new HashMap(); - args.put("useridto", botId); - args.put("read", "0"); - String response = ""; - try { - response = sendRequest(domainName, "core_message_get_messages", args); - - // Extract relevant information and create message objects for recent messages - JSONObject json = new JSONObject(response); - JSONArray receivedMessages = (JSONArray) json.get("messages"); - long last = 0; // Timestamp of the last message - for (int i = 0; i < receivedMessages.length(); i++) { - JSONObject messageObj = (JSONObject) receivedMessages.get(i); - String userid = Integer.toString(messageObj.getInt("useridfrom")); - String text = messageObj.getString("fullmessage"); - long timecreated = messageObj.getLong("timecreated"); - if (lastUpdated < timecreated) { - ChatMessage message = new ChatMessage(userid, userid, text); - messages.add(message); - if (last < timecreated) { - last = timecreated; - } - } - } - if (last != 0) { - lastUpdated = last; - } - } catch (Exception e) { - e.printStackTrace(); - } - return messages; - } - - @Override - public String getChannelByEmail(String email) { - // TODO Auto-generated method stub - return null; - } - - - - @Override - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, - String text, Optional id) { - // TODO Auto-generated method stub - - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken) { - super.sendBlocksMessageToChannel(channel, blocks, authToken); - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id){ - - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts) { - super.updateBlocksMessageToChannel(channel, blocks, authToken, ts); - } - - - @Override - public void editMessage(String channel, String messageId, String message, Optional id){} - - @Override - public void close() { - // TODO Auto-generated method stub - - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java deleted file mode 100644 index 677a1ff3..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMediator.java +++ /dev/null @@ -1,229 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; -import org.json.JSONObject; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -import org.json.JSONArray; - -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.util.Vector; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.ArrayList; -import java.util.Arrays; - -public class MoodleForumMediator extends ChatMediator { - private final static String domainName = "https://moodle.tech4comp.dbis.rwth-aachen.de"; - private MoodleForumMessageCollector messageCollector = new MoodleForumMessageCollector(); - private HashMap discussions = new HashMap(); - - public MoodleForumMediator(String authToken) throws IOException, AuthTokenException{ - super(authToken); - // test whether given authToken is valid - HashMap args = new HashMap(); - try { - String response = sendRequest(domainName, "core_webservice_get_site_info", args); - if(response.contains("Invalid token")){ - throw new AuthTokenException("Authentication Token is faulty!"); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - try { - // Get sequence IDs and find origin post - HashMap args = new HashMap(); - boolean shouldPost = false; - boolean noDiscussion = true; - args.put("message", text); - args.put("subject", "Bot response"); - - for (Entry entry : discussions.entrySet()) { - MessageTree discussion = entry.getValue(); - if (discussion.containsPost(channel)) { - noDiscussion = false; - MessageTree originPost = discussion.searchPost(channel); - if (originPost != null) { - String postid = originPost.getSequenceTail().getPostId(); - args.put("postid", postid); - shouldPost = true; - System.out.println("\u001B[33mDebug --- Post found in tree: " + postid + "\u001B[0m"); - } else { - args.put("postid", channel); - shouldPost = true; - System.out.println("Debug --- Post not in tree: " + channel); - } - break; - } - } - if (noDiscussion) { - args.put("postid", channel); - shouldPost = true; - System.out.println("Debug --- No discussion tree: " + channel); - } - if (shouldPost) { - String res = sendRequest(domainName, "mod_forum_add_discussion_post", args); - JSONObject respObj = new JSONObject(res); - JSONObject postObj = (JSONObject) respObj.get("post"); - JSONObject authorObj = (JSONObject) postObj.get("author"); - String botid = Integer.toString(authorObj.getInt("id")); - MessageTree.setIgnoreId(botid); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void handle(ArrayList statements) { - for (String statement : statements) { - - JSONObject json = new JSONObject(statement); - JSONObject statementObj = (JSONObject) json.get("statement"); - JSONObject verb = (JSONObject) statementObj.get("verb"); - String verbID = verb.getString("id"); - - // If the statement is about forum activity - if (verbID.contains("replied") || verbID.contains("posted")) { - JSONObject obj = (JSONObject) statementObj.get("object"); - JSONObject definition = (JSONObject) obj.get("definition"); - JSONObject description = (JSONObject) definition.get("description"); - JSONObject actor = (JSONObject) statementObj.get("actor"); - JSONObject account = (JSONObject) actor.get("account"); - - JSONObject context = (JSONObject) statementObj.get("context"); - JSONObject extensions = (JSONObject) context.get("extensions"); - - String message = description.getString("en-US"); - String userEmail = account.getString("name"); - HashMap args = new HashMap(); - args.put("field", "email"); - args.put("values[0]", userEmail); - String userid = ""; - try { - String res = sendRequest(domainName, "core_user_get_users_by_field", args); - JSONObject resObj = (JSONObject) (new JSONArray(res)).get(0); - userid = Integer.toString(resObj.getNumber("id").intValue()); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - // Determine discussion id, post id, and parent post id - String discussionid = obj.getString("id").split("d=")[1].split("#")[0]; - String postid; - String parentid; - if (verbID.contains("replied")) { - postid = obj.getString("id").split("#p")[1]; - parentid = Integer.toString(((JSONObject) extensions.get("https://tech4comp.de/xapi/context/extensions/postParentID")).getInt("parentid")); - } else { - postid = Integer.toString(((JSONObject) extensions.get("https://tech4comp.de/xapi/context/extensions/rootPostID")).getInt("rootpostid")); - parentid = null; - } - - if (parentid == null && !discussions.containsKey(discussionid)) { - MessageTree newPost = new MessageTree(postid, userid, null); - discussions.put(discussionid, newPost); - if (!MessageTree.hasIgnoreId(userid)) { - this.messageCollector.handle(postid, userid, message); - } - } else if (discussions.containsKey(discussionid) && !discussions.get(discussionid).containsPost(postid)) { - - // Add post to existing tree - //System.out.println("\u001B[33mDebug --- Parent ID: " + parentid + "\u001B[0m"); - if (discussions.get(discussionid).insertPost(postid, userid, parentid)) { - // Add message to collector with post ID of the original post - String originid = discussions.get(discussionid).searchPost(postid).getOriginPid(); - if (!MessageTree.hasIgnoreId(userid)) { - this.messageCollector.handle(originid, userid, message); - } - - // If no parent could be found (for example, if parent message was not received by the service) - } else { - if (!MessageTree.hasIgnoreId(userid)) { - this.messageCollector.handle(postid, userid, message); - } - System.out.println("Error: Origin post not found (postid = " + postid + ")"); - } - - // If discussion does not exist (for example, because the service stopped), - } else { - if (!MessageTree.hasIgnoreId(userid) && !discussions.containsKey(discussionid)) { - //MessageTree newPost = new MessageTree(postid, userid, null); - //discussions.put(discussionid, newPost); - this.messageCollector.handle(postid, userid, message); - } - System.out.println("Error: Discussion tree not initialized (postid = " + postid + ")"); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - // TODO Auto-generated method stub - - } - - - @Override - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, String text, - Optional id) { - // TODO Auto-generated method stub - - } - - @Override - public Vector getMessages() { - return this.messageCollector.getMessages(); - } - - @Override - public String getChannelByEmail(String email) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken) { - super.sendBlocksMessageToChannel(channel, blocks, authToken); - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id){ - - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts) { - super.updateBlocksMessageToChannel(channel, blocks, authToken, ts); - } - - @Override - public void editMessage(String channel, String messageId, String message, Optional id){} - - @Override - public void close() { - // TODO Auto-generated method stub - - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMessageCollector.java deleted file mode 100644 index 9ac2b260..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/MoodleForumMessageCollector.java +++ /dev/null @@ -1,9 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class MoodleForumMessageCollector extends ChatMessageCollector { - public void handle(String convid, String userEmail, String message) { - String text = replaceUmlaute(message.replaceAll("\\<.*?>", "")); - addMessage(new ChatMessage(convid, userEmail, text)); - //System.out.println("Debug --- Collector: " + messages.toString()); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java deleted file mode 100644 index 7f60bcd7..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMediator.java +++ /dev/null @@ -1,82 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; -import java.util.Vector; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -public class RESTfulChatMediator extends ChatMediator{ - - static HashMap chatsession = null; - private RESTfulChatMessageCollector messageCollector = new RESTfulChatMessageCollector(); - - // To we need a token? Prevent malicious attacks? - public RESTfulChatMediator(String authToken) { - super(authToken); - if(chatsession==null){ - chatsession = new HashMap(); - messageCollector = new RESTfulChatMessageCollector(); - } - } - - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - RESTfulChatResponse rcr = new RESTfulChatResponse(text, hashMap,type); - chatsession.put(channel, rcr); - } - - @Override - public void editMessage(String channel, String messageId, String message, Optional id) { - RESTfulChatResponse rcr = new RESTfulChatResponse(message); - chatsession.put(channel, rcr); - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - // TODO Auto-generated method stub - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, - Optional id) { - // TODO Auto-generated method stub - - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - // TODO Auto-generated method stub - - } - - @Override - public Vector getMessages() { - Vector messages = this.messageCollector.getMessages(); - return messages; - } - - public RESTfulChatResponse getMessageForChannel(String channel) { - return chatsession.getOrDefault(channel, new RESTfulChatResponse("")); - } - - @Override - public String getChannelByEmail(String email) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void close() { - // TODO Auto-generated method stub - - } - - @Override - public ChatMessageCollector getMessageCollector(){ - return (ChatMessageCollector) messageCollector; - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java deleted file mode 100644 index 5d1727b3..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatMessageCollector.java +++ /dev/null @@ -1,33 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class RESTfulChatMessageCollector extends ChatMessageCollector{ - public void handle(String convid, String userEmail, String message) { - String text = replaceUmlaute(message.replaceAll("\\<.*?>", "")); - addMessage(new ChatMessage(convid, userEmail, text)); - } - - - - - public void handle(String fileBody, String fileName, String fileType, - String channel) { - try { - System.out.println("Handling Attachment."); - - ChatMessage cm = new ChatMessage(channel, channel, "", fileName, fileType, fileBody); - cm.setEmail(channel); - cm.setRole(0); - - // timestamp - //cm.setTime(message.getMsgTimestamp().toInstant().toString()); - - // domain - //cm.setDomain(this.getDomain()); - - this.addMessage(cm); - System.out.println("Message added."); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatResponse.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatResponse.java deleted file mode 100644 index bfacdfe3..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RESTfulChatResponse.java +++ /dev/null @@ -1,68 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -public class RESTfulChatResponse { - private String message; - private List interactiveElements; - private String fileId; - private InteractiveChatElementType type; - - public RESTfulChatResponse(String text, HashMap hashMap, String type) { - this(text); - HashSet icel = new HashSet(); - setType(type); - for (Entry entry : hashMap.entrySet()) { - String key = entry.getKey(); - System.out.println("Interactive element:" +key); - IncomingMessage value = entry.getValue(); - String intent = key; - if(intent==null||intent=="") intent = value.getIntentKeyword(); - InteractiveChatElement ice = new InteractiveChatElement(intent, value.getIntentLabel()); - icel.add(ice); - } - interactiveElements = Arrays.asList(icel.toArray()); - } - - public RESTfulChatResponse(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public List getInteractiveElements() { - return interactiveElements; - } - - public void setInteractiveElements(List interactiveElements) { - this.interactiveElements = interactiveElements; - } - - public String getFileId() { - return fileId; - } - - public void setFileID(String fileId) { - this.fileId = fileId; - } - - public InteractiveChatElementType getType() { - return type; - } - - public void setType(String type) { - this.type = InteractiveChatElementType.valueOf(type.toUpperCase()); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java deleted file mode 100644 index 81e429f8..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMediator.java +++ /dev/null @@ -1,590 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.logging.Level; - -import javax.print.attribute.standard.Media; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.glassfish.jersey.media.multipart.FormDataMultiPart; -import org.glassfish.jersey.media.multipart.MultiPartFeature; -import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; -import org.java_websocket.util.Base64; -import org.json.JSONArray; -import org.json.JSONObject; - -import com.rocketchat.common.data.lightdb.document.UserDocument; -import com.rocketchat.common.data.model.ErrorObject; -import com.rocketchat.common.data.model.UserObject; -import com.rocketchat.common.listener.ConnectListener; -import com.rocketchat.common.listener.SubscribeListener; -import com.rocketchat.common.network.ReconnectionStrategy; -import com.rocketchat.core.RocketChatAPI; -import com.rocketchat.core.RocketChatAPI.ChatRoom; -import com.rocketchat.core.callback.FileListener; -import com.rocketchat.core.callback.GetSubscriptionListener; -import com.rocketchat.core.callback.LoginListener; -import com.rocketchat.core.callback.MessageListener.SubscriptionListener; -import com.rocketchat.core.callback.RoomListener; -import com.rocketchat.core.callback.RoomListener.GetMembersListener; -import com.rocketchat.core.callback.RoomListener.GetRoomListener; -import com.rocketchat.core.factory.ChatRoomFactory; -import com.rocketchat.core.model.RocketChatMessage; -import com.rocketchat.core.model.RocketChatMessage.Type; -import com.rocketchat.core.model.RoomObject; -import com.rocketchat.core.model.SubscriptionObject; -import com.rocketchat.core.model.TokenObject; - -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import i5.las2peer.services.socialBotManagerService.database.SQLDatabase; -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import i5.las2peer.services.socialBotManagerService.nlu.RasaNlu; - - -import javax.ws.rs.core.MediaType; - -public class RocketChatMediator extends ChatMediator implements ConnectListener, LoginListener, - RoomListener.GetRoomListener, SubscribeListener, GetSubscriptionListener, SubscriptionListener { - - // TODO Default url, should be set via env variable - private String url = "https://chat.tech4comp.dbis.rwth-aachen.de"; - RocketChatAPI client; - private String username; - private String password; - private String token; - private RocketChatMessageCollector messageCollector = new RocketChatMessageCollector(); - private HashSet activeSubscriptions = null; - private RasaNlu rasa; - private SQLDatabase database; - private Thread checkRooms = null; - private boolean shouldCheckRooms = false; - private HashMap sendingMessage = new HashMap(); - - public RocketChatMediator(String authToken, SQLDatabase database, RasaNlu rasa) throws AuthTokenException{ - super(authToken); - this.database = database; - setAuthData(authToken); - if (activeSubscriptions == null) { - activeSubscriptions = new HashSet(); - } - client = new RocketChatAPI(url); - client.setReconnectionStrategy(new ReconnectionStrategy(4, 2000)); - client.setPingInterval(15000); - client.connect(this); - MiniClient clientLoginTest = new MiniClient(); - clientLoginTest.setConnectorEndpoint(url + "/api/v1/login"); - HashMap headers = new HashMap(); - ClientResponse r = null; - JSONObject reqBody = new JSONObject(); - reqBody.put("username", username); - reqBody.put("password", password); - r = clientLoginTest.sendRequest("POST", "", reqBody.toString(), MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, headers); - if(r.getHttpCode() != 200){ - throw new AuthTokenException("Authentication Token is faulty!"); - } - - RocketChatAPI.LOGGER.setLevel(Level.OFF); - this.rasa = rasa; - messageCollector.setDomain(url); - } - - public RocketChatMediator(String authToken, SQLDatabase database) { - super(authToken); - this.database = database; - setAuthData(authToken); - if (activeSubscriptions == null) { - activeSubscriptions = new HashSet(); - } - client = new RocketChatAPI(url); - client.setReconnectionStrategy(new ReconnectionStrategy(4, 2000)); - client.setPingInterval(15000); - client.connect(this); - RocketChatAPI.LOGGER.setLevel(Level.OFF); - messageCollector.setDomain(url); - } - - private void setAuthData(String authToken){ - // TODO some error handling? - String[] auth = authToken.split(":"); - username = auth[0]; - password = auth[1]; - if (auth.length>3){ - url = auth[2]+":"+auth[3]; - } - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - ChatRoom room = client.getChatRoomFactory().getChatRoomById(channel); - System.out.println("Sending File Message to : " + room.getRoomData().getRoomId()); - String newText = text.replace("\\n", "\n"); - Client textClient = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); - WebTarget target = textClient.target(url + "/api/v1/rooms.upload/" + room.getRoomData().getRoomId()); - try { - FileDataBodyPart filePart = new FileDataBodyPart("file", f); - if(f.getName().toLowerCase().contains("json")){ - filePart.setMediaType(MediaType.APPLICATION_JSON_TYPE); - } - FormDataMultiPart mp = new FormDataMultiPart(); - FormDataMultiPart multipart = (FormDataMultiPart) mp.field("msg", newText).field("description", "") - .bodyPart(filePart); - Response response = target.request().header("X-User-Id", client.getMyUserId()).header("X-Auth-Token", token) - .post(Entity.entity(multipart, multipart.getMediaType())); - System.out.println(response.getEntity().toString()); - mp.close(); - multipart.close(); - try { - java.nio.file.Files.deleteIfExists(Paths.get(f.getName())); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } catch (IOException e) { - System.out.println(e.getMessage()); - try { - java.nio.file.Files.deleteIfExists(Paths.get(f.getName())); - } catch (IOException g) { - // TODO Auto-generated catch block - g.printStackTrace(); - } - } - } - - @Override - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, String text, - Optional id) { - byte[] decodedBytes = java.util.Base64.getDecoder().decode(fileBody); - File file = new File(fileName + "." + fileType); - try { - FileUtils.writeByteArrayToFile(file, decodedBytes); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sendFileMessageToChannel(channel, file, text, id); - file.delete(); - } - - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - System.out.println(text); - ChatRoom room = client.getChatRoomFactory().getChatRoomById(channel); - System.out.println("Sending Message to : " + room.getRoomData().getRoomId()); - if (sendingMessage.get(channel) != null) { - while (sendingMessage.get(channel) == true) { - - } - } - sendingMessage.put(channel, true); - - room.getMembers(new GetMembersListener() { - - @Override - public void onGetRoomMembers(Integer arg0, List arg1, ErrorObject arg2) { - // TODO Auto-generated method stub - try { - String userName = ""; - String newText = text; - for (UserObject u : (ArrayList) arg1) { - if (!u.getUserId().equals(client.getMyUserId())) { - userName += u.getUserName() + ", "; - } - } - - if (userName.length() > 2) { - userName = userName.substring(0, userName.length() - 2); - } - System.out.println(username + newText); - newText = newText.replace("menteeName", userName); - newText = newText.replace("\\n", "\n"); - if (newText.length() > 5000) { - sendingMessage.put(channel, false); - try { - File tempFile = new File("message.txt"); - FileWriter writer = new FileWriter(tempFile); - writer.write(newText); - writer.close(); - room.uploadFile(tempFile, "message.txt", "", new FileListener() { - - @Override - public void onSendFile(RocketChatMessage arg0, ErrorObject arg1) { - // TODO Auto-generated method stub - } - - @Override - public void onUploadError(ErrorObject arg0, IOException arg1) { - room.sendMessage(arg0.getMessage()); - room.sendMessage(arg0.getReason()); - tempFile.delete(); - } - - @Override - public void onUploadProgress(int arg0, String arg1, String arg2, String arg3) { - // TODO Auto-generated method stub - - } - - @Override - public void onUploadStarted(String arg0, String arg1, String arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void onUploadComplete(int arg0, com.rocketchat.core.model.FileObject arg1, - String arg2, String arg3, String arg4) { - tempFile.delete(); - } - }); - } catch (IOException e) { - // TODO Auto-generated catch block - sendingMessage.put(channel, false); - e.printStackTrace(); - } - } else { - room.sendMessage(newText); - sendingMessage.put(channel, false); - } - } catch (Exception e) { - sendingMessage.put(channel, false); - e.printStackTrace(); - } - sendingMessage.put(channel, false); - } - - }); - - } - - @Override - public Vector getMessages() { - Vector messages = this.messageCollector.getMessages(); - return messages; - } - - @Override - public String getChannelByEmail(String email) { - List users = client.getDbManager().getUserCollection().getData(); - for (UserDocument u : users) { - // TODO Email Matching - return u.getName(); - } - return null; - } - - @Override - public void onGetRooms(List rooms, ErrorObject error) { - if (error == null) { - try { - // System.out.println("Available rooms: " + rooms.size()); - ChatRoomFactory factory = client.getChatRoomFactory(); - synchronized (factory) { - ArrayList roomList = factory.createChatRooms(rooms).getChatRooms(); - for (ChatRoom room : roomList) { - if (!activeSubscriptions.contains(room.getRoomData().getRoomId())) { - room.subscribeRoomMessageEvent(new SubscribeListener() { - @Override - public void onSubscribe(Boolean isSubscribed, String subId) { - - } - }, this); - activeSubscriptions.add(room.getRoomData().getRoomId()); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Override - public void onLogin(TokenObject token, ErrorObject error) { - if (error == null) { - System.out.println("Logged in successfully, returned token " + token.getAuthToken()); - client.getRooms(this); - this.token = token.getAuthToken(); - GetRoomListener grl = this; - if (checkRooms == null) { - if (shouldCheckRooms == false) { - shouldCheckRooms = true; - } - checkRooms = new Thread(new Runnable() { - @Override - public void run() { - try { - while (shouldCheckRooms) { - client.getRooms(grl); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - System.out.println("Thread created"); - checkRooms.start(); - } - - } else { - System.out.println("Got error " + error.getMessage()); - } - } - - @Override - public void onConnect(String sessionID) { - System.out.println("Connected to server."); - client.login(username, password, this); - } - - @Override - public void onConnectError(Exception arg0) { - System.out.println("R.C connection error: " + arg0.getMessage()); - // TODO Auto-generated method stub - if (checkRooms != null) { - shouldCheckRooms = false; - checkRooms = null; - activeSubscriptions = new HashSet(); - System.out.println("Thread stopped"); - } - } - - @Override - public void onDisconnect(boolean arg0) { - System.out.println("R.C disconnect : " + arg0); - // TODO Auto-generated method stub - if (checkRooms != null) { - shouldCheckRooms = false; - checkRooms = null; - activeSubscriptions = new HashSet(); - System.out.println("Thread stopped"); - } - } - - @Override - public void onSubscribe(Boolean arg0, String arg1) { - // System.out.println(arg1); - } - - public static int countWords(String s) { - - int wordCount = 0; - - boolean word = false; - int endOfLine = s.length() - 1; - - for (int i = 0; i < s.length(); i++) { - // if the char is a letter, word = true. - if (Character.isLetter(s.charAt(i)) && i != endOfLine) { - word = true; - // if char isn't a letter and there have been letters before, - // counter goes up. - } else if (!Character.isLetter(s.charAt(i)) && word) { - wordCount++; - word = false; - // last word of String; if it doesn't end with a non letter, it - // wouldn't count without this. - } else if (Character.isLetter(s.charAt(i)) && i == endOfLine) { - wordCount++; - } - } - return wordCount; - } - - protected String getTxtFile(String userId, String file) { - MiniClient textClient = new MiniClient(); - textClient.setConnectorEndpoint(url); - HashMap textClientHeader = new HashMap(); - textClientHeader.put("cookie", "rc_uid=" + userId + "; rc_token=" + token + "; "); - ClientResponse r = textClient.sendRequest("GET", file, "", MediaType.TEXT_PLAIN, MediaType.TEXT_PLAIN, - textClientHeader); - InputStream in = new ByteArrayInputStream(r.getRawResponse()); - StringWriter writer = new StringWriter(); - String encoding = StandardCharsets.UTF_8.name(); - String res = ""; - try { - IOUtils.copy(in, writer, encoding); - res = writer.toString(); - writer.close(); - in.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return res; - } - - protected String getFileBase64(String userId, String file) { - System.out.println(userId); - MiniClient textClient = new MiniClient(); - textClient.setConnectorEndpoint(url); - HashMap textClientHeader = new HashMap(); - textClientHeader.put("cookie", "rc_uid=" + userId + "; rc_token=" + token + "; "); - ClientResponse r = textClient.sendRequest("GET", file, "", MediaType.TEXT_PLAIN, "application/pdf", - textClientHeader); - return Base64.encodeBytes(r.getRawResponse()); - } - - protected byte[] getPDFFile(String userId, String file) { - MiniClient textClient = new MiniClient(); - textClient.setConnectorEndpoint(url); - HashMap textClientHeader = new HashMap(); - textClientHeader.put("cookie", "rc_uid=" + userId + "; rc_token=" + token + "; "); - ClientResponse r = textClient.sendRequest("GET", file, "", MediaType.TEXT_PLAIN, "application/pdf", - textClientHeader); - return r.getRawResponse(); - } - - protected int getStudentRole(String email) { - int role = 0; - PreparedStatement stmt = null; - Connection conn = null; - ResultSet rs = null; - try { - - conn = database.getDataSource().getConnection(); - stmt = conn.prepareStatement("SELECT role FROM users WHERE email=?"); - stmt.setString(1, email); - rs = stmt.executeQuery(); - while (rs.next()) - role = rs.getInt(1); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - if (rs != null) - rs.close(); - } catch (Exception e) { - } - ; - try { - if (stmt != null) - stmt.close(); - } catch (Exception e) { - } - ; - try { - if (conn != null) - conn.close(); - } catch (Exception e) { - } - ; - } - return role; - } - - protected String getStudentEmail(String userName) { - MiniClient textClient = new MiniClient(); - textClient.setConnectorEndpoint(url); - HashMap textClientHeader = new HashMap(); - textClientHeader.put("X-User-Id", client.getMyUserId()); - textClientHeader.put("X-Auth-Token", token); - ClientResponse r = textClient.sendRequest("GET", "api/v1/users.info?username=" + userName, "", - MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, textClientHeader); - System.out.println("response is" + r.getResponse()); - JSONObject userObject = new JSONObject(r.getResponse()); - JSONArray emails = userObject.getJSONObject("user").getJSONArray("emails"); - return emails.getJSONObject(0).getString("address"); - } - - @Override - public void onGetSubscriptions(List subscriptions, ErrorObject error) { - // Creating Logical ChatRooms using factory class - } - - - @Override - public void editMessage(String channel, String messageId, String message, Optional id){} - - @Override - public void onMessage(String arg0, RocketChatMessage message) { - ChatRoom room = client.getChatRoomFactory().getChatRoomById(message.getRoomId()); - synchronized (room) { - if (!message.getSender().getUserId().equals(client.getMyUserId())) { - String email = getStudentEmail(message.getSender().getUserName()); - System.out.println("Email: " + email); - System.out.println("Message: " + message.getMessage()); - - Type type = message.getMsgType(); - if (type.equals(Type.ATTACHMENT)) { - System.out.println("Handling attachement"); - JSONObject j = message.getRawJsonObject(); - String fileType = j.getJSONObject("file").getString("type"); - String fileName = j.getJSONObject("file").getString("name"); - System.out.println(j); - if (fileType.equals("text/plain") || fileType.equals("application/pdf") - || fileType.equals("image/png") || fileType.equals("audio/aac") || fileType.equals("audio/mpeg") || fileType.equals("audio/x-m4a")) { - String file = j.getJSONArray("attachments").getJSONObject(0).getString("title_link") - .substring(1); - JSONObject bodyJSON = new JSONObject(); - String fileBody = getFileBase64(client.getMyUserId(), file); - messageCollector.handle(message, fileBody, fileName, fileType, 0, - getStudentEmail(message.getSender().getUserName())); - } else { - messageCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); - } - } else { - messageCollector.handle(message, 0, getStudentEmail(message.getSender().getUserName())); - } - } - } - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken) { - super.sendBlocksMessageToChannel(channel, blocks, authToken); - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id){ - - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts) { - super.updateBlocksMessageToChannel(channel, blocks, authToken, ts); - } - - public RocketChatMessageCollector getMessageCollector() { - return messageCollector; - } - - @Override - public void close() { - shouldCheckRooms = false; - checkRooms = null; - activeSubscriptions = null; - System.out.println("Thread stopped"); - client.disconnect(); - // client = null; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java deleted file mode 100644 index 91a25241..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/RocketChatMessageCollector.java +++ /dev/null @@ -1,137 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.Instant; -import java.util.TimeZone; - -import org.json.JSONArray; - -import com.rocketchat.core.model.RocketChatMessage; -import com.rocketchat.core.model.RocketChatMessage.Type; - -public class RocketChatMessageCollector extends ChatMessageCollector { - - public void handle(RocketChatMessage message) { - Type type = message.getMsgType(); - if (type != null) { - if (type.equals(Type.TEXT)) { - try { - System.out.println("Handling text."); - JSONArray emails = message.getSender().getEmails(); - // System.out.println(emails.toString()); - String rid = message.getRoomId(); - String user = message.getSender().getUserName(); - String msg = replaceUmlaute(message.getMessage()); - ChatMessage cm = new ChatMessage(rid, user, msg); - // timestamp - cm.setTime(message.getMsgTimestamp().toInstant().toString()); - // domain - cm.setDomain(this.getDomain()); - - this.addMessage(cm); - System.out.println("Message added."); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - System.out.println("Unsupported type: " + type.toString()); - } - } else { - System.out.println("Skipped"); - } - } - - public void handle(RocketChatMessage message, int role, String email) { - Type type = message.getMsgType(); - if (type != null) { - if (type.equals(Type.TEXT)) { - try { - System.out.println("Handling text."); - JSONArray emails = message.getSender().getEmails(); - // System.out.println(emails.toString()); - String rid = message.getRoomId(); - String user = message.getSender().getUserName(); - String msg = replaceUmlaute(message.getMessage()); - ChatMessage cm = new ChatMessage(rid, user, msg); - System.out.println("Email of user is " + email); - cm.setEmail(email); - cm.setRole(role); - // timestamp - cm.setTime(message.getMsgTimestamp().toInstant().toString()); - // domain - cm.setDomain(this.getDomain()); - - this.addMessage(cm); - System.out.println("Message added."); - } catch (Exception e) { - e.printStackTrace(); - } - }else if(type.equals(Type.MESSAGE_EDITED)){ - try { - System.out.println("Handling edited message."); - JSONArray emails = message.getSender().getEmails(); - // System.out.println(emails.toString()); - String rid = message.getRoomId(); - String user = message.getSender().getUserName(); - String msg = replaceUmlaute(message.getMessage()); - ChatMessage cm = new ChatMessage(rid, user, msg); - System.out.println("Email of user is " + email); - cm.setEmail(email); - cm.setRole(role); - // timestamp - cm.setTime(message.getMsgTimestamp().toInstant().toString()); - // domain - cm.setDomain(this.getDomain()); - - this.addMessage(cm); - System.out.println("Edited message added."); - } catch (Exception e) { - e.printStackTrace(); - } - } - else { - System.out.println("Unsupported type: " + type.toString()); - } - } else { - System.out.println("Skipped"); - } - } - - public void handle(RocketChatMessage message, String fileBody, String fileName, String fileType, int role, - String email) { - Type type = message.getMsgType(); - if (type != null) { - if (type.equals(Type.ATTACHMENT)) { - try { - System.out.println("Handling Attachment."); - JSONArray emails = message.getSender().getEmails(); - System.out.println("rcket message is " + message); - String rid = message.getRoomId(); - System.out.println(rid); - String user = message.getSender().getUserName(); - String msg = replaceUmlaute(fileName); - ChatMessage cm = new ChatMessage(rid, user, msg, fileName, fileType, fileBody); - System.out.println("Email of user is " + email); - cm.setEmail(email); - cm.setRole(role); - - // timestamp - cm.setTime(message.getMsgTimestamp().toInstant().toString()); - - // domain - cm.setDomain(this.getDomain()); - - this.addMessage(cm); - System.out.println("Message added."); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - System.out.println("Unsupported type: " + type.toString()); - } - } else { - System.out.println("Skipped"); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java deleted file mode 100644 index 1cde8f44..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMediator.java +++ /dev/null @@ -1,588 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Optional; -import java.util.Vector; -import java.util.concurrent.TimeUnit; - -import javax.websocket.DeploymentException; -import javax.ws.rs.core.UriBuilder; - -// TODO: Currently needed because of class with the same name in this package -import com.slack.api.Slack; -import com.slack.api.methods.SlackApiException; -import com.slack.api.methods.response.users.UsersLookupByEmailResponse; -import com.slack.api.methods.response.chat.ChatPostMessageResponse; -import com.slack.api.methods.response.chat.ChatUpdateResponse; -import com.slack.api.methods.response.conversations.ConversationsListResponse; -import com.slack.api.methods.response.files.FilesUploadResponse; -import com.slack.api.methods.response.users.UsersConversationsResponse; -import com.slack.api.model.Conversation; -import com.slack.api.model.ConversationType; -import com.slack.api.rtm.RTMClient; -import com.slack.api.rtm.message.Message; -import com.slack.api.rtm.message.Message.MessageBuilder; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -import com.slack.api.methods.request.bots.*; - -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; - -public class SlackChatMediator extends EventChatMediator { - private Slack slack = null; - private RTMClient rtm = null; - private SlackChatMessageCollector messageCollector = new SlackChatMessageCollector(); - private String botUser; - // this variable is only good when using a bot in a private conversation - public static HashMap usersByChannel; - // Is needed to use the token when downloading user files - public static HashMap botTokens = new HashMap(); - // When files are sent, it is not clear whether a bot or user sent them, - // differentiate using the id of the bot! - public static ArrayList botIDs = new ArrayList(); - - - // store the mediators so that you can restart them all at the same time - public static HashSet mediators = new HashSet(); - - public SlackChatMediator(String authToken) throws IOException, DeploymentException, AuthTokenException { - - super(authToken); - this.slack = new Slack(); - try{ - this.rtm = this.slack.rtm(authToken); - } catch (Exception e){ - if(e.toString().toLowerCase().contains("invalid_auth")){ - throw new AuthTokenException("Authentication Token is faulty!"); - } else throw e; - } - usersByChannel = new HashMap(); - this.rtm.addMessageHandler(messageCollector); - this.rtm.connect(); - ArrayList types = new ArrayList(); - types.add(ConversationType.IM); - types.add(ConversationType.MPIM); - // Search for every channelId a bot has access to and keep the token - try { - UsersConversationsResponse test = (slack.methods() - .usersConversations(req -> req.token(authToken).types(types))); - for (Conversation c : test.getChannels()) { - botTokens.put(c.getId(), authToken); - // Save users' email address - usersByChannel.put(c.getId(), slack.methods().usersInfo(req -> req.token(authToken).user(c.getUser())) - .getUser().getProfile().getEmail()); - } - } catch (IOException | SlackApiException e) { - System.out.println("Could not retrieve bot channels because of " + e - + ". The bot will not be able to download sent files..."); - } - this.botUser = rtm.getConnectedBotUser().toString(); - botIDs.add(rtm.getConnectedBotUser().getId()); - messageCollector.setDomain("https://slack.com/"); - mediators.add(this); - System.out.println(this.botUser + " connected."); - } - - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, - Optional id) { - JSONObject jsonBlocks = new JSONObject(); - jsonBlocks.put("id", System.currentTimeMillis()); - jsonBlocks.put("channel", channel); - jsonBlocks.put("blocks", blocks); - jsonBlocks.put("ts", ts); - id.ifPresent(s -> jsonBlocks.put("id", Long.parseLong(s))); - System.out.println(jsonBlocks); - try { - String line = null; - StringBuilder sb = new StringBuilder(); - String res = null; - URL url = UriBuilder.fromPath("https://slack.com/api/chat.update").build().toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Authorization", "Bearer " + authToken); - connection.setRequestProperty("Content-type", "application/json; charset=utf-8"); - connection.setDoOutput(true); - connection.connect(); - byte[] outputBytes = jsonBlocks.toString().getBytes("UTF-8"); - OutputStream os = connection.getOutputStream(); - os.write(outputBytes); - os.close(); - - BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); - - while ((line = rd.readLine()) != null) { - sb.append(line); - } - res = sb.toString(); - System.out.println(res); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - MessageBuilder msg = Message.builder().id(System.currentTimeMillis()).channel(channel).text(text); - if (id.isPresent()) { - msg.id(Long.parseLong(id.get())); - } - String message = msg.build().toJSONString(); - try { - // make sure that the bot's name and profile pic is used - String userId = (slack.methods().authTest(req -> req.token(authToken))).getUserId(); - String url = slack.methods().usersInfo(req -> req.token(authToken).user(userId)).getUser().getProfile() - .getImageOriginal(); - String name = slack.methods().usersInfo(req -> req.token(authToken).user(userId)).getUser().getName(); - - ChatPostMessageResponse response = slack.methods(authToken).chatPostMessage(req -> req.channel(channel) // Channel - // ID - .text(text).iconUrl(url).username(name)); - System.out.println("Message sent: " + response.isOk()); - } catch (Exception e) { - this.messageCollector.setConnected(false); - reconnect(); - rtm.sendMessage(message); - System.out.println("Sent message with Exception: " + e.getMessage()); - if (e.getMessage().toLowerCase().equals("timeout")) { - sendMessageToChannel(channel, text, null, "text", id); - } - } - try { - // get the users email address if not done at the beginning (should only happen - // if a new user joined the - // space) - if (usersByChannel.get(channel) == null) { - String user = slack.methods().conversationsInfo(req -> req.token(authToken).channel(channel)) - .getChannel().getUser(); - usersByChannel.put(channel, slack.methods().usersInfo(req -> req.token(authToken).user(user)).getUser() - .getProfile().getEmail()); - } - } catch (Exception e) { - System.out.println("Could not extract Email for reason + " + e); - } - - } - - // @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, Optional id) { - // System.out.println("sending blocks now..."); - - JSONObject jsonBlocks = new JSONObject(); - jsonBlocks.put("id", System.currentTimeMillis()); - jsonBlocks.put("channel", channel); - jsonBlocks.put("blocks", blocks); - id.ifPresent(s -> jsonBlocks.put("id", Long.parseLong(s))); - try { - String line = null; - StringBuilder sb = new StringBuilder(); - String res = null; - URL url = UriBuilder.fromPath("https://slack.com/api/chat.postMessage").build().toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Authorization", "Bearer " + authToken); - connection.setRequestProperty("Content-type", "application/json;charset=utf-8"); - connection.setDoOutput(true); - connection.connect(); - byte[] outputBytes = jsonBlocks.toString().getBytes("UTF-8"); - OutputStream os = connection.getOutputStream(); - os.write(outputBytes); - os.close(); - - BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); - - while ((line = rd.readLine()) != null) { - sb.append(line); - } - res = sb.toString(); - System.out.println(res); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - public void editMessage(String channel, String messageId, String message, Optional id) { - System.out.println("now trying editing..."); - MessageBuilder msg = Message.builder() - .id(System.currentTimeMillis()) - .channel(channel); - - if (id.isPresent()) { - msg.id(Long.parseLong(id.get())); - } - String msgString = msg.build().toJSONString(); - - try { - ChatUpdateResponse response = slack.methods(authToken).chatUpdate(req -> req.channel(channel) - .blocksAsString(message).ts(messageId)); - System.out.println("Chat updated: " + response.isOk()); - } catch (Exception e) { - this.messageCollector.setConnected(false); - reconnect(); - rtm.sendMessage(msgString); - System.out.println("Sent message with Exception: " + e.getMessage()); - if (e.getMessage().toLowerCase().equals("timeout")) { - // TODO recursive call not the best idea - editMessage(channel, messageId, message, id); - } - try { - // get the users email address if not done at the beginning (should only happen - // if a new user joined the - // space) - if (usersByChannel.get(channel) == null) { - String user = slack.methods().conversationsInfo(req -> req.token(authToken).channel(channel)) - .getChannel().getUser(); - usersByChannel.put(channel, - slack.methods().usersInfo(req -> req.token(authToken).user(user)).getUser() - .getProfile().getEmail()); - } - } catch (Exception exception) { - System.out.println("Could not extract Email for reason + " + exception); - } - } - } - - // static for calling from `SlackChatMessageCollector` - public static ChatMessage parseSlackMessage(JSONObject o) throws InvalidChatMessageException { - String channel = o.getAsString("channel"); - String user = o.getAsString("user"); - String text = o.getAsString("text"); - // used to identity the message (in case it gets edited) - String time = o.getAsString("ts"); - - // System.out.println(user); - // System.out.println(channel); - // System.out.println(text); - - if (o.containsKey("subtype")) { - if (o.getAsString("subtype").equals("message_changed")) { - JSONParser parser = new JSONParser(); - System.out.println("message subtype message_changed recognized..."); - - try { - String currMessage = o.getAsString("message"); - String prevMessage = o.getAsString("previous_message"); - - JSONObject currMessageJson = (JSONObject) parser.parse(currMessage); - - System.out.println("now checking who edited answer..."); - if (currMessageJson.containsKey("subtype")) { - // check if the bot edited an answer - System.out.println("subtype: " + currMessageJson.getAsString("subtype")); - if (currMessageJson.getAsString("subtype").equals("bot_message")) { - System.out.println("bot changed answer, ignore"); - throw new InvalidChatMessageException(); - } - } - System.out.println("user edited answer"); - // user edited an answer - user = currMessageJson.getAsString("user"); - text = currMessageJson.getAsString("text"); - - // System.out.println("creating new chat message: c: " + channel + " u: " + user - // + " t: " + text + " cm: " + currMessage + " pm: " + prevMessage + " ts: " + - // ts); - ChatMessage msg = new ChatMessage(channel, user, text, time); - msg.setCurrMessage(currMessage); - msg.setPreviousMessage(prevMessage); - System.out.println("returning msg"); - System.out.println(msg); - return msg; - } catch (Exception e) { - e.printStackTrace(); - } - - } - } - - // Second part of the if clause if bcs the bot would for some reason react to - // its own message - if (o.get("files") != null && !botIDs.contains(o.get("user"))) { - for (int i = 0; i < ((JSONArray) o.get("files")).size(); i++) { - // left it as for(...), but only sending 1 file at a time will be accepted - // currently - try { - URL url = new URL(((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("url_private")); - HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); - httpConn.addRequestProperty("Authorization", "Bearer " + botTokens.get(channel)); - InputStream in = httpConn.getInputStream(); - FileOutputStream fileOutputStream = new FileOutputStream( - ((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("title")); - byte dataBuffer[] = new byte[Integer - .valueOf(((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("size"))]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, Integer - .valueOf(((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("size")))) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } - String body = Base64.getEncoder() - .encodeToString(Files.readAllBytes( - new File(((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("title")) - .toPath())); - fileOutputStream.close(); - Files.deleteIfExists( - Paths.get(((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("title"))); - return new ChatMessage(channel, user, text, - ((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("title"), - ((JSONObject) ((JSONArray) o.get("files")).get(i)).getAsString("filetype"), body); - } catch (Exception e) { - System.out.println("Could not extract File for reason " + e); - } - - } - - } - if (channel == null || user == null || text == null) { - throw new InvalidChatMessageException(); - } - - return new ChatMessage(channel, user, text, time); - } - - public static String fetchEmailByUserId(String userId) { - Slack slackObj = new Slack(); - for (String token : botTokens.values()) { - try { - String email = slackObj.methods().usersInfo(req -> req.token(token).user(userId)).getUser().getProfile() - .getEmail(); - if (email != null) { - System.out.println("Slack group, extracted following email: " + email); - return email; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return "No Email?"; - - } - - @Override - public Vector getMessages() { - Vector messages = this.messageCollector.getMessages(); - if (!this.messageCollector.isConnected()) { - reconnect(); - } - return messages; - } - - /* - * public String getEmails(String channel) { - * - * if(usersByChannel.get(channel) == null) - * { - * return "No Email available at the moment"; - * } - * System.out.println("Email is " + usersByChannel.get(channel)); - * return usersByChannel.get(channel); // slack.methods().usersInfo(req -> - * req.token(authToken).user(user)).getUser().getProfile().getEmail(); - * } - */ - public String getBotUser() { - return this.botUser.toString(); - } - - @Override - public String getChannelByEmail(String email) { - Slack slack = Slack.getInstance(); - try { - UsersLookupByEmailResponse lookupByEmailResponse = slack.methods(this.authToken) - .usersLookupByEmail(req -> req.email(email)); - String userId = lookupByEmailResponse.getUser().getId(); - ConversationsListResponse listResponse = slack.methods(this.authToken) - .conversationsList(req -> req.excludeArchived(true).types(Arrays.asList(ConversationType.IM))); - Conversation im = listResponse.getChannels().stream().filter(c -> c.getUser().equals(userId)).findFirst() - .get(); - return im.getId(); - } catch (IOException | SlackApiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - public SlackChatMessageCollector getMessageCollector() { - return messageCollector; - } - - private void reconnect() { - System.out.println("Reconnecting all bots!"); - if (!this.messageCollector.isConnected()) { - for (SlackChatMediator scm : mediators) { - scm.messageCollector.setConnected(false); - System.out.println("Message Collector is connected: " + scm.messageCollector.isConnected()); - reconnect(scm); - } - } - - } - - public static void reconnect(SlackChatMediator scm) { - System.out.println("Reconnecting:" + scm.botUser); - if (!scm.messageCollector.isConnected()) { - try { - System.out.println(scm.botUser + " is reconnecting."); - scm.rtm.close(); - try { - TimeUnit.SECONDS.sleep(30); - } catch (InterruptedException i) { - i.printStackTrace(); - } - scm.slack = new Slack(); - scm.rtm = scm.slack.rtm(scm.authToken); - scm.rtm.removeMessageHandler(scm.messageCollector); - scm.messageCollector = new SlackChatMessageCollector(); - scm.rtm.addMessageHandler(scm.messageCollector); - scm.rtm.connect(); - System.out.println(scm.messageCollector.isConnected() + scm.rtm.getConnectedBotUser().toString()); - if (!scm.rtm.getConnectedBotUser().toString().equals(scm.botUser)) { - - System.out.println("Bot not online"); - scm.reconnect(); - } else { - scm.botUser = scm.rtm.getConnectedBotUser().toString(); - scm.messageCollector.setConnected(true); - - System.out.println(scm.botUser + " reconnected."); - - } - } catch (IOException | DeploymentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - try { - TimeUnit.SECONDS.sleep(30); - } catch (InterruptedException i) { - i.printStackTrace(); - } - reconnect(scm); - } catch (Exception e) { - e.printStackTrace(); - try { - TimeUnit.SECONDS.sleep(30); - } catch (InterruptedException i) { - i.printStackTrace(); - } - reconnect(scm); - } - } - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - ArrayList channels = new ArrayList(); - channels.add(channel); - FilesUploadResponse response2; - try { - response2 = slack.methods(authToken).filesUpload(req -> req.channels(channels).file(f) - .content("Pretty stuff").filename(f.getName()).title(f.getName()).initialComment(text)); - System.out.println("File sent: " + response2.isOk() + text); - } catch (IOException | SlackApiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - try { - Files.deleteIfExists(Paths.get(f.getName())); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public void close() { - try { - this.rtm.close(); - mediators.remove(this); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.slack = null; - } - - @Override - public void handleEvent(JSONObject action) { - System.out.println("action: " + action); - JSONParser p = new JSONParser(); - - try { - System.out.println("now trying to handle message..."); - String ts = ((JSONObject) p.parse(action.getAsString("container"))).getAsString("message_ts"); - String channel = ((JSONObject) p.parse(action.getAsString("channel"))).getAsString("id"); - String user = ((JSONObject) p.parse(action.getAsString("user"))).getAsString("id"); - String text = ""; - - JSONArray actions = (JSONArray) p.parse(action.getAsString("actions")); - for (Object actionsObject : actions) { - String selectedOptionsString = ((JSONObject) actionsObject).getAsString("selected_options"); - String selectedOptionString = ((JSONObject) actionsObject).getAsString("selected_option"); - if (selectedOptionsString != null) { - // multiple choice with one or more than one selected option - // System.out.println("selected options string: " + selectedOptionsString); - JSONArray selectedOptionsJson = (JSONArray) p.parse(selectedOptionsString); - text = selectedOptionsJson.toString(); - - } else if (selectedOptionString != null) { - // single choice with one selected option (possible) - // System.out.println("selected option: " + selectedOptionString); - JSONObject selectedOptionJson = (JSONObject) p.parse(selectedOptionString); - - String textString = selectedOptionJson.getAsString("text"); - JSONObject textJson = (JSONObject) p.parse(textString); - text += textJson.getAsString("text"); - - } else { - // System.out.println("No selectedOption and no selectedOptions."); - System.out.println("No selectedOption and no selectedOptions. Just a normal button press."); - - String textString = ((JSONObject) actionsObject).getAsString("text"); - JSONObject textJson = (JSONObject) p.parse(textString); - text += textJson.getAsString("text"); - } - } - - System.out.println("Assembled text from triggerButton is: " + text); - // remove the last "," - if ((String.valueOf(text.charAt(text.length() - 1)).equals(","))) { - System.out.println("inside removing last comma"); - text = text.substring(0, text.length() - 1); - } - - ChatMessage chatMessage = new ChatMessage(channel, user, text, ts); - - // set email, since it is not passed on in body - chatMessage.setEmail(user); - - messageCollector.addMessage(chatMessage); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, - HashMap hashMap, Optional optional) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'sendBlocksMessageToChannel'"); - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMessageCollector.java deleted file mode 100644 index e165e54d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/SlackChatMessageCollector.java +++ /dev/null @@ -1,45 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import com.slack.api.rtm.*; - -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; - -public class SlackChatMessageCollector extends ChatMessageCollector implements RTMMessageHandler { - public void handle(String messageJsonString) { - System.out.println("Received message: " + messageJsonString); - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject messageJson; - try { - messageJson = (JSONObject) p.parse(messageJsonString); - String type = messageJson.getAsString("type"); - System.out.println("Type Check"); - if (type != null) { - if (type.equals("message")) { - ChatMessage message; - message = SlackChatMediator.parseSlackMessage(messageJson); - if (SlackChatMediator.usersByChannel.get(message.getChannel()) != null) { - message.setEmail(SlackChatMediator.usersByChannel.get(message.getChannel())); - } else { - message.setEmail(SlackChatMediator.fetchEmailByUserId(message.getUser())); - } - System.out.println("message: " + message); - // If bot sent file to user, don't add message - if (!SlackChatMediator.botIDs.contains(messageJson.get("user"))) { - this.addMessage(message); - } - } else if (type.equals("goodbye")) { - System.out.println("Slack client disconnected"); - this.setConnected(false); - - } - } else { - System.out.println("Skipped"); - } - } catch (ParseException | InvalidChatMessageException e) { - // TODO We may want to handle other types of messages as well. - System.out.println("Invalid message skipped"); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/StateContainer.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/StateContainer.java deleted file mode 100644 index 78bd9f2e..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/StateContainer.java +++ /dev/null @@ -1,9 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; - -public abstract class StateContainer { - - public abstract IncomingMessage getIntentState(String channel, String user); - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramChatMediator.java deleted file mode 100644 index 7e02a377..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramChatMediator.java +++ /dev/null @@ -1,426 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Optional; -import java.util.Vector; - -import javax.ws.rs.core.MediaType; - -import com.pengrad.telegrambot.model.request.*; -import com.pengrad.telegrambot.request.*; -import jnr.ffi.annotations.In; -import net.minidev.json.JSONArray; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; -import org.apache.commons.io.IOUtils; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.pengrad.telegrambot.TelegramBot; -import com.pengrad.telegrambot.model.File; -import com.pengrad.telegrambot.model.request.ChatAction; -import com.pengrad.telegrambot.model.request.ReplyKeyboardRemove; -import com.pengrad.telegrambot.request.GetFile; -import com.pengrad.telegrambot.request.GetMe; -import com.pengrad.telegrambot.request.SendChatAction; -import com.pengrad.telegrambot.request.SendDocument; -import com.pengrad.telegrambot.request.SendMessage; -import com.pengrad.telegrambot.response.BaseResponse; -import com.pengrad.telegrambot.response.GetFileResponse; -import com.pengrad.telegrambot.response.GetMeResponse; - -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import net.minidev.json.JSONObject; - -/** - * The TelegramChatMediator handles the communication with the Telegram - * Messenger Application. This includes the parsing of incoming event data and - * the sending of data to telegram channels. - * - */ -public class TelegramChatMediator extends EventChatMediator { - - TelegramBot bot; - private TelegramMessageCollector messageCollector; - - /** - * URL address of the SBF manager service - */ - private String url; - MiniClient client; - - public TelegramChatMediator(String authToken) throws AuthTokenException{ - super(authToken); - try{ - this.bot = new TelegramBot(authToken); - } catch (Exception e){ - if(e.toString().toLowerCase().contains("404")){ - throw new AuthTokenException("Authentication Token is faulty!"); - } else throw e; - - } - this.client = new MiniClient(); - client.setConnectorEndpoint("https://api.telegram.org/bot" + authToken); - messageCollector = new TelegramMessageCollector(); - } - - @Override - public Vector getMessages() { - return messageCollector.getMessages(); - } - - /** - * Handle incoming telegram event message. - * - * @param event telegram event as json object - * @see Getting - * Telegram Updates - * - */ - @Override - public void handleEvent(JSONObject event) { - assert event != null : "jsonobject event parameter is null"; - - //System.out.println("event.toString: " + event.toString()); - try { - String messageString = ""; - String data = ""; - // check if a button click was detected - if(event.containsKey("callback_query")){ - System.out.println("inside callback_query"); - JSONObject callback_query = (JSONObject) event.get("callback_query"); - messageString = callback_query.getAsString("message"); - // the field data is defined when creating a button to identify the button that was clicked - data = callback_query.getAsString("data"); - } - else if(event.containsKey("edited_message")){ - System.out.println("inside edited message"); - messageString = event.getAsString("edited_message"); - } - else{ - messageString = event.get("message").toString(); - } - - JSONParser p = new JSONParser(); - JSONObject message = (JSONObject) p.parse(messageString); - JSONObject chat = (JSONObject) message.get("chat"); - JSONObject from = (JSONObject) message.get("from"); - JSONObject document = (JSONObject) message.get("document"); - JSONObject audio = (JSONObject) message.get("audio"); - String channel = chat.getAsString("id"); - String user = from.getAsString("first_name"); - String text = message.getAsString("text"); - String messageId = message.getAsString("message_id"); - if(event.containsKey("callback_query")){ - // the data field can be used to know which button was clicked - // (the text returned is not the text from the button, but the text above the button, therefore irrelevant) - text = data; - } - - String timestamp = message.getAsString("date"); - - if (channel == null || user == null || (text == null && document == null) || timestamp == null || messageId == null) - throw new InvalidChatMessageException("missing message fields"); - - this.showAction(channel, ChatAction.typing); - - // message with document - if (document != null) { - String fileName = document.getAsString("file_name"); - String mimeType = document.getAsString("mime_type"); - String fileId = document.getAsString("file_id"); - String fileBody = getFile(fileId); - messageCollector - .addMessage(new ChatMessage(channel, user, text, timestamp, messageId, fileName, mimeType, fileBody)); - } - else if(audio !=null){ - String fileId = audio.getAsString("file_id"); - String mimeType = audio.getAsString("mime_type"); - String fileBody = getFile(fileId); - messageCollector.addMessage(new ChatMessage(channel, user, text, timestamp, messageId, mimeType, fileBody)); - } - else { - messageCollector.addMessage(new ChatMessage(channel, user, text, timestamp, messageId)); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * Registers to receive push notifications from telegram - * - * @param url Address of bot url - * @see Setting Telegram - * Webhook - */ - public void settingWebhook(String url) throws AuthTokenException{ - System.out.println("poppo"); - this.url = url; - assert url != null : "url not initialized"; - assert !url.contentEquals("") : "empty url"; - - String path = "/sbfmanager/bots/events/telegram/"; - if (url.endsWith("/sbfmanager")) { - path = "/bots/events/telegram/"; - } - - System.out.println("Setting Webhook"); - ClientResponse result = client.sendRequest("GET", "setWebhook?url=" + url + path + super.authToken, - MediaType.TEXT_PLAIN); - if(result.getHttpCode() == 404){ - throw new AuthTokenException("Authentication Token is faulty!"); - } - System.out.println(result.getResponse()); - } - - public String getBotName() { - GetMe request = new GetMe(); - GetMeResponse response = bot.execute(request); - if (response.isOk() && response.user() != null) { - - String username = response.user().username(); - System.out.println("request botname: " + username); - return username; - } - - return null; - } - - /** - * Sends a plain text message to telegram messenger channel - */ - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - - System.out.println("send plain message to telegram channel " + channel + ", size: " + text.length()); - assert channel != null; - assert text != null; - - SendMessage request = new SendMessage(channel, text); - BaseResponse res = bot.execute(request); - - } - - @Override - public void sendFileMessageToChannel(String channel, String fileBody, String fileName, String fileType, String text, - Optional id) { - String caption = text; - System.out.println("Send File to Telegram channel: " + channel); - - try { - - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - JsonParser jp = new JsonParser(); - JsonElement je = jp.parse(fileBody); - fileBody = gson.toJson(je); - System.out.println(fileBody.substring(0, 160)); - - } catch (Exception e) { - e.printStackTrace(); - } - - byte[] bytes = fileBody.getBytes(StandardCharsets.UTF_8); - SendDocument request = new SendDocument(channel, bytes); - - if (!caption.contentEquals("")) - request.caption(caption); - if (fileName != null && !fileName.contentEquals("")) - request.fileName(fileName); - - request.replyMarkup(new ReplyKeyboardRemove()); - BaseResponse res = bot.execute(request); - System.out.println(String.valueOf(res.isOk()) + " " + res.errorCode() + " " + res.description()); - } - - @Override - public void sendFileMessageToChannel(String channel, java.io.File f, String text, Optional id) { - String caption = ""; - System.out.println("Send File to Telegram channel: " + channel); - - SendDocument request = new SendDocument(channel, f); - - if (!caption.contentEquals("")) - request.caption(caption); - - request.replyMarkup(new ReplyKeyboardRemove()); - BaseResponse res = bot.execute(request); - System.out.println(String.valueOf(res.isOk()) + " " + res.errorCode() + " " + res.description()); - } - - @Override - public String getChannelByEmail(String email) { - return null; - } - - @Override - public void close() { - - } - - private String getFile(String fileId) { - - GetFile request = new GetFile(fileId); - GetFileResponse response = bot.execute(request); - File file = response.file(); - System.out.println("file received"); - String path = "https://api.telegram.org/file/bot" + authToken + "/" + file.filePath(); - URL url; - String data = null; - try { - url = new URL(path); - data = IOUtils.toString(url); - - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return data; - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - - System.out.println("send interactive message to telegram channel " + channel); - assert channel != null; - assert blocks != null; - - JSONParser p = new JSONParser(); - - try{ - JSONObject blocksJO = (JSONObject) p.parse(blocks); - String text = blocksJO.getAsString("text"); - String inline_keyboard = blocksJO.getAsString("inline_keyboard"); - - InlineKeyboardMarkup markup = parseInlineKeyboardMarkup(inline_keyboard); - - SendMessage request = new SendMessage(channel, text); - request.replyMarkup(markup); - - BaseResponse res = bot.execute(request); - } catch(Exception e){ - e.printStackTrace(); - } - - } - - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id){ - - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts) { - super.updateBlocksMessageToChannel(channel, blocks, authToken, ts); - } - - private InlineKeyboardMarkup parseInlineKeyboardMarkup(String blocks){ - JSONParser p = new JSONParser(); - try{ - JSONArray blocksJA = (JSONArray) p.parse(blocks); - - InlineKeyboardButton[][] allButtons = new InlineKeyboardButton[blocksJA.size()][]; - - int i = 0; - for(Object o : blocksJA){ - JSONArray currO = (JSONArray) o; - InlineKeyboardButton[] currButtons = new InlineKeyboardButton[currO.size()]; - - int x = 0; - for(Object so : currO){ - JSONObject currSO = (JSONObject) so; - String text = currSO.getAsString("text"); - // currently used, since passed on unicodes get parsed wrong - // will be fixed soon - text = text.replaceAll(":check:", "\u2713"); - InlineKeyboardButton button = new InlineKeyboardButton(text); - button.callbackData(currSO.getAsString("callback_data")); - if(currSO.containsKey("url")){ - button.url(currSO.getAsString("url")); - } - currButtons[x] = button; - x++; - } - - allButtons[i] = currButtons; - i++; - } - - InlineKeyboardMarkup markup = new InlineKeyboardMarkup(allButtons); - return markup; - } catch (Exception e){ - e.printStackTrace(); - return null; - } - } - - public void editMessage(String channel, String messageId, String message, Optional id) { - - System.out.println("editing telegram message with id " + messageId + " and new message text " + message); - - try{ - JSONParser p = new JSONParser(); - JSONObject messageTextJO = (JSONObject) p.parse(message); - String text = messageTextJO.getAsString("text"); - - String inline_keyboard = ""; - try{ - inline_keyboard = messageTextJO.getAsString("inline_keyboard"); - } catch (Exception ex){ - // create empty inline keyboard - inline_keyboard = "[[]]"; - } - - Object chatId = channel; - int messageIdInt = Integer.parseInt(messageId); - System.out.println("text: " + text + " inline keyboard: " + inline_keyboard); - EditMessageText request = new EditMessageText(chatId, messageIdInt, text); - - InlineKeyboardMarkup markup = parseInlineKeyboardMarkup(inline_keyboard); - request.replyMarkup(markup); - - BaseResponse res = bot.execute(request); - System.out.println("res: " + String.valueOf(res.isOk()) + " " + res.errorCode() + " " + res.description()); - } catch(Exception e){ - System.out.println("editing message did not work"); - e.printStackTrace(); - } - - } - - public TelegramMessageCollector getMessageCollector() { - return messageCollector; - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken) { - sendBlocksMessageToChannel(channel, blocks, authToken, null, Optional.empty()); - } - - /** - * Shows an indication to the user about what the next bots action is - * - * @param channel id of channel indication should be shown - * @param action type of indication shown - * @return request was successful (true) or failed (false) - */ - public boolean showAction(String channel, ChatAction action) { - - SendChatAction typingAction = new SendChatAction(channel, action); - BaseResponse response = this.bot.execute(typingAction); - return response.isOk(); - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramMessageCollector.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramMessageCollector.java deleted file mode 100644 index b4acb11d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/TelegramMessageCollector.java +++ /dev/null @@ -1,10 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat; - -public class TelegramMessageCollector extends ChatMessageCollector { - - public void handle(String convid, String userEmail, String message) { - String text = replaceUmlaute(message.replaceAll("\\<.*?>", "")); - addMessage(new ChatMessage(convid, userEmail, text)); - //System.out.println("Debug --- Collector: " + messages.toString()); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubAppHelper.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubAppHelper.java deleted file mode 100644 index 9838b2b7..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubAppHelper.java +++ /dev/null @@ -1,105 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.github; - -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import org.kohsuke.github.GHAppInstallation; -import org.kohsuke.github.GitHub; -import org.kohsuke.github.GitHubBuilder; - -import javax.xml.bind.DatatypeConverter; -import java.io.IOException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Date; - -/** - * A GitHub app can be installed multiple times (e.g., within different organizations or repositories). - * To use the GitHub API for an app installation, we need an access token for this app installation. - * For requesting this access token, a JWT is needed. This JWT allows to authenticate as a GitHub app. - * The JWT needs to be signed using the app's private key (from general app settings). - * - * See https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps - */ -public class GitHubAppHelper { - - /** - * Id of the GitHub app. - */ - private int gitHubAppId; - - /** - * Private key used to sign JWTs. - */ - private Key privateKey; - - /** - * - * @param gitHubAppId Id of the GitHub app - * @param pkcs8PrivateKey Private key of GitHub app (already needs to be converted to pkcs8) - * @throws GitHubAppHelperException - */ - public GitHubAppHelper(int gitHubAppId, String pkcs8PrivateKey) throws GitHubAppHelperException { - this.gitHubAppId = gitHubAppId; - - byte[] pkcs8PrivateKeyBytes = DatatypeConverter.parseBase64Binary(pkcs8PrivateKey); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8PrivateKeyBytes); - try { - this.privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec); - } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { - throw new GitHubAppHelperException(e.getMessage()); - } - } - - /** - * Returns a GitHub object that has access to the given repository. - * @param repositoryFullName Full name of the repository, containing both owner and repository name. - * @return GitHub object that has access to the given repository. - */ - public GitHub getGitHubInstance(String repositoryFullName) { - String ownerName = repositoryFullName.split("/")[0]; - String repoName = repositoryFullName.split("/")[1]; - - try { - // first create GitHub object using a JWT (this is needed to request an access token for an app installation) - GitHub gitHub = new GitHubBuilder().withJwtToken(generateJWT()).build(); - - // get app installation for given repository (getInstallationByRepository requires a JWT) - GHAppInstallation installation = gitHub.getApp().getInstallationByRepository(ownerName, repoName); - - // create a GitHub object with app installation token - return new GitHubBuilder().withAppInstallationToken(installation.createToken().create().getToken()).build(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - /** - * Generates a JWT and signs it with the app's private key. - * @return JWT - */ - private String generateJWT() { - long nowMillis = System.currentTimeMillis(); - Date now = new Date(nowMillis); - Date expiration = new Date(nowMillis + 60000); - return Jwts.builder() - .setIssuedAt(now) // issue now - .setExpiration(expiration) // expiration time of JWT - .setIssuer(String.valueOf(gitHubAppId)) // app id needs to be used as issuer - .signWith(this.privateKey, SignatureAlgorithm.RS256) // sign with app's private key - .compact(); - } - - /** - * General exception that is thrown if something related to the GitHubAppHelper is not working. - */ - public class GitHubAppHelperException extends Exception { - public GitHubAppHelperException(String message) { - super(message); - } - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubChatMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubChatMediator.java deleted file mode 100644 index 4162cecf..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubChatMediator.java +++ /dev/null @@ -1,236 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.github; - -import i5.las2peer.services.socialBotManagerService.chat.AuthTokenException; -import i5.las2peer.services.socialBotManagerService.chat.ChatMessage; -import i5.las2peer.services.socialBotManagerService.chat.ChatMessageCollector; -import i5.las2peer.services.socialBotManagerService.chat.EventChatMediator; -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import net.minidev.json.JSONObject; -import org.kohsuke.github.GitHub; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; -import java.util.Vector; - -/** - * Parent class for GitHub issue and pull request chat mediators. - *

- * In the GitHubChatMediator, a channel is a comment section of an issue or a pull request. - * Therefore, the "messenger channel" is defined as follows: - * [Owner name]/[Repo name]#[Issue or PR number] - */ -public abstract class GitHubChatMediator extends EventChatMediator { - - /** - * Message collector: New comments are added to the collector in {@link #handleEvent(JSONObject) handleEvent}. - */ - private ChatMessageCollector messageCollector; - - /** - * Helper for the GitHub app that is used by the chat mediator. - */ - private GitHubAppHelper gitHubAppHelper; - - /** - * Id of the GitHub app that is used by the chat mediator. - */ - private int gitHubAppId; - - /** - * Event name for new comments is the same for both issues and pull requests. - */ - private final String eventNameItemComment = "issue_comment"; - - /** - * The action name for new comments is the same for both issues and pull requests. - */ - private final String actionNameItemComment = "created"; - - /** - * Event name for a newly opened issue or pull request. - */ - protected String eventNameItemOpened; - - /** - * Action name for a newly opened issue or pull request. - */ - private final String actionNameItemOpened = "opened"; - - /** - * Name of the field that contains the comment information (same for issues and pull requests). - */ - private final String itemNameComment = "issue"; - - /** - * Name of the field that contains the text of a newly opened issue or pull request. - */ - protected String itemNameOpened; - - /** - * Constructor for GitHub chat mediators. - * - * @param authToken Format: [GitHub app id]:[GitHub app private key in pkcs8] - * @throws GitHubAppHelper.GitHubAppHelperException If something related to the GitHubAppHelper is not working. - * @throws AuthTokenException If format of {@code authToken} is incorrect. - */ - public GitHubChatMediator(String authToken) throws GitHubAppHelper.GitHubAppHelperException, AuthTokenException { - super(authToken); - - // use default message collector - this.messageCollector = new ChatMessageCollector(); - - // check that authToken contains app id and private key - String[] parts = authToken.split(":"); - if (parts.length != 2) { - throw new AuthTokenException("Incorrect auth information, format should be: " + - "[GitHub app id]:[GitHub app private key in pkcs8]"); - } - - // get app id and private key - this.gitHubAppId = Integer.parseInt(parts[0]); - String pkcs8PrivateKey = parts[1]; - - // init GitHub app helper - this.gitHubAppHelper = new GitHubAppHelper(this.gitHubAppId, pkcs8PrivateKey); - } - - /** - * Used to filter out events that are not relevant for the chat mediators. - * - * @param parsedEvent Event - * @return Whether the given event is relevant for the chat mediators. - */ - protected boolean isRelevantEvent(JSONObject parsedEvent) { - String event = parsedEvent.getAsString("event"); - return List.of(eventNameItemComment, eventNameItemOpened).contains(event); - } - - /** - * Adds new comment to {@link GitHubChatMediator#messageCollector messageCollector} (if given event contains one). - * - * @param parsedEvent JSON representation of incoming GitHub event - */ - @Override - public void handleEvent(JSONObject parsedEvent) { - // extract name and payload of given event - String eventName = parsedEvent.getAsString("event"); - JSONObject payload = (JSONObject) parsedEvent.get("payload"); - - String repositoryFullName = this.getRepositoryFullNameOfEvent(parsedEvent); - String action = payload.getAsString("action"); - - boolean itemComment = eventName.equals(eventNameItemComment) && action.equals(actionNameItemComment); - boolean itemOpened = eventName.equals(eventNameItemOpened) && action.equals(actionNameItemOpened); - - if (itemComment || itemOpened) { - String itemName = itemComment ? itemNameComment : itemNameOpened; - JSONObject item = (JSONObject) payload.get(itemName); - String channelName = repositoryFullName + "#" + item.getAsNumber("number"); - - JSONObject comment; - if (itemComment) comment = (JSONObject) payload.get("comment"); - else if (itemOpened) comment = (JSONObject) payload.get(itemName); - else return; - - // extract user info from comment - JSONObject user = (JSONObject) comment.get("user"); - String username = user.getAsString("login"); - String message = comment.getAsString("body"); - - // dont handle bot messages - if (this.isBotAccount(user)) return; - - // add comment to message collector - ChatMessage chatMessage = new ChatMessage(channelName, username, message); - this.messageCollector.addMessage(chatMessage); - } - } - - /** - * Comments on an issue or pull request. As in GitHub a pull request also seems to be an issue, this method can - * be shared for both chat mediators. - * - * @param channel Format: [Owner name]/[Repo name]#[Issue or PR number] - * @param text The content of the comment - * @param id - */ - @Override - public void sendMessageToChannel(String channel, String text, HashMap hashMap, String type, Optional id) { - String repositoryFullName = channel.split("#")[0]; - int number = Integer.parseInt(channel.split("#")[1]); - - try { - GitHub instance = this.gitHubAppHelper.getGitHubInstance(repositoryFullName); - if (instance != null) { - // post comment (in GitHub a pull request also seems to be an issue) - instance.getRepository(repositoryFullName).getIssue(number).comment(text); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public Vector getMessages() { - return this.messageCollector.getMessages(); - } - - /** - * Returns the id of the GitHub app that the chat mediator is using. - * - * @return Id of the GitHub app that the chat mediator is using. - */ - public int getGitHubAppId() { - return this.gitHubAppId; - } - - /** - * Extracts the full repository name from an event JSONObject. - * - * @param parsedEvent Event - * @return Full name of the repository, containing both owner and repository name. - */ - private String getRepositoryFullNameOfEvent(JSONObject parsedEvent) { - JSONObject payload = (JSONObject) parsedEvent.get("payload"); - JSONObject repository = (JSONObject) payload.get("repository"); - return repository.getAsString("full_name"); - } - - /** - * Checks if the given user (from GitHub) is a bot. - * - * @param user User JSONObject from GitHub - * @return Whether the given user is a bot. - */ - private boolean isBotAccount(JSONObject user) { - return user.getAsString("type").equals("Bot"); - } - - @Override - public void editMessage(String channel, String messageId, String message, Optional id) { - } - - @Override - public void sendBlocksMessageToChannel(String channel, String blocks, String authToken, HashMap hashMap, Optional id) { - } - - @Override - public void updateBlocksMessageToChannel(String channel, String blocks, String authToken, String ts, Optional id) { - } - - @Override - public void sendFileMessageToChannel(String channel, File f, String text, Optional id) { - } - - @Override - public String getChannelByEmail(String email) { - return null; - } - - @Override - public void close() { - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubIssueMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubIssueMediator.java deleted file mode 100644 index f40a482f..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubIssueMediator.java +++ /dev/null @@ -1,40 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.github; - -import i5.las2peer.services.socialBotManagerService.chat.AuthTokenException; -import net.minidev.json.JSONObject; - -/** - * Chat mediator for comments on GitHub issues. - */ -public class GitHubIssueMediator extends GitHubChatMediator { - - /** - * Constructor for GitHub issue chat mediators. - * - * @param authToken Format: [GitHub app id]:[GitHub app private key in pkcs8] - * @throws GitHubAppHelper.GitHubAppHelperException If something related to the GitHubAppHelper is not working. - * @throws AuthTokenException If format of {@code authToken} is incorrect. - */ - public GitHubIssueMediator(String authToken) throws GitHubAppHelper.GitHubAppHelperException, AuthTokenException { - super(authToken); - this.eventNameItemOpened = "issues"; - this.itemNameOpened = "issue"; - } - - /** - * Adds new issue comment to the message collector (if given event contains one). - * - * @param parsedEvent JSON representation of incoming GitHub event - */ - @Override - public void handleEvent(JSONObject parsedEvent) { - if (!this.isRelevantEvent(parsedEvent)) return; - - // check if event belongs to an issue - JSONObject payload = (JSONObject) parsedEvent.get("payload"); - JSONObject issue = (JSONObject) payload.get("issue"); - if (!issue.containsKey("pull_request")) { - super.handleEvent(parsedEvent); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubPRMediator.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubPRMediator.java deleted file mode 100644 index ae8d7623..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubPRMediator.java +++ /dev/null @@ -1,50 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.github; - -import i5.las2peer.services.socialBotManagerService.chat.AuthTokenException; -import net.minidev.json.JSONObject; - -/** - * Chat mediator for comments on GitHub pull requests. - */ -public class GitHubPRMediator extends GitHubChatMediator { - - /** - * Constructor for GitHub pull request chat mediators. - * - * @param authToken Format: [GitHub app id]:[GitHub app private key in pkcs8] - * @throws GitHubAppHelper.GitHubAppHelperException If something related to the GitHubAppHelper is not working. - * @throws AuthTokenException If format of {@code authToken} is incorrect. - */ - public GitHubPRMediator(String authToken) throws GitHubAppHelper.GitHubAppHelperException, AuthTokenException { - super(authToken); - this.eventNameItemOpened = "pull_request"; - this.itemNameOpened = "pull_request"; - } - - /** - * Adds new pull request comment to the message collector (if given event contains one). - * - * @param parsedEvent JSON representation of incoming GitHub event - */ - @Override - public void handleEvent(JSONObject parsedEvent) { - if (!this.isRelevantEvent(parsedEvent)) return; - - // check if event belongs to a pull request - JSONObject payload = (JSONObject) parsedEvent.get("payload"); - // note: in GitHub a pull request also seems to be an issue - if (payload.containsKey("issue")) { - // could be a pull request comment - JSONObject issue = (JSONObject) payload.get("issue"); - if (issue.containsKey("pull_request")) { - // event belongs to a pull request (and not to an issue) - super.handleEvent(parsedEvent); - } - } else { - // could be a newly opened pull request - if (payload.containsKey("pull_request")) { - super.handleEvent(parsedEvent); - } - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubWebhookReceiver.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubWebhookReceiver.java deleted file mode 100644 index 34418c69..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/github/GitHubWebhookReceiver.java +++ /dev/null @@ -1,66 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.github; - -import i5.las2peer.api.Context; -import i5.las2peer.services.socialBotManagerService.SocialBotManagerService; -import i5.las2peer.services.socialBotManagerService.chat.ChatService; -import i5.las2peer.services.socialBotManagerService.model.Bot; -import i5.las2peer.services.socialBotManagerService.model.Messenger; -import io.swagger.annotations.Api; -import net.minidev.json.JSONObject; -import net.minidev.json.JSONValue; - -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; -import java.util.Collection; - -@Api(value = "GitHub Webhook Receiver Resource") -@Path("/github") -public class GitHubWebhookReceiver { - - /** - * Receives incoming webhook events from a GitHub app and sends them to related GitHub chat mediators. - * - * @param body Event - * @param eventName Name of event - * @param gitHubAppId Id of GitHub app - * @return 200 - */ - @POST - @Path("/webhook/{gitHubAppId}") - public Response receiveWebhookEvent(String body, @HeaderParam("X-GitHub-Event") String eventName, - @PathParam("gitHubAppId") int gitHubAppId) { - JSONObject payload = (JSONObject) JSONValue.parse(body); - - // put name of event and payload into one JSONObject - JSONObject eventObj = new JSONObject(); - eventObj.put("event", eventName); - eventObj.put("payload", payload); - - SocialBotManagerService service = (SocialBotManagerService) Context.get().getService(); - - // need to find bot(s) that use this GitHub app id - Collection bots = service.getConfig().getBots().values(); - for (Bot bot : bots) { - Messenger messenger = bot.getMessenger(ChatService.GITHUB_ISSUES); - if (messenger != null) { - GitHubIssueMediator mediator = (GitHubIssueMediator) messenger.getChatMediator(); - if (mediator.getGitHubAppId() == gitHubAppId) { - mediator.handleEvent(eventObj); - } - } - - messenger = bot.getMessenger(ChatService.GITHUB_PR); - if (messenger != null) { - GitHubPRMediator mediator = (GitHubPRMediator) messenger.getChatMediator(); - if (mediator.getGitHubAppId() == gitHubAppId) { - mediator.handleEvent(eventObj); - } - } - } - - return Response.status(200).build(); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/ChatStatement.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/ChatStatement.java deleted file mode 100644 index 73d0b3fc..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/ChatStatement.java +++ /dev/null @@ -1,69 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class ChatStatement { - private xAPIActor actor; - private xAPIVerb verb; - private xAPIObject object; - private xAPIContext context; - - public xAPIActor getActor() { - return actor; - } - - public void setActor(xAPIActor actor) { - this.actor = actor; - } - - public xAPIVerb getVerb() { - return verb; - } - - public void setVerb(xAPIVerb verb) { - this.verb = verb; - } - - public xAPIObject getObject() { - return object; - } - - public void setObject(xAPIObject object) { - this.object = object; - } - - public xAPIContext getContext() { - return context; - } - - public void setContext(xAPIContext context) { - this.context = context; - } - - public ChatStatement() { - actor = new xAPIActor(); - verb = new xAPIVerb(); - object = new xAPIObject(); - context = new xAPIContext(); - } - - public static ChatStatement generate(String from, String to, String text, String time, String platform) { - ChatStatement chatStatement = new ChatStatement(); - // actor - chatStatement.getActor().setName(from); - chatStatement.getActor().getAccount().setName(from); - chatStatement.getActor().getAccount().setHomePage(platform); - chatStatement.getActor().setObjectType("Agent"); - // verb - chatStatement.getVerb().getDisplay().setEnEN("messaged"); - chatStatement.getVerb().setId("https://tech4comp.de/xapi/verb/messaged"); - // object - chatStatement.getObject().setName(to); - chatStatement.getObject().getAccount().setName(to); - chatStatement.getObject().getAccount().setHomePage(platform); - chatStatement.getObject().setObjectType("Agent"); - // context - chatStatement.getContext().getExtension().getMessageInfo().setContent(text); - chatStatement.getContext().getExtension().getMessageInfo().setTimeSent(time); - // maybe add sth. like recognized intents, entities? - return chatStatement; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIAccount.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIAccount.java deleted file mode 100644 index 9592dff2..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIAccount.java +++ /dev/null @@ -1,22 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIAccount { - private String name; - private String homePage; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getHomePage() { - return homePage; - } - - public void setHomePage(String homePage) { - this.homePage = homePage; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIActor.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIActor.java deleted file mode 100644 index b7b554f2..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIActor.java +++ /dev/null @@ -1,35 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIActor { - private String name; - private xAPIAccount account; - private String objectType; - - public xAPIActor() { - account = new xAPIAccount(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public xAPIAccount getAccount() { - return account; - } - - public void setAccount(xAPIAccount account) { - this.account = account; - } - - public String getObjectType() { - return objectType; - } - - public void setObjectType(String objectType) { - this.objectType = objectType; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIContext.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIContext.java deleted file mode 100644 index c37403ca..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIContext.java +++ /dev/null @@ -1,17 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIContext { - private xAPIExtension extension; - - public xAPIContext() { - extension = new xAPIExtension(); - } - - public xAPIExtension getExtension() { - return extension; - } - - public void setExtension(xAPIExtension extension) { - this.extension = extension; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIDisplay.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIDisplay.java deleted file mode 100644 index 2a2d933d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIDisplay.java +++ /dev/null @@ -1,26 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -import com.google.gson.annotations.SerializedName; - -public class xAPIDisplay { - @SerializedName("en-EN") - private String enEN; - @SerializedName("de-DE") - private String deDE; - - public String getEnEN() { - return enEN; - } - - public void setEnEN(String enEN) { - this.enEN = enEN; - } - - public String getDeDE() { - return deDE; - } - - public void setDeDE(String deDE) { - this.deDE = deDE; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIExtension.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIExtension.java deleted file mode 100644 index f65aaf8d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIExtension.java +++ /dev/null @@ -1,21 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -import com.google.gson.annotations.SerializedName; - -public class xAPIExtension { - - @SerializedName("https://tech4comp.de/xapi/context/extensions/messageInfo") - private xAPIMessageInfo messageInfo; - - public xAPIExtension() { - messageInfo = new xAPIMessageInfo(); - } - - public xAPIMessageInfo getMessageInfo() { - return messageInfo; - } - - public void setMessageInfo(xAPIMessageInfo messageInfo) { - this.messageInfo = messageInfo; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIMessageInfo.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIMessageInfo.java deleted file mode 100644 index 4957c57f..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIMessageInfo.java +++ /dev/null @@ -1,22 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIMessageInfo { - private String content; - private String timeSent; - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getTimeSent() { - return timeSent; - } - - public void setTimeSent(String timeSent) { - this.timeSent = timeSent; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIObject.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIObject.java deleted file mode 100644 index 6b32b78c..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIObject.java +++ /dev/null @@ -1,35 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIObject { - private String name; - private xAPIAccount account; - private String objectType; - - public xAPIObject() { - account = new xAPIAccount(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public xAPIAccount getAccount() { - return account; - } - - public void setAccount(xAPIAccount account) { - this.account = account; - } - - public String getObjectType() { - return objectType; - } - - public void setObjectType(String objectType) { - this.objectType = objectType; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIVerb.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIVerb.java deleted file mode 100644 index f79f369e..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/chat/xAPI/xAPIVerb.java +++ /dev/null @@ -1,26 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.chat.xAPI; - -public class xAPIVerb { - private xAPIDisplay display; - private String id; - - public xAPIVerb() { - display = new xAPIDisplay(); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public xAPIDisplay getDisplay() { - return display; - } - - public void setDisplay(xAPIDisplay display) { - this.display = display; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabase.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabase.java deleted file mode 100644 index a2cd9732..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabase.java +++ /dev/null @@ -1,126 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.database; - -import java.sql.SQLException; -import java.sql.Statement; - -import org.apache.commons.dbcp2.BasicDataSource; - -/** - * - * Stores the database credentials and provides access to query execution. The original code was taken from the - * QueryVisualizationService. - * - * @author Peter de Lange - * - */ -public class SQLDatabase { - - private BasicDataSource dataSource; - - private SQLDatabaseType jdbcInfo = null; - private String username = null; - private String password = null; - private String database = null; - private String host = null; - private int port = -1; - - /** - * - * Constructor for a database instance. - * - * @param jdbcInfo the driver you are using - * @param username login name - * @param password password - * @param database database name - * @param host host for the connection - * @param port port of the SQL server - * - */ - public SQLDatabase(SQLDatabaseType jdbcInfo, String username, String password, String database, String host, - int port) { - - this.jdbcInfo = jdbcInfo; - this.username = username; - this.password = password; - this.host = host; - this.port = port; - this.database = database; - - BasicDataSource ds = new BasicDataSource(); - String urlPrefix = jdbcInfo.getURLPrefix(this.host, this.database, this.port) - + "?autoReconnect=true&useSSL=false&serverTimezone=UTC"; - ds.setUrl(urlPrefix); - ds.setUsername(username); - ds.setPassword(password); - ds.setDriverClassName(jdbcInfo.getDriverName()); - ds.setPoolPreparedStatements(true); - ds.setTestOnBorrow(true); - ds.setRemoveAbandonedOnBorrow(true); - ds.setRemoveAbandonedOnMaintenance(true); - ds.setMaxOpenPreparedStatements(100); - ds.setMaxConnLifetimeMillis(1000 * 60 * 60); - - dataSource = ds; - setValidationQuery(); - } - - /** - * - * Executes a SQL statement to insert an entry into the database. - * - * @param SQLStatment a SQLStatement - * - * @return true, if correctly inserted - * - * @throws SQLException problems inserting - * - */ - @Deprecated - public boolean store(String SQLStatment) throws SQLException { - // make sure one is connected to a database - if (!dataSource.getConnection().isValid(5000)) { - System.err.println("No database connection."); - return false; - } - Statement statement = dataSource.getConnection().createStatement(); - statement.executeUpdate(SQLStatment); - return true; - - } - - public String getUser() { - return this.username; - } - - public String getPassword() { - return this.password; - } - - public String getDatabase() { - return this.database; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public SQLDatabaseType getJdbcInfo() { - return jdbcInfo; - } - - public BasicDataSource getDataSource() { - return dataSource; - } - - private void setValidationQuery() { - switch (jdbcInfo.getCode()) { - case 1: - dataSource.setValidationQuery("SELECT 1;"); - } - } - -} \ No newline at end of file diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabaseType.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabaseType.java deleted file mode 100644 index 46eeaea4..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/database/SQLDatabaseType.java +++ /dev/null @@ -1,82 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.database; - -/** - * - * Enumeration class that provides the right drivers according to the database type. The original code was taken from - * the QueryVisualizationService. - * - * This implementation currently only supports MySQL. - * - */ -public enum SQLDatabaseType { - - /** - * A MySQL database. Works with the "mysqlConnectorJava-8.0.13.jar" archive. - */ - MySQL(1, "com.mysql.cj.jdbc.Driver", "mysql"); - - private final int code; - private final String driver; - private final String jdbc; - - SQLDatabaseType(int code, String driverName, String jdbc) { - this.driver = driverName; - this.jdbc = jdbc; - this.code = code; - } - - /** - * - * Returns the code of the database. - * - * @return a code - * - */ - public int getCode() { - return this.code; - } - - /** - * - * Returns the database type. - * - * @param code the number corresponding to a database type - * - * @return the corresponding {@link SQLDatabaseType} representation - * - */ - public static SQLDatabaseType getSQLDatabaseType(int code) { - switch (code) { - case 1: - return SQLDatabaseType.MySQL; - } - return null; - } - - /** - * - * Returns the driver name of the corresponding database. The library of this driver has to be in the "lib" folder. - * - * @return a driver name - * - */ - public String getDriverName() { - return driver; - } - - /** - * - * Constructs a URL prefix that can be used for addressing a database. - * - * @param host a database host address - * @param database the database name - * @param port the port the database is running at - * - * @return a String representing the URL prefix - * - */ - public String getURLPrefix(String host, String database, int port) { - return "jdbc:" + jdbc + "://" + host + ":" + port + "/" + database; - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ActionType.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ActionType.java deleted file mode 100644 index eda0bf91..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ActionType.java +++ /dev/null @@ -1,5 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public enum ActionType { - SERVICE, OPENAPI, SENDMESSAGE -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Bot.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Bot.java deleted file mode 100644 index 493a4d66..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Bot.java +++ /dev/null @@ -1,236 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; - -import javax.websocket.DeploymentException; - -import i5.las2peer.services.socialBotManagerService.chat.AuthTokenException; -import i5.las2peer.services.socialBotManagerService.chat.ChatService; -import i5.las2peer.services.socialBotManagerService.parser.ParseBotException; -import net.minidev.json.JSONObject; -import i5.las2peer.services.socialBotManagerService.nlu.RasaNlu; - -public class Bot { - private String name; - private String id; - private String version = "1.0.0"; - private String service; - private HashMap active; - - private HashMap botServiceFunctions; - private HashSet triggerList; - - private HashMap messengers; - - private String botAgent; - - private HashMap rasaServers; - - private HashMap serviceInformation; - private String address; - private HashMap routines; - - public Bot() { - botServiceFunctions = new HashMap(); - triggerList = new HashSet(); - active = new HashMap(); - this.messengers = new HashMap(); - this.rasaServers = new HashMap(); - setRoutines(new HashMap()); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - public HashMap getBotServiceFunctions() { - return botServiceFunctions; - } - - public void setServiceFunctions(HashMap serviceFunctions) { - this.botServiceFunctions = serviceFunctions; - } - - public void addBotServiceFunction(String name, ServiceFunction serviceFunction) { - this.botServiceFunctions.put(name, serviceFunction); - } - - public RasaNlu getRasaServer(String id) { - return this.rasaServers.get(id); - } - - public HashMap getRasaServers() { - return this.rasaServers; - } - - public RasaNlu getFirstRasaServer() { - return (RasaNlu) this.rasaServers.values().toArray()[0]; - } - - public void addRasaServer(String id, String url) { - this.rasaServers.put(id, new RasaNlu(url)); - } - - public HashSet getTriggerList() { - return triggerList; - } - - public void setTriggerList(HashSet triggerList) { - this.triggerList = triggerList; - } - - public void addTrigger(Trigger t) { - this.triggerList.add(t); - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public HashMap getActive() { - return active; - } - - public void setActive(HashMap active) { - this.active = active; - } - - public void setIdActive(String id, boolean active) { - this.active.put(id, active); - } - - public Messenger getMessenger(String name) { - // TODO: I'm not too sure about thread safety when calling - // something on this. Might need to make ChatMediator - // methods synchronized? - return this.messengers.get(name); - } - - public Messenger getMessenger(ChatService chatservice) { - for (Messenger messenger : this.messengers.values()) { - if (messenger.getChatService() == chatservice) - return messenger; - } - return null; - } - - public HashMap getMessengers() { - return this.messengers; - } - - public void addMessenger(Messenger messenger, String url) throws IOException, DeploymentException, ParseBotException, AuthTokenException { - messenger.setUrl(url); - this.messengers.put(messenger.getName(), messenger); - } - - public void deactivateAll() { - for (Messenger m : this.messengers.values()) { - m.close(); - } - for (String k : this.active.keySet()) { - this.active.put(k, false); - } - } - - public boolean deactivateAllWithCheck(ArrayList messengerNames) { - int correctEntries = 0; - for (Object object : messengerNames) { - HashMap list = (HashMap) object; - for (Messenger m : this.messengers.values()) { - if (list.get("name").toLowerCase().equals(m.getName().toLowerCase())) { - if (m.getChatMediator().checkToken(list.get("authToken"))) { - correctEntries++; - } - } - } - } - if (correctEntries < this.messengers.size()) { - return false; - } - for (Messenger m : this.messengers.values()) { - m.close(); - } - for (String k : this.active.keySet()) { - this.active.put(k, false); - } - return true; - } - - public int countActive() { - int trueCount = 0; - for (boolean b : active.values()) { - if (b) - trueCount++; - } - return trueCount; - } - - public void handleMessages(ArrayList messageInfos) { - for (Messenger m : this.messengers.values()) { - m.handleMessages(messageInfos, this); - } - } - - public String getBotAgent() { - return botAgent; - } - - public void setBotAgent(String botAgent) { - this.botAgent = botAgent; - } - - public HashMap getServiceInformation() { - return serviceInformation; - } - - public void setServiceInformation(HashMap serviceInformation) { - this.serviceInformation = serviceInformation; - } - - public void addServiceInformation(String name, JSONObject info) { - this.serviceInformation.put(name, info); - } - - public String getAddress() { - return address; - } - - public HashMap getRoutines() { - return routines; - } - - public void setRoutines(HashMap routines) { - this.routines = routines; - } - - public void addRoutine(String name, BotRoutine routine) { - this.routines.put(name, routine); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotConfiguration.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotConfiguration.java deleted file mode 100644 index 8d3f980d..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.HashMap; - -public class BotConfiguration { - private HashMap bots; - - public BotConfiguration() { - bots = new HashMap(); - } - - public HashMap getBots() { - return this.bots; - } - - public void setBotConfiguration(HashMap bots) { - this.bots = bots; - } - - public void addBot(String key, Bot bot) { - this.bots.put(key, bot); - } - - public void removeBot(String key) { - this.bots.remove(key); - } - - public Bot getBot(String key) { - return this.bots.get(key); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModel.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModel.java deleted file mode 100644 index 0186cb1b..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModel.java +++ /dev/null @@ -1,37 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; -import java.util.LinkedHashMap; - - -public class BotModel implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 2889244909583713463L; - /** - * - */ - private BotModelAttribute attributes; - private LinkedHashMap nodes; - private LinkedHashMap edges; - public BotModelAttribute getAttributes() { - return attributes; - } - public void setAttributes(BotModelAttribute attributes) { - this.attributes = attributes; - } - public LinkedHashMap getNodes() { - return nodes; - } - public void setNodes(LinkedHashMap nodes) { - this.nodes = nodes; - } - public LinkedHashMap getEdges() { - return edges; - } - public void setEdges(LinkedHashMap edges) { - this.edges = edges; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelAttribute.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelAttribute.java deleted file mode 100644 index bdb9fd5a..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelAttribute.java +++ /dev/null @@ -1,68 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; -import java.util.LinkedHashMap; - - -public class BotModelAttribute implements Serializable { - /** - * - */ - private static final long serialVersionUID = -3505476346232276390L; - private BotModelLabel label; - private double left; - private double top; - private double width; - private double height; - private double zIndex; - private String type; - private LinkedHashMap attributes; - public BotModelLabel getLabel() { - return label; - } - public void setLabel(BotModelLabel label) { - this.label = label; - } - public double getLeft() { - return left; - } - public void setLeft(double left) { - this.left = left; - } - public double getTop() { - return top; - } - public void setTop(double top) { - this.top = top; - } - public double getWidth() { - return width; - } - public void setWidth(double width) { - this.width = width; - } - public double getHeight() { - return height; - } - public void setHeight(double height) { - this.height = height; - } - public double getzIndex() { - return zIndex; - } - public void setzIndex(double zIndex) { - this.zIndex = zIndex; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public LinkedHashMap getAttributes() { - return attributes; - } - public void setAttributes(LinkedHashMap attributes) { - this.attributes = attributes; - } -} \ No newline at end of file diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelEdge.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelEdge.java deleted file mode 100644 index 9d14828a..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelEdge.java +++ /dev/null @@ -1,46 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; -import java.util.LinkedHashMap; - -public class BotModelEdge implements Serializable{ - /** - * - */ - private static final long serialVersionUID = 4613520960473047763L; - private BotModelLabel label; - private String source; - private String target; - private LinkedHashMap attributes; - private String type; - public BotModelLabel getLabel() { - return label; - } - public void setLabel(BotModelLabel label) { - this.label = label; - } - public String getSource() { - return source; - } - public void setSource(String source) { - this.source = source; - } - public String getTarget() { - return target; - } - public void setTarget(String target) { - this.target = target; - } - public LinkedHashMap getAttributes() { - return attributes; - } - public void setAttributes(LinkedHashMap attributes) { - this.attributes = attributes; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelLabel.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelLabel.java deleted file mode 100644 index cf6308c5..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelLabel.java +++ /dev/null @@ -1,31 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; - -public class BotModelLabel implements Serializable{ - /** - * - */ - private static final long serialVersionUID = -8123828374501000173L; - private String id; - private String name; - private BotModelValue value; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public BotModelValue getValue() { - return value; - } - public void setValue(BotModelValue value) { - this.value = value; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNode.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNode.java deleted file mode 100644 index b2a5f6f3..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNode.java +++ /dev/null @@ -1,68 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; -import java.util.LinkedHashMap; - - -public class BotModelNode implements Serializable{ - /** - * - */ - private static final long serialVersionUID = -3218604381718722388L; - private BotModelLabel label; - private double left; - private double top; - private double width; - private double height; - private double zIndex; - private String type; - private LinkedHashMap attributes; - public BotModelLabel getLabel() { - return label; - } - public void setLabel(BotModelLabel label) { - this.label = label; - } - public double getLeft() { - return left; - } - public void setLeft(double left) { - this.left = left; - } - public double getTop() { - return top; - } - public void setTop(double top) { - this.top = top; - } - public double getWidth() { - return width; - } - public void setWidth(double width) { - this.width = width; - } - public double getHeight() { - return height; - } - public void setHeight(double height) { - this.height = height; - } - public double getzIndex() { - return zIndex; - } - public void setzIndex(double zIndex) { - this.zIndex = zIndex; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public LinkedHashMap getAttributes() { - return attributes; - } - public void setAttributes(LinkedHashMap attributes) { - this.attributes = attributes; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNodeAttribute.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNodeAttribute.java deleted file mode 100644 index 46667235..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelNodeAttribute.java +++ /dev/null @@ -1,38 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; - -public class BotModelNodeAttribute implements Serializable{ - /** - * - */ - private static final long serialVersionUID = -1570395056424596193L; - private String id; - private String name; - private BotModelValue value; - private String option; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public BotModelValue getValue() { - return value; - } - public void setValue(BotModelValue value) { - this.value = value; - } - public String getOption() { - return option; - } - public void setOption(String option) { - this.option = option; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelValue.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelValue.java deleted file mode 100644 index ad668354..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotModelValue.java +++ /dev/null @@ -1,31 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.Serializable; - -public class BotModelValue implements Serializable{ - /** - * - */ - private static final long serialVersionUID = -7779402101938183839L; - private String id; - private String name; - private String value; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getValue() { - return value; - } - public void setValue(String value) { - this.value = value; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotRoutine.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotRoutine.java deleted file mode 100644 index 557a2eb8..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/BotRoutine.java +++ /dev/null @@ -1,68 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.HashSet; - -public class BotRoutine extends TriggerFunction{ - private String name; - private String interval; - private String time; - private long lastUpdate; - private HashSet trigger; - private Bot bot; - - public BotRoutine() { - this.setTrigger(new HashSet()); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getInterval() { - return interval; - } - - public void setInterval(String interval) { - this.interval = interval; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public long getLastUpdate() { - return lastUpdate; - } - - public void setLastUpdate(long lastUpdate) { - this.lastUpdate = lastUpdate; - } - - public HashSet getTrigger() { - return trigger; - } - - public void setTrigger(HashSet triggerFunctions) { - this.trigger = triggerFunctions; - } - - public void addTrigger(Trigger tf) { - this.trigger.add(tf); - } - - public Bot getBot() { - return bot; - } - - public void setBot(Bot bot) { - this.bot = bot; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ChatResponse.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ChatResponse.java deleted file mode 100644 index 22725186..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ChatResponse.java +++ /dev/null @@ -1,58 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -public class ChatResponse { - String response; - String triggeredFunctionId; - String triggerEntity; - String fileURL; - String errorMessage; - String type; - public ChatResponse(String response, String fileURL, String errorMessage, String type) { - this.response = response; - this.fileURL = fileURL; - this.errorMessage = errorMessage; - this.triggerEntity = ""; - this.type = type; - - } - public String getResponse(){ - return this.response; - } - - public String getFileURL() { - return fileURL; - } - - public String getErrorMessage() { - return errorMessage; - } - - public void setTriggeredFunctionId(String functionId){ - this.triggeredFunctionId = functionId; - } - - - public String getTriggeredFunctionId(){ - return this.triggeredFunctionId; - } - - public String getTriggerEntity(){ - return this.triggerEntity; - } - - public void addTriggerEntity(String triggerEntity){ - this.triggerEntity = triggerEntity; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } -} \ No newline at end of file diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IfThenBlock.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IfThenBlock.java deleted file mode 100644 index b744d23b..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IfThenBlock.java +++ /dev/null @@ -1,74 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public class IfThenBlock { - private ServiceFunctionAttribute sourceAttribute; - private ServiceFunctionAttribute targetAttribute; - private IfThenBlock prev; - private IfThenBlock next; - private String conditionType; - private String statementType; - private String conditionValueA; - private String conditionValueB; - private String statementValueA; - private String statementValueB; - public ServiceFunctionAttribute getSourceAttribute() { - return sourceAttribute; - } - public void setSourceAttribute(ServiceFunctionAttribute sourceAttribute) { - this.sourceAttribute = sourceAttribute; - } - public ServiceFunctionAttribute getTargetAttribute() { - return targetAttribute; - } - public void setTargetAttribute(ServiceFunctionAttribute targetAttribute) { - this.targetAttribute = targetAttribute; - } - public IfThenBlock getPrev() { - return prev; - } - public void setPrev(IfThenBlock prev) { - this.prev = prev; - } - public IfThenBlock getNext() { - return next; - } - public void setNext(IfThenBlock next) { - this.next = next; - } - public String getConditionType() { - return conditionType; - } - public void setConditionType(String conditionType) { - this.conditionType = conditionType; - } - public String getStatementType() { - return statementType; - } - public void setStatementType(String statementType) { - this.statementType = statementType; - } - public String getConditionValueA() { - return conditionValueA; - } - public void setConditionValueA(String conditionValueA) { - this.conditionValueA = conditionValueA; - } - public String getConditionValueB() { - return conditionValueB; - } - public void setConditionValueB(String conditionValueB) { - this.conditionValueB = conditionValueB; - } - public String getStatementValueA() { - return statementValueA; - } - public void setStatementValueA(String statementValueA) { - this.statementValueA = statementValueA; - } - public String getStatementValueB() { - return statementValueB; - } - public void setStatementValueB(String statementValueB) { - this.statementValueB = statementValueB; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java deleted file mode 100644 index 5230c1e7..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IncomingMessage.java +++ /dev/null @@ -1,180 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -public class IncomingMessage { - String intentKeyword; - String intentLabel; - String followupMessageType; - String entityKeyword; - String NluID; - boolean containsFile; - String response; - String triggeredFunctionId; - String triggerEntity; - String fileURL; - String errorMessage; - String type; - - ArrayList responses; - - // Intent keywords used as keys - HashMap followupMessages; - - - private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, - { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, { new String("ö"), "oe" }, - { new String("ß"), "ss" } }; - - public static String replaceUmlaute(String orig) { - String result = orig; - - for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) { - result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]); - } - - return result; - } - - - public IncomingMessage(String intent, String NluID, Boolean containsFile,String response, String fileURL, String errorMessage, String type,String intentLabel, String followupType) { - if(intent != "") { - this.intentKeyword = replaceUmlaute(intent); - } else intentKeyword = ""; - this.followupMessages = new HashMap(); - this.responses = new ArrayList(); - this.containsFile = containsFile; - if (intentKeyword.equals("0") && containsFile){ - intentKeyword = "anyFile"; - } - if(NluID == ""){ - this.NluID = ""; - } else this.NluID = NluID; - - - this.response = response; - this.fileURL = fileURL; - this.errorMessage = errorMessage; - this.triggerEntity = ""; - this.type = type; - this.followupMessageType = followupType; - this.intentLabel = intentLabel; - } - - public String getIntentKeyword() { - return intentKeyword; - } - - public String getEntityKeyword() { - return entityKeyword; - } - - public void setEntityKeyword(String entityKeyword) { - this.entityKeyword = entityKeyword; - } - - public String getNluID() { - return NluID; - } - - public HashMap getFollowingMessages() { - return followupMessages; - } - - public void addFollowupMessage(String intentKeyword, IncomingMessage msg) { - String[] intentList = intentKeyword.split(","); - for (String intent : intentList) { - if (intent.equals("") && msg.containsFile){ - this.followupMessages.put(replaceUmlaute(intent).replaceAll("\\s+", "") + "anyFile", msg); - } else { - this.followupMessages.put(replaceUmlaute(intent).replaceAll("\\s+", ""), msg); - } - } - // (this.followupMessages.put(replaceUmlaute(intentKeyword), msg); - } - - public void addResponse(IncomingMessage response) { - this.responses.add(response); - } - - public IncomingMessage getResponse(Random random) { - if (responses.isEmpty()) { - return null; - } else { - return responses.get(random.nextInt(responses.size())); - } - } - - public ArrayList getResponseArray() { - if (responses.isEmpty()) { - return null; - } else { - return responses; - } - } - - public void setTriggeredFunction(ServiceFunction triggeredFunction) { - this.triggeredFunctionId = triggeredFunction.getId(); - } - - public String getTriggeredFunctionId() { - return this.triggeredFunctionId; - } - - public boolean expectsFile() { - return this.containsFile; - } - - public String getResponse(){ - return this.response; - } - - public String getFileURL() { - return fileURL; - } - - public String getErrorMessage() { - return errorMessage; - } - - public void setTriggeredFunctionId(String functionId){ - this.triggeredFunctionId = functionId; - } - - public String getTriggerEntity(){ - return this.triggerEntity; - } - - public void addTriggerEntity(String triggerEntity){ - this.triggerEntity = triggerEntity; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getIntentLabel() { - return intentLabel; - } - - - public void setIntentLabel(String intentLabel) { - this.intentLabel = intentLabel; - } - - - public String getFollowupMessageType() { - return followupMessageType; - } - - - public void setFollowupMessageType(String followupMessageType) { - this.followupMessageType = followupMessageType; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IntentEntity.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IntentEntity.java deleted file mode 100644 index 3d9ad25b..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/IntentEntity.java +++ /dev/null @@ -1,13 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public class IntentEntity { - String entityKeyword; - - public IntentEntity(String entity) { - this.entityKeyword = entity; - } - - public String getEntityKeyword() { - return this.entityKeyword; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java deleted file mode 100644 index 1682fcd3..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/MessageInfo.java +++ /dev/null @@ -1,60 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.Collection; - -import i5.las2peer.services.socialBotManagerService.chat.ChatMessage; -import i5.las2peer.services.socialBotManagerService.nlu.Intent; -import i5.las2peer.services.socialBotManagerService.nlu.Entity; - -public class MessageInfo { - ChatMessage message; - Intent intent; - String triggeredFunctionId; - String botName; - String serviceAlias; - boolean contextWithService; - Collection recognizedEntities; - - public MessageInfo(ChatMessage message, Intent intent, String triggeredFunctionId, String botName, - String serviceAlias, boolean contextWithService, Collection recognizedEntities) { - this.message = message; - this.intent = intent; - this.triggeredFunctionId = triggeredFunctionId; - this.botName = botName; - this.serviceAlias = serviceAlias; - this.contextWithService = contextWithService; - this.recognizedEntities = recognizedEntities; - } - - public ChatMessage getMessage() { - return this.message; - } - - public Intent getIntent() { - return this.intent; - } - - public String getTriggeredFunctionId() { - return this.triggeredFunctionId; - } - - public String getBotName() { - return this.botName; - } - - public String getServiceAlias() { - return this.serviceAlias; - } - - public boolean contextActive() { - return this.contextWithService; - } - - public void setRecognizedEntities(Collection entities) { - this.recognizedEntities = entities; - } - - public Collection getRecognizedEntities() { - return this.recognizedEntities; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java deleted file mode 100644 index e2642660..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Messenger.java +++ /dev/null @@ -1,741 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Collection; -import java.util.HashMap; -import java.util.Optional; -import java.util.Random; -import java.util.Vector; - -import javax.websocket.DeploymentException; - -import com.google.gson.Gson; - -import i5.las2peer.services.socialBotManagerService.chat.*; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubAppHelper; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubIssueMediator; -import i5.las2peer.services.socialBotManagerService.chat.github.GitHubPRMediator; -import i5.las2peer.services.socialBotManagerService.database.SQLDatabase; -import i5.las2peer.services.socialBotManagerService.nlu.Entity; -import i5.las2peer.services.socialBotManagerService.nlu.Intent; -import i5.las2peer.services.socialBotManagerService.nlu.RasaNlu; -import i5.las2peer.services.socialBotManagerService.parser.ParseBotException; - -public class Messenger { - private String name; - - // URL of the social bot manager service (used for setting up the webhook) - private String url; - - private ChatMediator chatMediator; - - /** - * The messenger application provider this object corresponds to - */ - private ChatService chatService; - - // Key: intent keyword - private HashMap knownIntents; - - // Used for keeping conversation state per channel - private HashMap stateMap; - // Used for keeping remembering entities during conversation state per channel - private HashMap> recognizedEntities; - // Used for keeping context between assessment and non-assessment states - // Key is the channelId - private HashMap currentNluModel; - // Used to know to which Function the received intents/messages are to be sent - // Is additionally used to check if we are currently communicating with a - // service(if set, then yes otherwise no) - private HashMap triggeredFunction; - // Keep up with how many times a default message was given out in a conversation - // state - private HashMap defaultAnswered; - - private Random random; - - private SQLDatabase db; - - public Messenger(String id, String chatService, String token, SQLDatabase database) - throws IOException, DeploymentException, ParseBotException, AuthTokenException { - -// this.rasa = new RasaNlu(rasaUrl); -// this.rasaAssessment = new RasaNlu(rasaAssessmentUrl); - this.db = database; - // Chat Mediator - this.chatService = ChatService.fromString(chatService); - System.out.println("Messenger: " + chatService.toString()); - switch (this.chatService) { - case SLACK: - this.chatMediator = new SlackChatMediator(token); - break; - case TELEGRAM: - this.chatMediator = new TelegramChatMediator(token); - String username = ((TelegramChatMediator) this.chatMediator).getBotName(); - if (username != null) - this.name = username; - break; - case ROCKET_CHAT: - this.chatMediator = new RocketChatMediator(token, database, new RasaNlu("rasaUrl")); - break; - case MOODLE_CHAT: - this.chatMediator = new MoodleChatMediator(token); - break; - case MOODLE_FORUM: - this.chatMediator = new MoodleForumMediator(token); - break; - case GITHUB_ISSUES: - try { - this.chatMediator = new GitHubIssueMediator(token); - } catch (GitHubAppHelper.GitHubAppHelperException e) { - throw new AuthTokenException(e.getMessage()); - } - break; - case GITHUB_PR: - try { - this.chatMediator = new GitHubPRMediator(token); - } catch (GitHubAppHelper.GitHubAppHelperException e) { - throw new AuthTokenException(e.getMessage()); - } - break; - case RESTful_Chat: - this.chatMediator = new RESTfulChatMediator(token); - System.out.println("RESTful Chat selected"); - break; - default: - throw new ParseBotException("Unimplemented chat service: " + chatService); - } - System.out.println("no exceptions"); - - this.name = id; - this.knownIntents = new HashMap(); - this.stateMap = new HashMap(); - this.recognizedEntities = new HashMap>(); - this.random = new Random(); - // Initialize the assessment setup - this.currentNluModel = new HashMap(); - this.triggeredFunction = new HashMap(); - this.defaultAnswered = new HashMap(); - } - - public String getName() { - return name; - } - - public ChatService getChatService() { - return chatService; - } - - public void addMessage(IncomingMessage msg) { - if (msg.getIntentKeyword().contains("defaultX")) { - this.knownIntents.put("defaultX", msg); - } else - this.knownIntents.put(msg.getIntentKeyword(), msg); - } - - public HashMap getKnownIntents() { - return this.knownIntents; - } - - public ChatMediator getChatMediator() { - return this.chatMediator; - } - - public IncomingMessage checkDefault(IncomingMessage state, ChatMessage message) { - if (this.knownIntents.get("defaultX") != null && Integer.valueOf( - this.knownIntents.get("defaultX").getIntentKeyword().split("defaultX")[1]) > this.defaultAnswered - .get(message.getChannel())) { - IncomingMessage newState = this.knownIntents.get("defaultX"); - newState.followupMessages = state.followupMessages; - state = newState; - this.defaultAnswered.put(message.getChannel(), this.defaultAnswered.get(message.getChannel()) + 1); - } else { - state = this.knownIntents.get("default"); - this.defaultAnswered.put(message.getChannel(), 0); - } - return state; - } - - private void addEntityToRecognizedList(String channel, Collection entities) { - - Collection recognizedEntitiesNew = recognizedEntities.get(channel); - // System.out.println("now is reco"); - // System.out.println(recognizedEntitiesNew); - for (Entity entity : entities) { - recognizedEntitiesNew.add(entity); - } - System.out.println(recognizedEntitiesNew); - // System.out.println("finish"); - recognizedEntities.put(channel, recognizedEntitiesNew); - } - // set the context of the specified channel - /* - * public void setContext(String channel, String contextName){ - * context.put(channel, contextName); - * - * } - */ - - /* - * public String getEmail(String channel) throws IOException, SlackApiException - * { return chatMediator.getEmail(channel); }; - */ - - public void setContextToBasic(String channel, String userid) { - triggeredFunction.remove(channel); - IncomingMessage state = this.stateMap.get(channel); - if (state != null) { - if (state.getFollowingMessages() == null) { - System.out.println("Conversation flow ended now"); - } else if (state.getFollowingMessages().get("") != null) { - // check whether bot action needs to be triggered without user input - state = state.getFollowingMessages().get(""); - stateMap.put(channel, state); - if (state.getResponse(random).triggeredFunctionId != null - || !state.getResponse(random).triggeredFunctionId.equals("")) { - ChatMessage chatMsg = new ChatMessage(channel, userid, "Empty Message"); - this.triggeredFunction.put(channel, state.getResponse(random).triggeredFunctionId); - this.chatMediator.getMessageCollector().addMessage(chatMsg); - } - } else { - // If only message to be sent - String response = state.getResponse(random).getResponse(); - if( response != null && !response.equals("")) - { - this.chatMediator.sendMessageToChannel(channel, response, state.getFollowingMessages(), state.getFollowupMessageType(),Optional.of(userid)); - } - if(state.getFollowingMessages().size()== 0){ - this.stateMap.remove(channel); - - } - } - } else { - } - } - - public String getContext(String channel, String user) { - return this.triggeredFunction.get(channel); - } - - // Handles simple responses ("Chat Response") directly, logs all messages and - // extracted intents into `messageInfos` for further processing later on. - // TODO: This would be much nicer if we could get a las2peer context here, but - // this - // is usually called from the routine thread. Maybe a context can be shared - // across - // threads somehow? - public void handleMessages(ArrayList messageInfos, Bot bot) { - Vector newMessages = this.chatMediator.getMessages(); - for (ChatMessage message : newMessages) { - try { - // // If a channel/user pair still isn't assigned to a state, assign it to null - // if (this.stateMap.get(message.getChannel()) == null) { - // HashMap initMap = new HashMap(); - // initMap.put(message.getUser(), null); - // this.stateMap.put(message.getChannel(), initMap); - // } - - // If a channel/user pair still isn't assigned to a NLU Model, assign it to the Model 0 - if (this.currentNluModel.get(message.getChannel()) == null) { - this.currentNluModel.put(message.getChannel(), "0"); - } - - // If channel/user pair is not assigned to a triggered function, assign it to null -// if (this.triggeredFunction.get(message.getChannel()) == null) { -// HashMap initMap = new HashMap(); -// initMap.put(message.getUser(), null); -// this.triggeredFunction.put(message.getChannel(), initMap); -// } - - - if (this.defaultAnswered.get(message.getChannel()) == null) { - this.defaultAnswered.put(message.getChannel(), 0); - } - Intent intent = null; - // Special case: `!` commands - // System.out.println(this.knownIntents.toString()); - if (message.getText().startsWith("!")) { - // Split at first occurring whitespace - - String splitMessage[] = message.getText().split("\\s+", 2); - - // First word without '!' prefix - String intentKeyword = splitMessage[0].substring(1); - IncomingMessage incMsg = this.knownIntents.get(intentKeyword); - // TODO: Log this? (`!` command with unknown intent / keyword) - if (incMsg == null && !intentKeyword.toLowerCase().equals("exit")) { - if (this.currentNluModel.get(message.getChannel()) == "0") { - continue; - } else { - incMsg = new IncomingMessage(intentKeyword, "", false,"",null,"",null, "","text"); - incMsg.setEntityKeyword("newEntity"); - } - } - - String entityKeyword = incMsg.getEntityKeyword(); - String entityValue = null; - // Entity value is the rest of the message. The whole rest - // is in the second element, since we only split it into two parts. - if (splitMessage.length > 1) { - entityValue = splitMessage[1]; - } - - intent = new Intent(intentKeyword, entityKeyword, entityValue); - } else { - // System.out.println(message.getFileName() + " + " + message.getFileBody()); - // System.out.println(Intent.replaceUmlaute(message.getText())); - if (bot.getRasaServer(currentNluModel.get(message.getChannel())) != null) { - intent = bot.getRasaServer(currentNluModel.get(message.getChannel())) - .getIntent(Intent.replaceUmlaute(message.getText())); - } else { - // if the given id is not fit to any server, pick the first one. (In case - // someone specifies only - // one server and does not give an ID) - intent = bot.getFirstRasaServer().getIntent(Intent.replaceUmlaute(message.getText())); - } - - } - - safeEntities(message,bot, intent); - - String triggeredFunctionId = null; - IncomingMessage state = this.stateMap.get(message.getChannel()); - if(state==null){ - System.out.println("No current state, we will start from scratch."); - }else{ - System.out.println("Current state: " + state.getIntentKeyword()); - } - // No conversation state present, starting from scratch - // TODO: Tweak this - if (!this.triggeredFunction.containsKey(message.getChannel())) { - if (intent.getKeyword().equals("exit")) { - recognizedEntities.remove(message.getChannel()); - state = this.knownIntents.get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); - } else - // add file case to default if part - if (intent.getConfidence() >= 0.40 || message.getFileName() != null) { - if (state == null) { - recognizedEntities.put(message.getChannel(), new ArrayList()); - if (message.getFileName() != null) { - // check whether incoming message with intent expects file or without intent, - // such that - // you can send a file regardless the intent - if (this.knownIntents.get(intent.getKeyword()) != null - && this.knownIntents.get(intent.getKeyword()).expectsFile()) { - state = this.knownIntents.get(intent.getKeyword()); - // get("0") refers to an empty intent that is accessible from the start state - } else if (this.knownIntents.get("anyFile") != null) { - state = this.knownIntents.get("anyFile"); - } else { - state = this.knownIntents.get("default"); - } - stateMap.put(message.getChannel(), state); - recognizedEntities.put(message.getChannel(), intent.getEntities()); - } else { - state = this.knownIntents.get(intent.getKeyword()); - // Incoming Message which expects file should not be chosen when no file was - // sent - if (state == null || state.expectsFile()) { - if(this.knownIntents.get("0") != null){ - state = this.knownIntents.get("0"); - } else{ - state = this.knownIntents.get("default"); - } - } - System.out.println(intent.getKeyword() + " detected with " + intent.getConfidence() - + " confidence."); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } - } else { - // any is a static forward - // TODO include entities of intents - // If there is no next state, stay in the same state - if (state.getFollowingMessages() == null || state.getFollowingMessages().isEmpty()) { - System.out.println("no follow up messages"); - state = this.knownIntents.get(intent.getKeyword()); - this.currentNluModel.put(message.getChannel(), "0"); - System.out.println(intent.getKeyword() + " detected with " + intent.getConfidence() - + " confidence."); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } else if (state.getFollowingMessages().get(intent.getKeyword()) != null) { - System.out.println("try follow up message"); - // check if a file was received during a conversation and search for a follow up - // incoming message which expects a file. - if (message.getFileBody() != null) { - if (state.getFollowingMessages().get(intent.getKeyword()).expectsFile()) { - state = state.getFollowingMessages().get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } else { - state = checkDefault(state, message); - } - } else if (state.getFollowingMessages().get(intent.getKeyword()).expectsFile()) { - state = checkDefault(state, message); - } else { - state = state.getFollowingMessages().get(intent.getKeyword()); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } - } else { - //System.out.println("\u001B[33mDebug --- Followups: " + state.getFollowingMessages() + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- Emptiness: " + state.getFollowingMessages().keySet().isEmpty() + "\u001B[0m"); - //System.out.println("\u001B[33mDebug --- State: " + state.getIntentKeyword() + "\u001B[0m"); - System.out.println(intent.getKeyword() + " not found in state map. Confidence: " - + intent.getConfidence() + " confidence."); - // try any - Gson g = new Gson(); - System.out.println("possible followup messages: "+ g.toJson(state.getFollowingMessages())); - - if (state.getFollowingMessages().get("any") != null) { - state = state.getFollowingMessages().get("any"); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - // In a conversation state, if no fitting intent was found and an empty leadsTo - // label is found - } else if(state.getFollowingMessages().get("") != null || state.getFollowingMessages().get("anyFile") != null){ - if (message.getFileBody() != null ) { - if (state.getFollowingMessages().get("anyFile") != null) { - state = state.getFollowingMessages().get("anyFile"); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } else { - state = this.knownIntents.get("default"); - } - - } else { - if (state.getFollowingMessages().get("") != null) { - state = state.getFollowingMessages().get(""); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } else { - state = checkDefault(state, message); - } - } - } else if (intent.getEntities().size() > 0 - && !this.triggeredFunction.containsKey(message.getChannel())) { - Collection entities = intent.getEntities(); - // System.out.println("try to use entity..."); - for (Entity e : entities) { - System.out.println(e.getEntityName() + " (" + e.getValue() + ")"); - state = this.knownIntents.get(e.getEntityName()); - // Dont fully understand the point of this, maybe I added it and forgot... - // Added return for a quick fix, will need to check more in detail - if (state != null) { - stateMap.put(message.getChannel(), state); - return; - } - } - - } else { - state = checkDefault(state, message); - } - } - } - } else { - if (state != null && state.getFollowingMessages().get("") != null) { - System.out.println("Empty leadsTo2"); - if (message.getFileBody() != null) { - if (state.getFollowingMessages().get("").expectsFile()) { - state = state.getFollowingMessages().get(""); - } else { - state = checkDefault(state, message); - } - } else { - if (!state.getFollowingMessages().get("").expectsFile()) { - state = state.getFollowingMessages().get(""); - stateMap.put(message.getChannel(), state); - addEntityToRecognizedList(message.getChannel(), intent.getEntities()); - } else { - state = checkDefault(state, message); - } - } - } else { - if (state != null) { - state = checkDefault(state, message); - } else { - System.out.println(intent.getKeyword() + " not detected with " + intent.getConfidence() - + " confidence."); - state = this.knownIntents.get("default"); - } - } - // System.out.println(state.getIntentKeyword() + " set"); - } - // If a user sends a file, without wanting to use intent extraction on the name, - // then intent - // extraction will still be done, but the result ignored in this case - } else if (message.getFileName() != null) { - if (this.knownIntents.get("0").expectsFile()) { - state = this.knownIntents.get("0"); - // System.out.println(state.getResponse(random)); - } else { - // if no Incoming Message is fitting, return default message - intent = new Intent("default", "", ""); - } - // Default message if the message does not contain a file or the Intent was too - // low - } else if (intent.getConfidence() < 0.40f) { - intent = new Intent("default", "", ""); - } - - Boolean contextOn = false; - if (this.triggeredFunction.containsKey(message.getChannel())) { - triggeredFunctionId = this.triggeredFunction.get(message.getChannel()); - contextOn = true; - } else { - // check if skip is wished or not - if (state != null) { - System.out.println("Getting response for: "+state.intentKeyword); - System.out.println(state.getResponse()); - if (state.getFollowingMessages().get("skip") != null) { - state = state.getFollowingMessages().get("skip"); - } - - String response = state.getResponse(); - if (state.getTriggeredFunctionId() != "" && state.getTriggeredFunctionId() != null) { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); - contextOn = true; - } - - if (state.getNluID() != "") { - System.out.println("New NluId is : " + state.getNluID()); - this.currentNluModel.put(message.getChannel(), state.getNluID()); - } - if (response != null) { - System.out.println("Debug - Response : " + response); - if (response != "") { - // System.out.println("1"); - String split = ""; - // System.out.println("2"); - // allows users to use linebreaks \n during the modeling for chat responses - for (int i = 0; i < response.split("\\\\n").length; i++) { - System.out.println(i); - split += response.split("\\\\n")[i] + " \n "; - } - // System.out.println("3"); - System.out.println(split); - // System.out.println("4"); - if (split.contains("[") && split.contains("]")) { - // System.out.println("5"); - String[] entitySplit1 = split.split("\\["); - // System.out.println("6"); - ArrayList entitySplit2 = new ArrayList(); - for (int i = 1; i < entitySplit1.length; i++) { - // System.out.println("7"); - entitySplit2.add(entitySplit1[i].split("\\]")[0]); - // System.out.println(7 + i); - } - // System.out.println(entitySplit2); - // System.out.println(recognizedEntities.get(message.getChannel())); - for (String entityName : entitySplit2) { - System.out.println("entity name is " + entityName); - for (Entity entity : recognizedEntities.get(message.getChannel())) { - System.out.println("entity2 name is " + entity.getEntityName()); - if (entityName.equals(entity.getEntityName())) { - System.out.println("replacing now " + entity.getValue()); - String replace = "[" + entity.getEntityName() + "]"; - split = split.replace(replace, entity.getValue()); - } - } - } - - } - // check if message parses buttons or is simple text - if(state.getType().equals("Interactive Message")){ - this.chatMediator.sendBlocksMessageToChannel(message.getChannel(), split, this.chatMediator.getAuthToken(), state.getFollowingMessages(), java.util.Optional.empty()); - } else{ - this.chatMediator.sendMessageToChannel(message.getChannel(), split, state.getFollowingMessages(),state.followupMessageType); - } - // check whether a file url is attached to the chat response and try to send it - // to - // the user - if (!state.getFileURL().equals("")) { - String fileName = ""; - try { - // Replacable variable in url menteeEmail - String urlEmail = state.getFileURL(); - if (message.getEmail() != null) { - urlEmail = state.getFileURL().replace("menteeEmail", - message.getEmail()); - } - System.out.println(urlEmail); - URL url = new URL(urlEmail); - HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); - // Header for l2p services - httpConn.addRequestProperty("Authorization", "Basic " + Base64.getEncoder() - .encodeToString((bot.getName() + ":actingAgent").getBytes())); - - String fieldValue = httpConn.getHeaderField("Content-Disposition"); - System.out.println(fieldValue); - if (fieldValue == null || !fieldValue.contains("filename=\"")) { - System.out.println("No file name available :("); - fieldValue = "pdf.pdf"; - } - // parse the file name from the header field - System.out.println(fieldValue); - fileName = "pdf.pdf"; - if (!fieldValue.equals("pdf.pdf")) { - fileName = fieldValue.substring(fieldValue.indexOf("filename=\"") + 10, - fieldValue.length() - 1); - } else { - // check if name is part of url - if (urlEmail.contains(".pdf") || urlEmail.contains(".png") - || urlEmail.contains(".svg") || urlEmail.contains(".json") - || urlEmail.contains(".txt")) { - fileName = urlEmail.split("/")[urlEmail.split("/").length - 1]; - } - } - InputStream in = httpConn.getInputStream(); - FileOutputStream fileOutputStream = new FileOutputStream(fileName); - int file_size = httpConn.getContentLength(); - if (file_size < 1) { - file_size = 2048; - } - System.out.println("file size is " + file_size); - byte dataBuffer[] = new byte[file_size]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, file_size)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } - fileOutputStream.close(); - this.chatMediator.sendFileMessageToChannel(message.getChannel(), - new File(fileName), ""); - - } catch (Exception e) { - System.out.println("Could not extract File for reason " + e); - e.printStackTrace(); - java.nio.file.Files.deleteIfExists(Paths.get(fileName)); - this.chatMediator.sendMessageToChannel(message.getChannel(), - state.getErrorMessage(),state.getFollowupMessageType()); - } - } - if (state.getTriggeredFunctionId() != null) { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); - contextOn = true; - } - } else { - if (state.getTriggeredFunctionId() != "") { - this.triggeredFunction.put(message.getChannel(), state.getTriggeredFunctionId()); - contextOn = true; - } else { - System.out.println("No Bot Action was given to the Response"); - } - } - } - if (this.triggeredFunction.containsKey(message.getChannel())) { - triggeredFunctionId = this.triggeredFunction.get(message.getChannel()); - } else - triggeredFunctionId = state.getTriggeredFunctionId(); - // If conversation flow is terminated, reset state - if (state.getFollowingMessages().isEmpty()) { - this.stateMap.remove(message.getChannel()); - this.recognizedEntities.remove(message.getChannel()); - } - } - } - if (state == null || !state.getIntentKeyword().contains("defaultX")) { - this.defaultAnswered.put(message.getChannel(), 0); - } - messageInfos.add(new MessageInfo(message, intent, triggeredFunctionId, bot.getName(), - "", contextOn, recognizedEntities.get(message.getChannel()))); - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - - public void setUrl(String Url) throws AuthTokenException { - this.url = Url; - if (this.chatMediator instanceof TelegramChatMediator) { - ((TelegramChatMediator) this.chatMediator).settingWebhook(Url); - } - } - - public void close() { - chatMediator.close(); - } - - private void safeEntities(ChatMessage msg, Bot bot, Intent intent){ - String user = msg.getUser(); - String channel = msg.getChannel(); - String b = bot.getId(); - intent.getEntities().forEach((entity) -> { - String k = entity.getEntityName(); - String v = entity.getValue(); - PreparedStatement stmt = null; - PreparedStatement stmt2 = null; - Connection conn = null; - ResultSet rs = null; - try { - - conn = db.getDataSource().getConnection(); - stmt = conn.prepareStatement("SELECT id FROM attributes WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); - stmt.setString(1, b); - stmt.setString(2, channel); - stmt.setString(3, user); - stmt.setString(4, k); - rs = stmt.executeQuery(); - boolean f = false; - while (rs.next()) - f = true; - if(f){ - // Update - stmt2 = conn.prepareStatement("UPDATE attributes SET `value`=? WHERE `bot`=? AND `channel`=? AND `user`=? AND `key`=?"); - stmt2.setString(1, v); - stmt2.setString(2, b); - stmt2.setString(3, channel); - stmt2.setString(4, user); - stmt2.setString(5, k); - stmt.executeUpdate(); - }else{ - // Insert - stmt2 = conn.prepareStatement("INSERT INTO attributes (`bot`, `channel`, `user`, `key`, `value`) VALUES (?,?,?,?,?)"); - stmt2.setString(1, b); - stmt2.setString(2, channel); - stmt2.setString(3, user); - stmt2.setString(4, k); - stmt2.setString(5, v); - stmt2.executeUpdate(); - } - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - if (rs != null) - rs.close(); - } catch (Exception e) { - } - ; - try { - if (stmt != null) - stmt.close(); - if (stmt2 != null) - stmt2.close(); - } catch (Exception e) { - } - ; - try { - if (conn != null) - conn.close(); - } catch (Exception e) { - } - ; - } - }); - } -} \ No newline at end of file diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/NLUKnowledge.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/NLUKnowledge.java deleted file mode 100644 index 01c50731..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/NLUKnowledge.java +++ /dev/null @@ -1,30 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public class NLUKnowledge { - String name; - String id; - String url; - - public NLUKnowledge(String name, String id, String url) { - this.name = name; - this.url = url; - if (id != "") { - this.id = id; - } else - this.id = "0"; - - } - - public String getName() { - return this.name; - } - - public String getId() { - return this.id; - } - - public String getUrl() { - return this.url; - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java deleted file mode 100644 index c0d9e4a4..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunction.java +++ /dev/null @@ -1,143 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.HashSet; - -public class ServiceFunction extends TriggerFunction{ - private String id; - private String serviceName; - private HashSet bots; - private String functionName; - private String functionPath; - private String httpMethod; - private String consumes; - private String produces; - private ActionType actionType = ActionType.SERVICE; - private String messengerName; - private HashSet attributes; - private HashSet trigger; - - public ServiceFunction() { - setAttributes(new HashSet()); - setBots(new HashSet()); - setTrigger(new HashSet()); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public HashSet getBots() { - return bots; - } - - public void setBots(HashSet bots) { - this.bots = bots; - } - - public void addBot(Bot b) { - this.bots.add(b); - } - - public String getFunctionName() { - return functionName; - } - - public void setFunctionName(String functionName) { - this.functionName = functionName; - } - - public String getFunctionPath() { - return functionPath; - } - - public void setFunctionPath(String functionPath) { - for (ServiceFunctionAttribute attr : attributes) { - if (attr.getParameterType().equals("path")) { - try { - functionPath = functionPath.replaceAll("\\{" + attr.getName() + "\\}", attr.getContent()); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - System.out.println(functionPath); - this.functionPath = functionPath; - } - - public String getConsumes() { - return consumes; - } - - public void setConsumes(String consumes) { - this.consumes = consumes; - } - - public String getProduces() { - return produces; - } - - public void setProduces(String produces) { - this.produces = produces; - } - - public ActionType getActionType() { - return actionType; - } - - public void setActionType(ActionType actionType) { - this.actionType = actionType; - } - - public String getMessengerName() { - return messengerName; - } - - public void setMessengerName(String messengerName) { - this.messengerName = messengerName; - } - - public HashSet getAttributes() { - return attributes; - } - - public void setAttributes(HashSet attributes) { - this.attributes = attributes; - } - - public void addAttribute(ServiceFunctionAttribute attribute) { - this.attributes.add(attribute); - } - - public String getHttpMethod() { - return httpMethod; - } - - public void setHttpMethod(String httpMethod) { - this.httpMethod = httpMethod; - } - - public HashSet getTrigger() { - return trigger; - } - - public void setTrigger(HashSet trigger) { - this.trigger = trigger; - } - - public void addTrigger(Trigger t) { - this.trigger.add(t); - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java deleted file mode 100644 index 6e6463ef..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/ServiceFunctionAttribute.java +++ /dev/null @@ -1,150 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -import java.util.ArrayList; - -public class ServiceFunctionAttribute { - private String id; - private String name; - private String parameterType; - private boolean sameAsTrigger = false; - private ServiceFunctionAttribute mappedTo; - private ArrayList childAttributes; - private ServiceFunctionAttribute parent; - private ServiceFunction function; - private IfThenBlock itb; - - private boolean staticContent; - private String content; - private String contentURL; - private String contentType; - // this attribute will dissapear as everything will be done with a single content attribute - private String nluQuizContent; - - public ServiceFunctionAttribute() { - this.childAttributes = new ArrayList(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String type) { - this.contentType = type; - } - - public ArrayList getChildAttributes() { - return childAttributes; - } - - /*public void setChildAttributes(ArrayList childAttributes) { - this.childAttributes = childAttributes; - }*/ - - public void addChildAttribute(ServiceFunctionAttribute childAttribute) { - this.childAttributes.add(childAttribute); - System.out.println("My child is" + childAttribute); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public boolean isSameAsTrigger() { - return sameAsTrigger; - } - - public void setSameAsTrigger(boolean sameAsTrigger) { - this.sameAsTrigger = sameAsTrigger; - } - - public ServiceFunctionAttribute getMappedTo() { - return mappedTo; - } - - public void setMappedTo(ServiceFunctionAttribute mappedTo) { - this.mappedTo = mappedTo; - } - - public ServiceFunction getFunction() { - return function; - } - - public void setFunction(ServiceFunction function) { - this.function = function; - } - - public boolean hasStaticContent() { - return staticContent; - } - - public void setStaticContent(boolean staticContent) { - this.staticContent = staticContent; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getContentURL() { - return contentURL; - } - - public void setContentURL(String contentURL) { - this.contentURL = contentURL; - } - - public String getParameterType() { - return parameterType; - } - - public void setParameterType(String parameterType) { - this.parameterType = parameterType; - } - - public ServiceFunctionAttribute getParent() { - return parent; - } - - public void setParent(ServiceFunctionAttribute parent) { - System.out.println("My parent is" +parent); - this.parent = parent; - } - - public IfThenBlock getItb() { - return itb; - } - - public void setItb(IfThenBlock itb) { - this.itb = itb; - } - - - - - - @Override - public String toString() { - return "ServiceFunctionAttribute [id=" + id + ", name=" + name + ", parameterType=" + parameterType - + ", sameAsTrigger=" + sameAsTrigger + ", mappedTo=" + mappedTo + ", childAttributes=" + childAttributes - + ", parent=" + parent + ", function=" + function + ", itb=" + itb - + ", staticContent=" + staticContent + ", content=" + content + ", contentURL=" + contentURL - + ", contentType=" + contentType + "]"; - } - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Trigger.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Trigger.java deleted file mode 100644 index 1324bab2..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/Trigger.java +++ /dev/null @@ -1,24 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public class Trigger { - private TriggerFunction triggerFunction; - private ServiceFunction triggeredFunction; - - public Trigger(TriggerFunction t, ServiceFunction s) { - this.triggerFunction = t; - this.triggeredFunction = s; - } - - public TriggerFunction getTriggerFunction() { - return triggerFunction; - } - public void setTriggerFunction(TriggerFunction triggerFunction) { - this.triggerFunction = triggerFunction; - } - public ServiceFunction getTriggeredFunction() { - return triggeredFunction; - } - public void setTriggeredFunction(ServiceFunction triggeredFunction) { - this.triggeredFunction = triggeredFunction; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/TriggerFunction.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/TriggerFunction.java deleted file mode 100644 index bda4da96..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/model/TriggerFunction.java +++ /dev/null @@ -1,5 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.model; - -public abstract class TriggerFunction { - -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Entity.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Entity.java deleted file mode 100644 index 83e2821a..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Entity.java +++ /dev/null @@ -1,49 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.nlu; - -import net.minidev.json.JSONObject; - -public class Entity { - private String entityName; - private String value; - private float confidence; - - // Constructor for entity extraction through Rasa NLU. - public Entity(JSONObject o) { - this.entityName = o.getAsString("entity"); - this.value = o.getAsString("value"); - if (o.getAsNumber("confidence") == null) { - // added this because there was a nullpointerexception when extracting entities, - // may need to further search what caused the problem - // System.out.println("No Confidence Available"); - this.confidence = 1; - } else { - if (o.getAsNumber("confidence_entity") != null) { - this.confidence = o.getAsNumber("confidence_entity").floatValue(); - } else - this.confidence = o.getAsNumber("confidence").floatValue(); - } - System.out.println("Entityname is" + this.entityName); - System.out.println("Entityvalue is" + this.value); - } - - // Constructor for bypassing entity extraction. Used for '!'-commands, for - // example. - public Entity(String entityName, String entityValue) { - - this.entityName = entityName; - this.value = entityValue; - this.confidence = 1.0f; - } - - public String getEntityName() { - return entityName; - } - - public float getConfidence() { - return confidence; - } - - public String getValue() { - return value; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Intent.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Intent.java deleted file mode 100644 index 8f4b5f18..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/Intent.java +++ /dev/null @@ -1,95 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.nlu; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map.*; -import java.util.ArrayList; - -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; - -public class Intent { - private String intentKeyword; - private float confidence; - - private HashMap entities; - - private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, - { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, - { new String("ö"), "oe" }, { new String("ß"), "ss" } }; - - public static String replaceUmlaute(String orig) { - String result = orig; - - for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) { - result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]); - } - - return result; - } - - // Constructor for intent extraction through Rasa NLU. - public Intent(JSONObject json) { - JSONObject intentInner = (JSONObject) json.get("intent"); - float confidence = intentInner.getAsNumber("confidence").floatValue(); - this.intentKeyword = replaceUmlaute(intentInner.getAsString("name")); - this.confidence = confidence; - - JSONArray entities = (JSONArray) json.get("entities"); - HashMap entitiesMap = new HashMap(); - - entities.forEach(o -> { - Entity entity = new Entity((JSONObject) o); - // System.out.println("Entity "+ entity.getEntityName() + "extracted with value - // " + entity.getValue()); - if (!entitiesMap.containsKey(entity.getEntityName())) { - entitiesMap.put(entity.getEntityName(), entity); - } - }); - this.entities = entitiesMap; - } - - // Constructor for bypassing intent extraction. Used for '!'-commands, for - // example. - public Intent(String intentKeyword, String entityName, String entityValue) { - this.intentKeyword = replaceUmlaute(intentKeyword); - this.confidence = 1.0f; - this.entities = new HashMap(); - this.entities.put(entityName, new Entity(entityName, entityValue)); - } - - public String getKeyword() { - return this.intentKeyword; - } - - public float getConfidence() { - return this.confidence; - } - - public Entity getEntity(String entity) { - return this.entities.get(entity); - } - - - /* public ArrayList getEntities(){ - ArrayList extractedEntities= new ArrayList(); - for(Entry entry : entities.entrySet()) { - String key = entry.getKey(); - extractedEntities.add(key); - } - return extractedEntities; - } - */ - public ArrayList getEntitieValues(){ - ArrayList extractedEntitieValues= new ArrayList(); - for(Entry entry : entities.entrySet()) { - String value = entry.getValue().getValue(); - extractedEntitieValues.add(value); - } - return extractedEntitieValues; - } - - public Collection getEntities() { - return this.entities.values(); - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java deleted file mode 100644 index 8ddbf6d5..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/RasaNlu.java +++ /dev/null @@ -1,67 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.nlu; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; - -import javax.ws.rs.core.MediaType; - -import org.apache.commons.lang3.StringEscapeUtils; - -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; - -public class RasaNlu { - private String url; - private HashSet intents; - public RasaNlu(String url) { - this.url = url; - this.intents = new HashSet(); - } - - public void addIntent(String intent){ - this.intents.add(intent); - } - - public void setIntents(HashSet intents){ - this.intents = intents; - } - - public String[] getIntents(){ - return this.intents.toArray(new String[this.intents.size()]); - } - - public Intent getIntent(String input) { - JSONObject intentJSON; - try { - intentJSON = getIntentJSON(input); - return new Intent(intentJSON); - } catch (IOException | ParseException e) { - System.err.println("Error retrieving intent from Rasa NLU:"); - e.printStackTrace(); - } - return null; - } - - private JSONObject getIntentJSON(String input) throws IOException, ParseException { - try { - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(this.url); - JSONObject inputJSON = new JSONObject( - Collections.singletonMap("text", StringEscapeUtils.escapeJson(input))); - HashMap headers = new HashMap(); - ClientResponse response = client.sendRequest("POST", "model/parse", inputJSON.toString(), - MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, headers); - System.out.println("Result: " + response.getResponse()); - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - return (JSONObject) p.parse(response.getResponse()); - } catch (Exception e) { - e.printStackTrace(); - return new JSONObject(); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/TrainingHelper.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/TrainingHelper.java deleted file mode 100644 index ed1b17b4..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/nlu/TrainingHelper.java +++ /dev/null @@ -1,88 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.nlu; - -import java.util.HashMap; - -import javax.ws.rs.core.MediaType; - -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import net.minidev.json.JSONObject; - -public class TrainingHelper implements Runnable { - String url; - String config; - String markdownTrainingData; - - boolean success = false; - private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, - { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, { new String("ö"), "oe" }, - { new String("ß"), "ss" } }; - - public static String replaceUmlaute(String orig) { - String result = orig; - - for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) { - result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]); - } - - return result; - } - - public TrainingHelper(String url, String config, String markdownTrainingData) { - this.url = url; - this.config = config; - this.markdownTrainingData = replaceUmlaute(markdownTrainingData); - } - - @Override - // Trains and loads the model trained with the data given in the constructor. - public void run() { - MiniClient client = new MiniClient(); - client.setConnectorEndpoint(url); - - JSONObject json = new JSONObject(); - json.put("config", config); - if (markdownTrainingData.contains("examples: |")) { - // json.put("domain", markdownTrainingData.replace("\\t", "")); - json.put("nlu", markdownTrainingData); - HashMap headers = new HashMap(); - ClientResponse response = client.sendRequest("POST", "model/train", markdownTrainingData, - MediaType.TEXT_PLAIN + ";charset=utf-8", MediaType.APPLICATION_JSON + ";charset=utf-8", headers); - - String filename = response.getHeader("filename"); - if (filename == null) { - this.success = false; - return; - } - - json = new JSONObject(); - json.put("model_file", "models/" + filename); - - response = client.sendRequest("PUT", "model", json.toString(), MediaType.APPLICATION_JSON + ";charset=utf-8", - MediaType.APPLICATION_JSON + ";charset=utf-8", headers); - this.success = response.getHttpCode() == 204; - } else { - json.put("nlu", markdownTrainingData); - HashMap headers = new HashMap(); - ClientResponse response = client.sendRequest("POST", "model/train", json.toJSONString(), - MediaType.APPLICATION_JSON + ";charset=utf-8", MediaType.APPLICATION_JSON + ";charset=utf-8", headers); - - String filename = response.getHeader("filename"); - if (filename == null) { - this.success = false; - return; - } - - json = new JSONObject(); - json.put("model_file", "models/" + filename); - - response = client.sendRequest("PUT", "model", json.toString(), MediaType.APPLICATION_JSON + ";charset=utf-8", - MediaType.APPLICATION_JSON + ";charset=utf-8", headers); - this.success = response.getHttpCode() == 204; - } - } - - public boolean getSuccess() { - return this.success; - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java deleted file mode 100644 index b4da490e..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/BotParser.java +++ /dev/null @@ -1,795 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.parser; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map.Entry; - -import javax.websocket.DeploymentException; -import javax.ws.rs.core.MediaType; - -import com.google.gson.Gson; - -import i5.las2peer.api.Context; -import i5.las2peer.api.logging.MonitoringEvent; -import i5.las2peer.api.security.AgentException; -import i5.las2peer.api.security.AgentNotFoundException; -import i5.las2peer.connectors.webConnector.client.ClientResponse; -import i5.las2peer.connectors.webConnector.client.MiniClient; -import i5.las2peer.security.BotAgent; -import i5.las2peer.services.socialBotManagerService.chat.AuthTokenException; -import i5.las2peer.services.socialBotManagerService.database.SQLDatabase; -import i5.las2peer.services.socialBotManagerService.model.ActionType; -import i5.las2peer.services.socialBotManagerService.model.Bot; -import i5.las2peer.services.socialBotManagerService.model.BotConfiguration; -import i5.las2peer.services.socialBotManagerService.model.BotModelEdge; -import i5.las2peer.services.socialBotManagerService.model.BotModelNode; -import i5.las2peer.services.socialBotManagerService.model.BotModelNodeAttribute; -import i5.las2peer.services.socialBotManagerService.model.BotModelValue; -import i5.las2peer.services.socialBotManagerService.model.IfThenBlock; -import i5.las2peer.services.socialBotManagerService.model.IncomingMessage; -import i5.las2peer.services.socialBotManagerService.model.IntentEntity; -import i5.las2peer.services.socialBotManagerService.model.Messenger; - -import i5.las2peer.services.socialBotManagerService.model.NLUKnowledge; - -import i5.las2peer.services.socialBotManagerService.model.ServiceFunction; -import i5.las2peer.services.socialBotManagerService.model.ServiceFunctionAttribute; -import i5.las2peer.services.socialBotManagerService.model.Trigger; -import i5.las2peer.services.socialBotManagerService.model.BotRoutine; -import i5.las2peer.tools.CryptoException; -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; - -public class BotParser { - private static BotParser instance = null; - private static final String botPass = "actingAgent"; - - protected BotParser() { - } - - public static BotParser getInstance() { - if (instance == null) { - instance = new BotParser(); - } - return instance; - } - - public void parseNodesAndEdges(BotConfiguration config, HashMap botAgents, - LinkedHashMap nodes, LinkedHashMap edges, SQLDatabase database) - throws ParseBotException, IOException, DeploymentException, AuthTokenException { - - HashMap messengers = new HashMap(); - HashMap incomingMessages = new HashMap(); - HashMap responses = new HashMap(); - HashMap intentEntities = new HashMap(); - HashMap bots = new HashMap(); - - HashMap nluKnowledge = new HashMap(); - - HashMap bsfList = new HashMap(); - HashMap usfList = new HashMap(); - HashMap sfaList = new HashMap(); - - HashMap itbList = new HashMap(); - HashMap rlist = new HashMap(); - - Bot bot = null; - Gson g = new Gson(); - // NODES - for (Entry entry : nodes.entrySet()) { - BotModelNode elem = entry.getValue(); - String nodeType = elem.getType(); - - if (nodeType.equals("Bot")) { - try{ - bot = addBot(elem, botAgents); - config.addBot(bot.getName(), bot); - bots.put(entry.getKey(), bot); - } catch (Exception e){ - throw e; - } - // Messenger - }else if (nodeType.equals("Messenger")) { - Messenger m = addMessenger(entry.getKey(), elem, config, database); - messengers.put(entry.getKey(), m); - } else if (nodeType.equals("Incoming Message")) { - IncomingMessage m = addIncomingMessage(entry.getKey(), elem, config); - incomingMessages.put(entry.getKey(), m); - } else if (nodeType.equals("Intent Entity")) { - IntentEntity entity = addIntentEntity(entry.getKey(), elem, config); - intentEntities.put(entry.getKey(), entity); - // Nlu Url's - } else if (nodeType.equals("NLU Knowledge")) { - NLUKnowledge nlu = addNLUKnowledge(entry.getKey(), elem, config); - nluKnowledge.put(entry.getKey(), nlu); - // VLE Routine - } else if (nodeType.equals("Routine")) { - BotRoutine routine = addRoutine(elem); - rlist.put(entry.getKey(), routine); - // BOT Action - } else if (nodeType.equals("IfThen")) { - IfThenBlock ifThenBlock = addIfThenBlock(elem); - itbList.put(entry.getKey(), ifThenBlock); - // BOT Action - } else if (nodeType.equals("Bot Action")) { - ServiceFunction sf = addAction(entry.getKey(), elem, config); - bsfList.put(entry.getKey(), sf); - // User Action - } else if (nodeType.equals("Action Parameter")) { - ServiceFunctionAttribute sfa = addActionParameter(entry.getKey(), elem); - sfaList.put(entry.getKey(), sfa); - } - } - - if (bots.isEmpty()) { - throw new ParseBotException("Missing Bot!"); - } else if (bsfList.isEmpty() && rlist.isEmpty() && incomingMessages.isEmpty()) { - throw new ParseBotException("Missing Bot Action and Chat interaction! (You need at least one chat interaction OR a bot action for the bot to work)"); - } - - // ToDo - bot.setRoutines(rlist); - - if (bots.size() == 0) { - throw new ParseBotException("Missing Bot!"); - } - - int checkGeneratorIns = 0; - int checkGeneratorOuts = 0; - - // EDGES - for (Entry entry : edges.entrySet()) { - BotModelEdge elem = entry.getValue(); - String type = elem.getType(); - String source = elem.getSource(); - String target = elem.getTarget(); - String value = elem.getLabel().getValue().getValue(); - // HAS - if (type.equals("has")) { - // VLE has... - if (bots.get(source) != null) { - Bot b = bots.get(source); - // ...messenger / ChatMediator - if (messengers.get(target) != null) { - Messenger m = messengers.get(target); - b.addMessenger(m, b.getAddress()); - // NLU Servers - } else if (nluKnowledge.get(target) != null){ - NLUKnowledge nlu = nluKnowledge.get(target); - b.addRasaServer(nlu.getId(), nlu.getUrl()); - } - // User Function has... - } else if (usfList.get(source) != null) { - ServiceFunction sf = usfList.get(source); - // ...Parameter - if (sfaList.get(target) != null) { - ServiceFunctionAttribute sfa = sfaList.get(target); - sf.addAttribute(sfa); - sfa.setFunction(sf); - } - // Bot Function has... - } else if (bsfList.get(source) != null) { - ServiceFunction sf = bsfList.get(source); - // ...Parameter - if (sfaList.get(target) != null) { - ServiceFunctionAttribute sfa = sfaList.get(target); - sf.addAttribute(sfa); - sfa.setFunction(sf); - } - // Function Parameter has... - } else if (sfaList.get(source) != null) { - ServiceFunctionAttribute sfaParent = sfaList.get(source); - // ...Parameter - if (sfaList.get(target) != null) { - ServiceFunctionAttribute sfaChild = sfaList.get(target); - sfaParent.addChildAttribute(sfaChild); - sfaChild.setParent(sfaParent); - } - // Incoming Message has... - } else if (incomingMessages.get(source) != null) { - IncomingMessage message = incomingMessages.get(source); - // ...Intent Entity - if (intentEntities.get(target) != null) { - IntentEntity entity = intentEntities.get(target); - message.setEntityKeyword(entity.getEntityKeyword()); - } - } - // PERFORMS - } else if (type.equals("performs")) { - // Bot performs Action - if (bots.get(source) != null && bots.get(source).equals(bot)) { - //Bot bot = bots.get(source); - ServiceFunction bsfListItem = bsfList.get(target); - if (bsfListItem != null) { - bot.addBotServiceFunction(bsfListItem.getId(), bsfListItem); - bsfListItem.addBot(bot); - } - } else if (bots.get(source) != null) { - Bot v = bots.get(source); - BotRoutine r = rlist.get(target); - if (r != null) { - v.addRoutine(target, r); - r.setBot(v); - } - } - - // same as - // TODO - } else if (type.equals("same as")) { - sfaList.get(source).setSameAsTrigger(true); - sfaList.get(source).setMappedTo(sfaList.get(target)); - sfaList.get(target).setSameAsTrigger(true); - sfaList.get(target).setMappedTo(sfaList.get(source)); - // USES - } else if (type.equals("uses")) { - if (itbList.get(source) != null) { - IfThenBlock itb = itbList.get(source); - if (itbList.get(target) != null) { - // chain - IfThenBlock prev = itbList.get(target); - itb.setPrev(prev); - prev.setNext(itb); - } else if (sfaList.get(target) != null) { - ServiceFunctionAttribute sAtt = sfaList.get(target); - itb.setSourceAttribute(sAtt); - } - // Bot Action uses Messenger - } else if (bsfList.containsKey(source)) { - ServiceFunction sf = bsfList.get(source); - Messenger m = messengers.get(target); - if (m == null) { - throw new ParseBotException("Bot Action uses Messenger, but is not connected to Messenger"); - } - sf.setMessengerName(m.getName()); - } else if (responses.containsKey(source)){ - IncomingMessage cr = responses.get(source); - if (bsfList.get(target) != null) { - ServiceFunction botFunction = bsfList.get(target); - cr.setTriggeredFunctionId(botFunction.getId()); - } - } - - // GENERATES - } else if (type.equals("generates")) { - if (itbList.get(source) != null) { - IfThenBlock itb = itbList.get(source); - if (sfaList.get(target) != null) { - ServiceFunctionAttribute sAtt = sfaList.get(target); - sAtt.setItb(itb); - itb.setTargetAttribute(sAtt); - } - // Messenger generates... - } else if (messengers.containsKey(source)) { - Messenger messenger = messengers.get(source); - // ...IncomingMessage - if (incomingMessages.containsKey(target)) { - IncomingMessage incMsg = incomingMessages.get(target); - messenger.addMessage(incMsg); - } - } - // TRIGGERS - // LEADSTO - // left precedes in the query so that older bots can still be used with the manager, but will need to get removed later on - } else if (type.equals("leadsTo") || type.equals("precedes") ) { - // IncomingMessage leads to... - if (incomingMessages.containsKey(source)) { - IncomingMessage sourceMessage = incomingMessages.get(source); - // ...another IncomingMessage - if (incomingMessages.containsKey(target)) { - IncomingMessage targetMessage = incomingMessages.get(target); - sourceMessage.addFollowupMessage(value, targetMessage); - } - } - } - } - - - - for(IncomingMessage m : incomingMessages.values()){ - String nluId = m.getNluID(); - if(bot.getRasaServer(nluId)!=null){ - bot.getRasaServer(nluId).addIntent(m.getIntentKeyword()); - }else{ - throw new ParseBotException("Missing NLU Knowledge, ID: "+ nluId); - } - } - - // EDGES - for (Entry entry : edges.entrySet()) { - BotModelEdge elem = entry.getValue(); - String type = elem.getType(); - String source = elem.getSource(); - String target = elem.getTarget(); - String value = elem.getLabel().getValue().getValue(); - if (type.equals("triggers")) { - // Action triggers action - if (usfList.get(source) != null) { - ServiceFunction userFunction = usfList.get(source); - if (bsfList.get(target) != null) { - ServiceFunction botFunction = bsfList.get(target); - Trigger t = new Trigger(userFunction, botFunction); - userFunction.addTrigger(t); - for (Bot b : botFunction.getBots()) { - b.addTrigger(t); - } - } - // Routine triggers action - } else if (rlist.get(source) != null) { - BotRoutine r = rlist.get(source); - if (bsfList.get(target) != null) { - ServiceFunction botFunction = bsfList.get(target); - Trigger t = new Trigger(r, botFunction); - r.addTrigger(t); - } - // Incoming Message triggers... - } else if (incomingMessages.get(source) != null) { - IncomingMessage m = incomingMessages.get(source); - // ...Chat Response - if (responses.get(target) != null) { - IncomingMessage response = responses.get(target); - response.addTriggerEntity(value); - m.addResponse(response); - - // ...Bot Action - } else if (bsfList.get(target) != null) { - ServiceFunction botFunction = bsfList.get(target); - m.setTriggeredFunction(botFunction); - } - } - } - } - - if (checkGeneratorIns != checkGeneratorOuts) { - throw new ParseBotException("Check the Content Generator connections! There are " + checkGeneratorIns - + " inputs and " + checkGeneratorOuts + " outputs."); - } - - JSONArray jaf = swaggerHelperFunction(bot); - - JSONObject j = new JSONObject(); - j.put("triggerFunctions", jaf); - System.out.println(jaf.toJSONString()); - JSONArray jarr = new JSONArray(); - for (BotAgent b : botAgents.values()) { - jarr.add(b.getIdentifier()); - } - j.put("botIds", jarr); - - Context.get().monitorEvent(MonitoringEvent.BOT_ADD_TO_MONITORING, j.toJSONString()); - } - - private Messenger addMessenger(String key, BotModelNode elem, BotConfiguration config, SQLDatabase database) - throws ParseBotException, IOException, DeploymentException, AuthTokenException{ - String messengerName = null; - String messengerType = null; - String token = null; - String url = null; - - // TODO: Reduce code duplication - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.contentEquals("Name")) { - messengerName = subVal.getValue(); - } else if (name.contentEquals("Messenger Type")) { - messengerType = subVal.getValue(); - } else if (name.contentEquals("Authentication Token")) { - token = subVal.getValue(); - } - } - if (messengerName == null) { - throw new ParseBotException("Messenger is missing a name"); - } - if (messengerType == null) { - throw new ParseBotException("Messenger is missing \"Messenger Type\" attribute"); - } - if (token == null || token == "") { - throw new ParseBotException("Messenger is missing \"Authentication Token\" attribute"); - } - - Messenger newMessenger = new Messenger(messengerName, messengerType, token, database); - return newMessenger; - - } - - private NLUKnowledge addNLUKnowledge(String key, BotModelNode elem, BotConfiguration config) - throws ParseBotException { - String rasaName = null; - String id = null; - String url = null; - // TODO: Reduce code duplication - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.contentEquals("Name")) { - rasaName = subVal.getValue(); - } else if(name.contentEquals("ID")){ - id = subVal.getValue(); - } else if(name.contentEquals("URL")){ - url = subVal.getValue(); - } - } - - if (url == null || url == "") { - throw new ParseBotException("NLU Knowledge without URL"); - } - - return new NLUKnowledge(rasaName, id, url); - } - - private IncomingMessage addIncomingMessage(String key, BotModelNode elem, BotConfiguration config) - throws ParseBotException { - String intentKeyword = null; - String NluID = null; - Boolean containsFile = null; - String message = null; - String fileURL = null; - String errorMessage = null; - String type = null; - String intentLabel = null; - String followupMessageType = null; - - // TODO: Reduce code duplication - try{ - for (Entry subEntry : elem.getAttributes().entrySet()) { - - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.contentEquals("Intent Keyword")) { - intentKeyword = subVal.getValue(); - } else if (name.contentEquals("NLU ID")){ - NluID = subVal.getValue(); - } else if (name.contentEquals("IsFile")){ - containsFile = Boolean.valueOf(subVal.getValue()); - } else if (name.contentEquals("Message")) { - message = subVal.getValue(); - } else if (name.contentEquals("FileURL")) { - fileURL = subVal.getValue(); - } else if (name.contentEquals("ErrorMessage")) { - errorMessage = subVal.getValue(); - } else if (name.contentEquals("Type")) { - type = subVal.getValue(); - } else if (name.contentEquals("Intent Label")) { - intentLabel = subVal.getValue(); - } else if (name.contentEquals("Followup Message Type")) { - followupMessageType = subVal.getValue(); - } - } - } catch(Exception e){ - System.out.println("Error: " + e.getMessage()); - - } - - if (intentKeyword == null) { - throw new ParseBotException("Incoming Message is missing Intent Keyword"); - } else if (NluID== null) { - throw new ParseBotException("Incoming Message is missing NluID"); - } - - if(intentKeyword.equals("")) { - intentKeyword = "0"; - } - - if (message == null) { - throw new ParseBotException("Response is missing Message"); - } - if (fileURL == null) { - throw new ParseBotException("Response is missing File URL"); - } - if (errorMessage == null) { - throw new ParseBotException("Response is missing Error Message"); - } - if (type == null) { - throw new ParseBotException("Response is missing Type"); - } - - return new IncomingMessage(intentKeyword, NluID, containsFile, message, fileURL, errorMessage, type, intentLabel, followupMessageType); - } - - private IntentEntity addIntentEntity(String key, BotModelNode elem, BotConfiguration config) - throws ParseBotException { - String intentEntity = null; - - // TODO: Reduce code duplication - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.contentEquals("Keyword")) { - intentEntity = subVal.getValue(); - } - } - - if (intentEntity == null) { - throw new ParseBotException("Intent Entity is missing Keyword"); - } - - return new IntentEntity(intentEntity); - } - - private Bot addBot(BotModelNode elem, HashMap botAgents) { - Bot b = new Bot(); - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - if (subVal.getName().equals("Name")) { - String botName = subVal.getValue(); - BotAgent botAgent = null; - try { - try { - botAgent = (BotAgent) Context.getCurrent() - .fetchAgent(Context.getCurrent().getUserAgentIdentifierByLoginName(botName)); - } catch (AgentNotFoundException e) { - // AgentOperationFailedException should be handled separately - botAgent = BotAgent.createBotAgent(botPass); - botAgent.unlock(botPass); - botAgent.setLoginName(botName); - System.out.println(botName); - Context.getCurrent().storeAgent(botAgent); - System.out.println("Here?"); - } - botAgent.unlock(botPass); - Context.getCurrent().registerReceiver(botAgent); - } catch (AgentException | IllegalArgumentException | CryptoException e2) { - // TODO Errorhandling - System.out.println("Caught the error here"); - e2.printStackTrace(); - throw new IllegalArgumentException(e2); - } - // runningAt = botAgent.getRunningAtNode(); - System.out.println("Bot " + botName + " registered at: " + botAgent.getRunningAtNode().getNodeId()); - - // config.addBot(botAgent.getIdentifier(), botAgent.getLoginName()); - b.setId(botAgent.getIdentifier()); - b.setName(botAgent.getLoginName()); - botAgents.put(botName, botAgent); - } - } - return b; - } - - private BotRoutine addRoutine(BotModelNode elem) { - BotRoutine r = new BotRoutine(); - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.equals("Name")) { - String routineName = subVal.getValue(); - r.setName(routineName); - } else if (name.equals("Time")) { - String routineTime = subVal.getValue(); - r.setTime(routineTime); - } else if (name.equals("Interval")) { - String routineInterval = subVal.getValue(); - r.setInterval(routineInterval); - } - } - return r; - } - - private IfThenBlock addIfThenBlock(BotModelNode elem) { - IfThenBlock itb = new IfThenBlock(); - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.equals("Condition Type")) { - itb.setConditionType(subVal.getValue()); - } else if (name.equals("Statement Type")) { - itb.setStatementType(subVal.getValue()); - } else if (name.equals("Condition A")) { - itb.setConditionValueA(subVal.getValue()); - } else if (name.equals("Condition B")) { - itb.setConditionValueB(subVal.getValue()); - } else if (name.equals("Statement A")) { - itb.setStatementValueA(subVal.getValue()); - } else if (name.equals("Statement B")) { - itb.setStatementValueB(subVal.getValue()); - } - } - return itb; - } - - private ServiceFunction addAction(String key, BotModelNode elem, BotConfiguration config) - throws IOException, DeploymentException { - ServiceFunction sf = new ServiceFunction(); - sf.setId(key); - String actionType = ""; - String messengerID = ""; - String service = ""; - String sfName = ""; - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.equals("Function Name")) { - sfName = subVal.getValue(); - } else if (name.equals("Service Alias")) { - service = subVal.getValue(); - } else if (name.equals("Action Type")) { - actionType = subVal.getValue(); - } else if (name.equals("Messenger Name")) { - messengerID = subVal.getValue(); - } - } - - if (actionType.equals("SendMessage")) { - sf.setActionType(ActionType.SENDMESSAGE); - sf.setMessengerName(messengerID); - sf.setServiceName(service); - sf.setFunctionName(sfName); - } else if (actionType.equals("OpenAPI")) { - URL functionURL = null; - // Open API with full path - // service alias should contain base path, so that /swagger can be added - // afterwards - try { - functionURL = new URL(service); - sf.setFunctionName(sfName); - sf.setFunctionPath(service); - sf.setServiceName(service); - sf.setActionType(ActionType.OPENAPI); - // maybe check here whether there is a swagger.json? if not, return null - } catch (Exception e) { - System.out.println("Given URL in service alias is not correct"); - return null; - } - } else { - // default case - sf.setFunctionName(sfName); - sf.setServiceName(service); - } - return sf; - } - - private ServiceFunctionAttribute addActionParameter(String key, BotModelNode elem) { - - ServiceFunctionAttribute sfa = new ServiceFunctionAttribute(); - sfa.setId(key); - for (Entry subEntry : elem.getAttributes().entrySet()) { - BotModelNodeAttribute subElem = subEntry.getValue(); - BotModelValue subVal = subElem.getValue(); - String name = subVal.getName(); - if (name.equals("Content Type")) { - if(subVal.getValue() == "Quiz") { - sfa.setContentType("String"); - } else sfa.setContentType(subVal.getValue()); - } else if (name.equals("Name")) { - sfa.setName(subVal.getValue()); - } else if (name.equals("Static")) { - sfa.setStaticContent(Boolean.parseBoolean(subVal.getValue())); - } else if (name.equals("Content")) { - sfa.setContent(subVal.getValue()); - } else if (name.equals("URL")) { - sfa.setContentURL(subVal.getValue()); - } else if (name.equals("Parameter Type")) { - String pType = subVal.getValue(); - sfa.setParameterType(pType); - } - } - return sfa; - } - - - private void addServiceInformation(ServiceFunction f, JSONObject elem) { - // pfade - for (HashMap.Entry subEntry : ((JSONObject) elem.get("paths")).entrySet()) { - // type - for (HashMap.Entry subsubEntry : ((JSONObject) subEntry.getValue()).entrySet()) { - JSONObject functionInfo = (JSONObject) subsubEntry.getValue(); - String opId = (String) functionInfo.get("operationId"); - JSONArray consumes = (JSONArray) functionInfo.get("consumes"); - JSONArray produces = (JSONArray) functionInfo.get("produces"); - if (opId.toLowerCase().equals(f.getFunctionName().toLowerCase())) { - f.setFunctionPath(subEntry.getKey()); - f.setHttpMethod(subsubEntry.getKey()); - if (consumes == null) { - f.setConsumes("text/html"); - } else { - f.setConsumes(consumes.get(0).toString()); - } - if (produces == null) { - f.setProduces("text/html"); - } else { - f.setProduces(produces.get(0).toString()); - } - } - } - } - } - - private JSONArray swaggerHelperFunction(Bot b) { - JSONArray jaf = new JSONArray(); - HashMap allFunctions = new HashMap(); - - for (Trigger t : b.getTriggerList()) { - if (t.getTriggerFunction() instanceof ServiceFunction) { - ServiceFunction sf = (ServiceFunction) t.getTriggerFunction(); - jaf.add(sf.getFunctionName()); - } - - } - - allFunctions.putAll(b.getBotServiceFunctions()); - for (ServiceFunction s : allFunctions.values()) { - // try to get swagger information - - if (b.getServiceInformation().get(s.getServiceName()) == null - /*&& s.getActionType().equals(ActionType.SERVICE)*/ ) { - try { - - System.out.println("Service name is:" + s.getServiceName() + "\nBot is : " + b.getName()); - if (s.getActionType().equals(ActionType.OPENAPI)) { - JSONObject j = readJsonFromUrl(s.getFunctionPath() + "/swagger.json"); - System.out.println("Information is: " + j); - b.addServiceInformation(s.getServiceName(), j); - } else { - JSONObject j = readJsonFromUrl( - b.getAddress() + "/" + s.getServiceName() + "/swagger.json"); - System.out.println("Information is: " + j); - b.addServiceInformation(s.getServiceName(), j); - if (s.getServiceName().equals("AssessmentHandler")) { - MiniClient client = new MiniClient(); - // client.setLogin(, password); - client.setConnectorEndpoint(b.getAddress()); - HashMap headers = new HashMap(); - JSONObject botName = new JSONObject(); - - System.out.println(b); - - botName.put("botName", b.getId()); - // client.setLogin("alice", "pwalice"); - client.setLogin(b.getId(), "actingAgent"); - - ClientResponse result = client.sendRequest("POST", "AssessmentHandler/reset", - botName.toString(), MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, headers); - - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - if (b.getServiceInformation().get(s.getServiceName()) != null && s.getFunctionName() != null) { - addServiceInformation(s, b.getServiceInformation().get(s.getServiceName())); - } - } - return jaf; - } - - private static String readAll(Reader rd) throws IOException { - StringBuilder sb = new StringBuilder(); - int cp; - while ((cp = rd.read()) != -1) { - sb.append((char) cp); - } - return sb.toString(); - } - - private static JSONObject readJsonFromUrl(String url) throws IOException, ParseException { - InputStream is = new URL(url).openStream(); - try { - BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); - String jsonText = readAll(rd); - JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); - JSONObject json = (JSONObject) p.parse(jsonText); - return json; - } finally { - is.close(); - } - } -} diff --git a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/ParseBotException.java b/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/ParseBotException.java deleted file mode 100644 index a9c60086..00000000 --- a/social-bot-manager/src/test/java/java/i5/las2peer/services/socialBotManagerService/parser/ParseBotException.java +++ /dev/null @@ -1,10 +0,0 @@ -package i5.las2peer.services.socialBotManagerService.parser; - -public class ParseBotException extends Exception { - - private static final long serialVersionUID = 3581207731993661888L; - - public ParseBotException(String msg) { - super(msg); - } -}