├── .DS_Store ├── src ├── .DS_Store ├── banner.png ├── diagram.png └── main │ ├── .DS_Store │ ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── openai │ │ ├── .DS_Store │ │ ├── repository │ │ ├── SlackViewRepository.java │ │ ├── OpenAiModalRepository.java │ │ ├── SlackOauthResponseRepository.java │ │ ├── SlackUserRepository.java │ │ ├── UserRequestDetailsRepository.java │ │ └── TextRequestQueueRepository.java │ │ ├── slack │ │ ├── event │ │ │ └── dto │ │ │ │ ├── RefundOrder.java │ │ │ │ ├── AuthedUser.java │ │ │ │ ├── ReplaceOrder.java │ │ │ │ ├── EscalateToAgent.java │ │ │ │ ├── OrderActionBase.java │ │ │ │ ├── Channel.java │ │ │ │ ├── Team.java │ │ │ │ ├── AccessToken.java │ │ │ │ ├── Files.java │ │ │ │ ├── Block.java │ │ │ │ ├── Element.java │ │ │ │ ├── OrderUtils.java │ │ │ │ ├── User.java │ │ │ │ ├── Container.java │ │ │ │ ├── SlideData.java │ │ │ │ ├── Action.java │ │ │ │ ├── BotProfile.java │ │ │ │ ├── Authorization.java │ │ │ │ ├── Order.java │ │ │ │ ├── FunctionCallBase.java │ │ │ │ ├── SlackOAuthResponse.java │ │ │ │ ├── View.java │ │ │ │ ├── EventPayload.java │ │ │ │ └── Event.java │ │ └── services │ │ │ ├── AsyncExceptionHandler.java │ │ │ ├── ExceptionNotificationService.java │ │ │ ├── SlackOauthService.java │ │ │ ├── ViewUpdateService.java │ │ │ ├── SlackUserService.java │ │ │ └── SlackMessageServices.java │ │ ├── utils │ │ ├── VideoToAudioConverter.java │ │ ├── FileTypeChecker.java │ │ ├── TimeUtils.java │ │ ├── Constants.java │ │ ├── SlackDTOConvertor.java │ │ └── SlackUtils.java │ │ ├── entity │ │ ├── SlackView.java │ │ ├── UserRequestDetails.java │ │ ├── SlackUseridTeamid.java │ │ ├── SlackOauthModal.java │ │ ├── OpenAiModal.java │ │ ├── SlackUser.java │ │ └── TextRequestQueue.java │ │ ├── OpenAiApplication.java │ │ ├── GlobalExceptionHandler.java │ │ ├── controller │ │ └── HealthCheck.java │ │ ├── services │ │ ├── TwitterService.java │ │ ├── CustomeOpenAIClient.java │ │ ├── PowerPointCreator.java │ │ ├── OpenAiMessageRequestCreator.java │ │ └── OpenAiMessageCreation.java │ │ ├── OpenAiConfig.java │ │ └── eventlistner │ │ └── EventService.java │ └── resources │ ├── application.properties │ ├── quotaCompleted.txt │ ├── summaryMessage.json │ ├── application-local.properties │ ├── postMessage.json │ ├── welcomeMessage.txt │ ├── userwithnoprimeaccess.json │ ├── userselection.json │ ├── customerservice.json │ ├── feedbackView.json │ ├── moodselection.json │ ├── SectorSelection.json │ ├── codetoTranslate.json │ ├── afterpaymentview.json │ ├── firstTimeView.json │ ├── codetoWrite.json │ └── langtranslation.json ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .gitignore ├── README.md ├── pom.xml ├── mvnw.cmd └── mvnw /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/.DS_Store -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /src/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/banner.png -------------------------------------------------------------------------------- /src/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/diagram.png -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=local 2 | #spring.datasource.password=password -------------------------------------------------------------------------------- /src/main/java/com/openai/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yashjani/slackbot/HEAD/src/main/java/com/openai/.DS_Store -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/SlackViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import com.openai.entity.SlackView; 5 | 6 | public interface SlackViewRepository extends JpaRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/OpenAiModalRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import com.openai.entity.OpenAiModal; 5 | 6 | public interface OpenAiModalRepository extends JpaRepository{ 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/RefundOrder.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.Optional; 4 | 5 | public class RefundOrder extends OrderActionBase { 6 | public RefundOrder(Optional rationale, Optional imageDescription, String action, Optional message) { 7 | super(rationale, imageDescription, action, message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/AuthedUser.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class AuthedUser { 4 | 5 | private String id; 6 | 7 | public String getId() { 8 | return id; 9 | } 10 | 11 | public void setId(String id) { 12 | this.id = id; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "AuthedUser [id=" + id + "]"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/ReplaceOrder.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.Optional; 4 | 5 | public class ReplaceOrder extends OrderActionBase { 6 | public ReplaceOrder(Optional rationale, Optional imageDescription, String action, Optional message) { 7 | super(rationale, imageDescription, action, message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/EscalateToAgent.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.Optional; 4 | 5 | public class EscalateToAgent extends FunctionCallBase { 6 | public EscalateToAgent(Optional rationale, Optional imageDescription, String action, Optional message) { 7 | super(rationale, imageDescription, action, message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/OrderActionBase.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.Optional; 4 | 5 | public class OrderActionBase extends FunctionCallBase { 6 | public OrderActionBase(Optional rationale, Optional imageDescription, String action, Optional message) { 7 | super(rationale, imageDescription, action, message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/SlackOauthResponseRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import com.openai.entity.SlackOauthModal; 5 | 6 | public interface SlackOauthResponseRepository extends JpaRepository{ 7 | 8 | SlackOauthModal findByTeamIdAndUserId(String teamId, String userId); 9 | 10 | SlackOauthModal findByTeamId(String teamId); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/VideoToAudioConverter.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.io.IOException; 4 | 5 | public class VideoToAudioConverter { 6 | 7 | public static void convertMp4ToMp3(String inputFilePath, String outputFilePath) throws IOException, InterruptedException { 8 | ProcessBuilder processBuilder = new ProcessBuilder( 9 | "ffmpeg", "-i", inputFilePath, "-q:a", "0", "-map", "a", outputFilePath); 10 | 11 | Process process = processBuilder.start(); 12 | process.waitFor(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Channel.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class Channel { 7 | private String id; 8 | private String name; 9 | 10 | public String getId() { 11 | return id; 12 | } 13 | 14 | public void setId(String id) { 15 | this.id = id; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Team.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class Team { 4 | 5 | private String id; 6 | private String name; 7 | 8 | public String getId() { 9 | return id; 10 | } 11 | 12 | public void setId(String id) { 13 | this.id = id; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Team [id=" + id + ", name=" + name + "]"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/SlackUserRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import com.openai.entity.SlackUser; 7 | 8 | public interface SlackUserRepository extends JpaRepository { 9 | 10 | SlackUser findByTeamIdAndUserId(String teamId, String userId); 11 | 12 | List findByTeamIdAndSubscriptionId(String teamId, String subscriptionId); 13 | 14 | List findByUserIdIn(List userIds); 15 | 16 | List findByTeamId(String teamId); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/AccessToken.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class AccessToken { 4 | 5 | 6 | private String token; 7 | private String plan; 8 | 9 | public String getToken() { 10 | return token; 11 | } 12 | 13 | public void setToken(String token) { 14 | this.token = token; 15 | } 16 | 17 | public String getPlan() { 18 | return plan; 19 | } 20 | 21 | public void setPlan(String plan) { 22 | this.plan = plan; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "AccessToken [token=" + token + ", plan=" + plan + "]"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/quotaCompleted.txt: -------------------------------------------------------------------------------- 1 | Dear <@userId>, 2 | 3 | We regret to inform you that you have used up all the quota allocated for your account or your trial period has ended. We hope that you found our service useful during your time with us. 4 | 5 | To continue using our service, we recommend upgrading to one of our premium plans. Our premium plans offer more quota and additional features that can help you get the most out of our service. 6 | 7 | If you have any questions or concerns, please don't hesitate to reach out to our team. We're always happy to help. 8 | 9 | Thank you for choosing Wicebot, and we hope to continue serving you in the future. -------------------------------------------------------------------------------- /src/main/resources/summaryMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "blocks": [ 3 | { 4 | "type": "header", 5 | "text": { 6 | "type": "plain_text", 7 | "text": ":newspaper: Summary :newspaper:", 8 | "emoji": true 9 | } 10 | }, 11 | { 12 | "type": "section", 13 | "text": { 14 | "type": "mrkdwn", 15 | "text": ":rocket: " 16 | } 17 | }, 18 | { 19 | "type": "section", 20 | "text": { 21 | "type": "mrkdwn", 22 | "text": "summarydetails" 23 | } 24 | }, 25 | { 26 | "type": "section", 27 | "text": { 28 | "type": "mrkdwn", 29 | "text": ":airplane_arriving: " 30 | } 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/UserRequestDetailsRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import java.util.Date; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.data.repository.query.Param; 8 | import com.openai.entity.UserRequestDetails; 9 | 10 | public interface UserRequestDetailsRepository extends JpaRepository { 11 | 12 | @Query("select count(*) from UserRequestDetails a where a.requestDate > :requestDate and a.userId = :userId") 13 | int findAllWithRequestDateTimeBefore(@Param("requestDate") Date requestDate, @Param("userId") String userId); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/SlackView.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.Id; 5 | import javax.persistence.Lob; 6 | 7 | @Entity 8 | public class SlackView { 9 | 10 | @Id 11 | private String name; 12 | 13 | @Lob 14 | private String view; 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | public String getView() { 25 | return view; 26 | } 27 | 28 | public void setView(String view) { 29 | this.view = view; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "SlackView [name=" + name + ", view=" + view + "]"; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/openai/OpenAiApplication.java: -------------------------------------------------------------------------------- 1 | package com.openai; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.web.servlet.ServletComponentScan; 7 | import org.springframework.scheduling.annotation.EnableAsync; 8 | 9 | @SpringBootApplication 10 | @ServletComponentScan 11 | @EnableAsync 12 | public class OpenAiApplication implements CommandLineRunner { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(OpenAiApplication.class, args); 16 | } 17 | 18 | @Override 19 | public void run(String... args) throws Exception { 20 | 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/application-local.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 2 | spring.jpa.hibernate.ddl-auto=update 3 | spring.jpa.show-sql=false 4 | spring.jpa.properties.hibernate.format_sql=true 5 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect 6 | spring.datasource.url=jdbc:mysql://localhost:3306/db 7 | spring.datasource.username=root 8 | server.port=8080 9 | 10 | #######Slack Cred 11 | slackAppToken= 12 | slackBotToken= 13 | slackClientId= 14 | slackClientSecret= 15 | 16 | botToken= 17 | openaiToken= 18 | 19 | #############Twitter 20 | twitter.api.key= 21 | twitter.api.secret= 22 | twitter.api.bearerToken= 23 | twitter.api.accesstoken= 24 | twitter.api.token.secret= 25 | twitter.api.token.client= 26 | twitter.api.token.client.secret= -------------------------------------------------------------------------------- /src/main/java/com/openai/repository/TextRequestQueueRepository.java: -------------------------------------------------------------------------------- 1 | package com.openai.repository; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.data.repository.query.Param; 8 | import com.openai.entity.TextRequestQueue; 9 | 10 | public interface TextRequestQueueRepository extends JpaRepository { 11 | 12 | @Query("select count(*) from TextRequestQueue a where a.updatedDate > :updatedDate and a.userId = :userId") 13 | int findAllWithCreationDateTimeBefore(@Param("updatedDate") Date updatedDate, @Param("userId") String userId); 14 | 15 | List findByStatusAndRetryCountGreaterThan(String status, int retryCount); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Files.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class Files { 9 | 10 | private String id; 11 | private String file_id; 12 | private String url_private; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | public void setId(String id) { 18 | this.id = id; 19 | } 20 | public String getFile_id() { 21 | return file_id; 22 | } 23 | public void setFile_id(String file_id) { 24 | this.file_id = file_id; 25 | } 26 | public String getUrl_private() { 27 | return url_private; 28 | } 29 | public void setUrl_private(String url_private) { 30 | this.url_private = url_private; 31 | } 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/openai/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.openai; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | 10 | import com.openai.slack.services.ExceptionNotificationService; 11 | 12 | @ControllerAdvice 13 | public class GlobalExceptionHandler { 14 | 15 | Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); 16 | 17 | @Autowired 18 | ExceptionNotificationService exceptionNotificationService; 19 | 20 | @ExceptionHandler(Exception.class) 21 | public ResponseEntity handleExceptions(Exception e) { 22 | exceptionNotificationService.sendException(e); 23 | return null; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/AsyncExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import java.lang.reflect.Method; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { 12 | 13 | Logger logger = LoggerFactory.getLogger(AsyncExceptionHandler.class); 14 | 15 | @Autowired 16 | ExceptionNotificationService exceptionNotificationService; 17 | 18 | @Override 19 | public void handleUncaughtException(Throwable ex, Method method, Object... params) { 20 | logger.error("Unexpected asynchronous exception at : " + method.getDeclaringClass().getName() + "." 21 | + method.getName(), ex); 22 | exceptionNotificationService.sendAsyncException(ex, method, params); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/resources/postMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "callback_id" : "CommandMessage", 3 | "blocks": [ 4 | { 5 | "type": "section", 6 | "text": { 7 | "type": "mrkdwn", 8 | "text": "messageOutput" 9 | } 10 | }, 11 | { 12 | "type": "actions", 13 | "elements": [ 14 | { 15 | "type": "button", 16 | "action_id": "PostMessageId", 17 | "text": { 18 | "type": "plain_text", 19 | "text": "Post", 20 | "emoji": true 21 | }, 22 | "value": "PostMessage" 23 | } 24 | ] 25 | } 26 | ], 27 | "metadata": { 28 | "event_type": "task_created", 29 | "event_payload": { 30 | "id": "TK-2132", 31 | "summary": "New issue with the display of mobile element", 32 | "description": "An end user has found a problem with the new mobile container for data entry. It was reproduced in the current version of IOS.", 33 | "priority": "HIGH", 34 | "resource_type": "TASK" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Block.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class Block { 9 | public String type; 10 | public String block_id; 11 | public ArrayList elements; 12 | 13 | public String getType() { 14 | return type; 15 | } 16 | 17 | public void setType(String type) { 18 | this.type = type; 19 | } 20 | 21 | public String getBlock_id() { 22 | return block_id; 23 | } 24 | 25 | public void setBlock_id(String block_id) { 26 | this.block_id = block_id; 27 | } 28 | 29 | public ArrayList getElements() { 30 | return elements; 31 | } 32 | 33 | public void setElements(ArrayList elements) { 34 | this.elements = elements; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "Block [type=" + type + ", block_id=" + block_id + ", elements=" + elements + "]"; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Element.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class Element { 9 | 10 | public String type; 11 | public ArrayList elements; 12 | public String user_id; 13 | 14 | public String getType() { 15 | return type; 16 | } 17 | 18 | public void setType(String type) { 19 | this.type = type; 20 | } 21 | 22 | public ArrayList getElements() { 23 | return elements; 24 | } 25 | 26 | public void setElements(ArrayList elements) { 27 | this.elements = elements; 28 | } 29 | 30 | public String getUser_id() { 31 | return user_id; 32 | } 33 | 34 | public void setUser_id(String user_id) { 35 | this.user_id = user_id; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Element [type=" + type + ", elements=" + elements + ", user_id=" + user_id + "]"; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/OrderUtils.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class OrderUtils { 4 | 5 | // Placeholder function to retrieve order details based on the order ID 6 | public static Order getOrderDetails(String orderId) { 7 | return new Order(orderId, "Product X", 100.0, "Delivered", "2024-04-10"); 8 | } 9 | 10 | // Placeholder function to escalate the order to a human agent 11 | public static String escalateToAgent(Order order, String message) { 12 | return "Order " + order.getOrderId() + " has been escalated to an agent with message: `" + message + "`"; 13 | } 14 | 15 | // Placeholder function to process a refund for the order 16 | public static String refundOrder(Order order) { 17 | return "Order " + order.getOrderId() + " has been refunded successfully."; 18 | } 19 | 20 | // Placeholder function to replace the order with a new one 21 | public static String replaceOrder(Order order) { 22 | return "Order " + order.getOrderId() + " has been replaced with a new order."; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/User.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class User { 7 | 8 | private String id; 9 | private String username; 10 | private String name; 11 | private String team_id; 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | public void setId(String id) { 18 | this.id = id; 19 | } 20 | 21 | public String getUsername() { 22 | return username; 23 | } 24 | 25 | public void setUsername(String username) { 26 | this.username = username; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public String getTeam_id() { 38 | return team_id; 39 | } 40 | 41 | public void setTeam_id(String team_id) { 42 | this.team_id = team_id; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "User [id=" + id + ", username=" + username + ", name=" + name + ", team_id=" + team_id + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/resources/welcomeMessage.txt: -------------------------------------------------------------------------------- 1 | Hello <@userId> and welcome to Wicebot! 2 | 3 | I'm a chat bot powered by GPT-3, and I'm here to make your experience on Slack more efficient and productive. As a new user, I'm excited to offer you a 7 day free trial of our services, which includes access to all the premium features of Wicebot. 4 | 5 | With Wicebot, you can benefit from a range of useful features, such as: 6 | 7 | :speech_balloon: . 8 | :briefcase: . 9 | :brain: . 10 | :electric_plug: 11 | :newspaper: The ability to summarize thread conversations, making it easier for you to quickly understand the main points of a long discussion. 12 | 13 | 14 | Thank you for choosing Wicebot, and I hope you enjoy your free trial! -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Container.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class Container { 7 | private String type; 8 | private String message_ts; 9 | private String channel_id; 10 | private String is_ephemeral; 11 | public String getType() { 12 | return type; 13 | } 14 | public void setType(String type) { 15 | this.type = type; 16 | } 17 | public String getMessage_ts() { 18 | return message_ts; 19 | } 20 | public void setMessage_ts(String message_ts) { 21 | this.message_ts = message_ts; 22 | } 23 | public String getChannel_id() { 24 | return channel_id; 25 | } 26 | public void setChannel_id(String channel_id) { 27 | this.channel_id = channel_id; 28 | } 29 | public String getIs_ephemeral() { 30 | return is_ephemeral; 31 | } 32 | public void setIs_ephemeral(String is_ephemeral) { 33 | this.is_ephemeral = is_ephemeral; 34 | } 35 | @Override 36 | public String toString() { 37 | return "Container [type=" + type + ", message_ts=" + message_ts + ", channel_id=" + channel_id 38 | + ", is_ephemeral=" + is_ephemeral + "]"; 39 | } 40 | 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/userwithnoprimeaccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "view_id":"viewId", 3 | "type": "home", 4 | "blocks": [ 5 | { 6 | "type": "header", 7 | "text": { 8 | "type": "plain_text", 9 | "text": "Unleash the power of :bulb: GPT with :robot_face: Wicebot, your ultimate AI companion :speech_balloon:", 10 | "emoji": true 11 | } 12 | }, 13 | { 14 | "type": "divider" 15 | }, 16 | { 17 | "type": "section", 18 | "text": { 19 | "type": "mrkdwn", 20 | "text": "*Welcome to Wicebot!*\nHere are some of our features:" 21 | } 22 | }, 23 | { 24 | "type": "section", 25 | "text": { 26 | "type": "mrkdwn", 27 | "text": ":speech_balloon: Understands and responds to natural language input\n:briefcase: Provides assistance with a variety of tasks\n:brain: Advanced AI capabilities for understanding context and intent\n:electric_plug: Can be integrated with various platforms\n" 28 | } 29 | }, 30 | { 31 | "type": "divider" 32 | }, 33 | { 34 | "type": "section", 35 | "text": { 36 | "type": "mrkdwn", 37 | "text": "*Wicebot in action!*" 38 | } 39 | }, 40 | { 41 | "type": "image", 42 | "title": { 43 | "type": "plain_text", 44 | "text": "Wicebot in action" 45 | }, 46 | "image_url": "https://media.giphy.com/media/3oKIPnAiaMCws8nOsE/giphy.gif", 47 | "alt_text": "Wicebot in action" 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /src/main/resources/userselection.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "UserSelection", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "Wicebot", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "section", 24 | "block_id": "o09a", 25 | "text": { 26 | "type": "mrkdwn", 27 | "text": "Please select/deselect all users who should be licensed to use Wicebot.", 28 | "verbatim": false 29 | } 30 | }, 31 | { 32 | "type": "input", 33 | "block_id": "update_selected_users", 34 | "label": { 35 | "type": "plain_text", 36 | "text": "Select/Deselect users", 37 | "emoji": true 38 | }, 39 | "optional": false, 40 | "dispatch_action": false, 41 | "element": { 42 | "type": "multi_users_select", 43 | "action_id": "AssignedUsers", 44 | "initial_users": ["intialUsersId"], 45 | "placeholder": { 46 | "type": "plain_text", 47 | "text": "Users who will be licensed to use Wicebot", 48 | "emoji": true 49 | }, 50 | "max_selected_items": "totalcountOfLicenses" 51 | } 52 | } 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/SlideData.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class SlideData { 9 | private String title; 10 | private String text; 11 | private String imagePath; 12 | 13 | public SlideData() { 14 | // Default constructor 15 | } 16 | 17 | @JsonCreator 18 | public SlideData( 19 | @JsonProperty("title") String title, 20 | @JsonProperty("text") String text, 21 | @JsonProperty("imagePath") String imagePath 22 | ) { 23 | this.title = title; 24 | this.text = text; 25 | this.imagePath = imagePath; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | public String getText() { 37 | return text; 38 | } 39 | 40 | public void setText(String text) { 41 | this.text = text; 42 | } 43 | 44 | public String getImagePath() { 45 | return imagePath; 46 | } 47 | 48 | public void setImagePath(String imagePath) { 49 | this.imagePath = imagePath; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Action.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class Action { 7 | private String action_id; 8 | private String block_id; 9 | private String value; 10 | private String type; 11 | private String action_ts; 12 | 13 | public String getAction_id() { 14 | return action_id; 15 | } 16 | 17 | public void setAction_id(String action_id) { 18 | this.action_id = action_id; 19 | } 20 | 21 | public String getBlock_id() { 22 | return block_id; 23 | } 24 | 25 | public void setBlock_id(String block_id) { 26 | this.block_id = block_id; 27 | } 28 | 29 | public String getValue() { 30 | return value; 31 | } 32 | 33 | public void setValue(String value) { 34 | this.value = value; 35 | } 36 | 37 | public String getType() { 38 | return type; 39 | } 40 | 41 | public void setType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String getAction_ts() { 46 | return action_ts; 47 | } 48 | 49 | public void setAction_ts(String action_ts) { 50 | this.action_ts = action_ts; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Action [action_id=" + action_id + ", block_id=" + block_id + ", value=" + value + ", type=" + type 56 | + ", action_ts=" + action_ts + "]"; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/openai/controller/HealthCheck.java: -------------------------------------------------------------------------------- 1 | package com.openai.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.fasterxml.jackson.core.JsonProcessingException; 12 | import com.fasterxml.jackson.databind.JsonMappingException; 13 | import com.fasterxml.jackson.databind.ObjectMapper; 14 | import com.openai.eventlistner.EventService; 15 | import com.openai.services.OpenAiMessageCreation; 16 | import com.openai.slack.event.dto.EventPayload; 17 | import com.openai.slack.services.SlackMessageServices; 18 | import com.openai.slack.services.SlackUserService; 19 | import com.slack.api.Slack; 20 | 21 | @RestController 22 | public class HealthCheck { 23 | 24 | Logger logger = LoggerFactory.getLogger(HealthCheck.class); 25 | 26 | @Autowired 27 | SlackUserService slackUserService; 28 | 29 | @Autowired 30 | SlackMessageServices slackMessageService; 31 | 32 | @Autowired 33 | OpenAiMessageCreation openAiMessageCreation; 34 | 35 | @GetMapping(path = "/dhbh1387/healthcheck") 36 | public String healthCheck() { 37 | return "Success"; 38 | } 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/FileTypeChecker.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.io.File; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class FileTypeChecker { 8 | 9 | private static final List IMAGE_EXTENSIONS = Arrays.asList("jpg", "jpeg", "png", "bmp", "gif", "tiff", 10 | "webp"); 11 | private static final List VIDEO_EXTENSIONS = Arrays.asList("mp4", "avi", "mkv", "mov", "wmv", "flv", "webm", 12 | "m4v"); 13 | private static final List AUDIO_EXTENSIONS = Arrays.asList("mp3", "wav", "aac", "flac", "ogg", "m4a"); 14 | 15 | public enum FileType { 16 | IMAGE, VIDEO, AUDIO, UNKNOWN 17 | } 18 | 19 | public static FileType getFileType(String filePath) { 20 | String fileExtension = getFileExtension(filePath).toLowerCase(); 21 | 22 | if (IMAGE_EXTENSIONS.contains(fileExtension)) { 23 | return FileType.IMAGE; 24 | } else if (VIDEO_EXTENSIONS.contains(fileExtension)) { 25 | return FileType.VIDEO; 26 | } else if (AUDIO_EXTENSIONS.contains(fileExtension)) { 27 | return FileType.AUDIO; 28 | } else { 29 | return FileType.UNKNOWN; 30 | } 31 | } 32 | 33 | private static String getFileExtension(String filePath) { 34 | String fileName = new File(filePath).getName(); 35 | int dotIndex = fileName.lastIndexOf('.'); 36 | if (dotIndex > 0 && dotIndex < fileName.length() - 1) { 37 | return fileName.substring(dotIndex + 1); 38 | } 39 | return ""; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/BotProfile.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class BotProfile { 7 | private String id; 8 | private boolean deleted; 9 | private String name; 10 | private int updated; 11 | private String app_id; 12 | private String team_id; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | 18 | public void setId(String id) { 19 | this.id = id; 20 | } 21 | 22 | public boolean isDeleted() { 23 | return deleted; 24 | } 25 | 26 | public void setDeleted(boolean deleted) { 27 | this.deleted = deleted; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public int getUpdated() { 39 | return updated; 40 | } 41 | 42 | public void setUpdated(int updated) { 43 | this.updated = updated; 44 | } 45 | 46 | public String getApp_id() { 47 | return app_id; 48 | } 49 | 50 | public void setApp_id(String app_id) { 51 | this.app_id = app_id; 52 | } 53 | 54 | public String getTeam_id() { 55 | return team_id; 56 | } 57 | 58 | public void setTeam_id(String team_id) { 59 | this.team_id = team_id; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "BotProfile [id=" + id + ", deleted=" + deleted + ", name=" + name + ", updated=" + updated + ", app_id=" 65 | + app_id + ", team_id=" + team_id + "]"; 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/UserRequestDetails.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Temporal; 11 | import javax.persistence.TemporalType; 12 | 13 | @Entity 14 | public class UserRequestDetails { 15 | 16 | @Id 17 | @Column(name = "id") 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | private String requestType; 21 | private String userId; 22 | @Temporal(TemporalType.TIMESTAMP) 23 | private Date requestDate; 24 | 25 | 26 | public UserRequestDetails(String requestType, String userId) { 27 | this.requestDate = new Date(); 28 | this.requestType = requestType; 29 | this.userId = userId; 30 | } 31 | 32 | 33 | 34 | public String getRequestType() { 35 | return requestType; 36 | } 37 | public void setRequestType(String requestType) { 38 | this.requestType = requestType; 39 | } 40 | public String getUserId() { 41 | return userId; 42 | } 43 | public void setUserId(String userId) { 44 | this.userId = userId; 45 | } 46 | public Date getRequestDate() { 47 | return requestDate; 48 | } 49 | public void setRequestDate(Date requestDate) { 50 | this.requestDate = requestDate; 51 | } 52 | @Override 53 | public String toString() { 54 | return "UserRequestDetails [requestType=" + requestType + ", userId=" + userId + ", requestDate=" + requestDate 55 | + "]"; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Authorization.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class Authorization { 7 | public Object enterprise_id; 8 | public String team_id; 9 | public String user_id; 10 | public boolean is_bot; 11 | public boolean is_enterprise_install; 12 | 13 | public Object getEnterprise_id() { 14 | return enterprise_id; 15 | } 16 | 17 | public void setEnterprise_id(Object enterprise_id) { 18 | this.enterprise_id = enterprise_id; 19 | } 20 | 21 | public String getTeam_id() { 22 | return team_id; 23 | } 24 | 25 | public void setTeam_id(String team_id) { 26 | this.team_id = team_id; 27 | } 28 | 29 | public String getUser_id() { 30 | return user_id; 31 | } 32 | 33 | public void setUser_id(String user_id) { 34 | this.user_id = user_id; 35 | } 36 | 37 | public boolean isIs_bot() { 38 | return is_bot; 39 | } 40 | 41 | public void setIs_bot(boolean is_bot) { 42 | this.is_bot = is_bot; 43 | } 44 | 45 | public boolean isIs_enterprise_install() { 46 | return is_enterprise_install; 47 | } 48 | 49 | public void setIs_enterprise_install(boolean is_enterprise_install) { 50 | this.is_enterprise_install = is_enterprise_install; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Authorization [enterprise_id=" + enterprise_id + ", team_id=" + team_id + ", user_id=" + user_id 56 | + ", is_bot=" + is_bot + ", is_enterprise_install=" + is_enterprise_install + "]"; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Order.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class Order { 4 | private String orderId; 5 | private String productName; 6 | private double price; 7 | private String status; 8 | private String deliveryDate; 9 | 10 | // Constructor 11 | public Order(String orderId, String productName, double price, String status, String deliveryDate) { 12 | this.orderId = orderId; 13 | this.productName = productName; 14 | this.price = price; 15 | this.status = status; 16 | this.deliveryDate = deliveryDate; 17 | } 18 | 19 | // Getters and setters 20 | public String getOrderId() { 21 | return orderId; 22 | } 23 | 24 | public void setOrderId(String orderId) { 25 | this.orderId = orderId; 26 | } 27 | 28 | public String getProductName() { 29 | return productName; 30 | } 31 | 32 | public void setProductName(String productName) { 33 | this.productName = productName; 34 | } 35 | 36 | public double getPrice() { 37 | return price; 38 | } 39 | 40 | public void setPrice(double price) { 41 | this.price = price; 42 | } 43 | 44 | public String getStatus() { 45 | return status; 46 | } 47 | 48 | public void setStatus(String status) { 49 | this.status = status; 50 | } 51 | 52 | public String getDeliveryDate() { 53 | return deliveryDate; 54 | } 55 | 56 | public void setDeliveryDate(String deliveryDate) { 57 | this.deliveryDate = deliveryDate; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/openai/services/TwitterService.java: -------------------------------------------------------------------------------- 1 | package com.openai.services; 2 | 3 | import java.net.URI; 4 | 5 | import javax.annotation.PostConstruct; 6 | 7 | import org.apache.http.HttpRequest; 8 | import org.apache.http.HttpResponse; 9 | import org.apache.http.client.HttpClient; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.stereotype.Service; 12 | 13 | import twitter4j.Twitter; 14 | import twitter4j.TwitterException; 15 | import twitter4j.TwitterFactory; 16 | import twitter4j.conf.ConfigurationBuilder; 17 | 18 | @Service 19 | public class TwitterService { 20 | 21 | @Value("${twitter.api.key}") 22 | private String apiKey; 23 | 24 | @Value("${twitter.api.secret}") 25 | private String apiSecret; 26 | 27 | @Value("${twitter.api.bearerToken}") 28 | private String bearerToken; 29 | 30 | @Value("${twitter.api.accesstoken}") 31 | private String accessToken; 32 | 33 | @Value("${twitter.api.token.secret}") 34 | private String accessTokenSecret; 35 | 36 | private Twitter twitter; 37 | 38 | @PostConstruct 39 | public void init() { 40 | ConfigurationBuilder cb = new ConfigurationBuilder(); 41 | cb.setDebugEnabled(true).setOAuthConsumerKey(apiKey).setOAuthConsumerSecret(apiSecret) 42 | .setOAuthAccessToken(accessToken).setOAuthAccessTokenSecret(accessTokenSecret); 43 | TwitterFactory tf = new TwitterFactory(cb.build()); 44 | this.twitter = tf.getInstance(); 45 | } 46 | 47 | public void postTweet(String tweetContent) { 48 | 49 | try { 50 | twitter.updateStatus(tweetContent); 51 | System.out.println("Successfully posted the tweet: " + tweetContent); 52 | } catch (TwitterException e) { 53 | e.printStackTrace(); 54 | System.out.println("Failed to post the tweet."); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.util.Calendar; 4 | import java.util.Date; 5 | import java.util.concurrent.TimeUnit; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class TimeUtils { 10 | Logger logger = LoggerFactory.getLogger(TimeUtils.class); 11 | 12 | public static Date addSevenDays() { 13 | Calendar calendar = Calendar.getInstance(); 14 | calendar.set(Calendar.HOUR_OF_DAY, 0); 15 | calendar.set(Calendar.MINUTE, 0); 16 | calendar.set(Calendar.SECOND, 0); 17 | calendar.set(Calendar.MILLISECOND, 0); 18 | calendar.add(Calendar.DATE, 7); 19 | return calendar.getTime(); 20 | } 21 | 22 | public static Date getNextDateWithOutTime() { 23 | Calendar calendar = Calendar.getInstance(); 24 | calendar.add(Calendar.DATE, 1); 25 | calendar.set(Calendar.HOUR_OF_DAY, 0); 26 | calendar.set(Calendar.MINUTE, 0); 27 | calendar.set(Calendar.SECOND, 0); 28 | calendar.set(Calendar.MILLISECOND, 0); 29 | return calendar.getTime(); 30 | } 31 | 32 | public static String getUnixTimestamp(String input) { 33 | int hours = 2; 34 | try { 35 | hours = Integer.valueOf(input); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | double currentTimeMillies = (double) (System.currentTimeMillis() - TimeUnit.HOURS.toMillis(hours)); 40 | currentTimeMillies = (currentTimeMillies / 1000); 41 | return String.valueOf(String.format("%.6f", currentTimeMillies)); 42 | } 43 | 44 | public static Date getLastDateOfPreviousMonth() { 45 | Calendar aCalendar = Calendar.getInstance(); 46 | // add -1 month to current month 47 | aCalendar.add(Calendar.MONTH, -1); 48 | // set actual maximum date of previous month 49 | aCalendar.set(Calendar.DATE, aCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); 50 | //read it 51 | return aCalendar.getTime(); 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/SlackUseridTeamid.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | public class SlackUseridTeamid implements Serializable { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 1L; 11 | 12 | private String userId; 13 | 14 | private String teamId; 15 | 16 | public SlackUseridTeamid() { 17 | super(); 18 | // TODO Auto-generated constructor stub 19 | } 20 | 21 | public SlackUseridTeamid(String userId, String teamId) { 22 | super(); 23 | this.userId = userId; 24 | this.teamId = teamId; 25 | } 26 | 27 | public String getUserId() { 28 | return userId; 29 | } 30 | 31 | public void setUserId(String userId) { 32 | this.userId = userId; 33 | } 34 | 35 | public String getTeamId() { 36 | return teamId; 37 | } 38 | 39 | public void setTeamId(String teamId) { 40 | this.teamId = teamId; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "SlackUseridTeamid [userId=" + userId + ", teamId=" + teamId + "]"; 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | final int prime = 31; 51 | int result = 1; 52 | result = prime * result + ((teamId == null) ? 0 : teamId.hashCode()); 53 | result = prime * result + ((userId == null) ? 0 : userId.hashCode()); 54 | return result; 55 | } 56 | 57 | @Override 58 | public boolean equals(Object obj) { 59 | if (this == obj) 60 | return true; 61 | if (obj == null) 62 | return false; 63 | if (getClass() != obj.getClass()) 64 | return false; 65 | SlackUseridTeamid other = (SlackUseridTeamid) obj; 66 | if (teamId == null) { 67 | if (other.teamId != null) 68 | return false; 69 | } else if (!teamId.equals(other.teamId)) 70 | return false; 71 | if (userId == null) { 72 | if (other.userId != null) 73 | return false; 74 | } else if (!userId.equals(other.userId)) 75 | return false; 76 | return true; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/ExceptionNotificationService.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.lang.reflect.Method; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.stereotype.Service; 10 | 11 | import com.slack.api.Slack; 12 | import com.slack.api.methods.MethodsClient; 13 | import com.slack.api.methods.response.chat.ChatPostMessageResponse; 14 | 15 | 16 | 17 | @Service 18 | public class ExceptionNotificationService { 19 | 20 | Logger logger = LoggerFactory.getLogger(ExceptionNotificationService.class); 21 | 22 | public void sendException(Exception e) { 23 | StringWriter sw = new StringWriter(); 24 | e.printStackTrace(new PrintWriter(sw)); 25 | String exceptionAsString = sw.toString(); 26 | logger.error(exceptionAsString); 27 | if(exceptionAsString != null) 28 | sendTextMessage("***************************" + exceptionAsString.substring(0,900)); 29 | } 30 | 31 | public void sendAsyncException(Throwable ex, Method method, Object... params) { 32 | StringBuilder sb = new StringBuilder("Exception Caught in Thread - " + Thread.currentThread().getName() + 33 | "\nException message - " + ex.getMessage() 34 | + "\nMethod name - " + method.getName()); 35 | for (Object param : params) { 36 | sb.append("Parameter value - " + param); 37 | } 38 | sendTextMessage(sb.toString()); 39 | } 40 | 41 | public void sendTextMessage(String text) { 42 | try { 43 | MethodsClient methodsClient = Slack.getInstance().methods(); 44 | try { 45 | ChatPostMessageResponse chatPostMessageResponse = methodsClient.chatPostMessage(r -> r.token("") 46 | .channel("").text(text) 47 | ); 48 | } catch (Exception e) { 49 | logger.error("replyMessage throw exception : " + e.toString()); 50 | } 51 | }catch(Exception e) { 52 | logger.info("Exception in sendTextMessage " + e.getMessage()); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/openai/OpenAiConfig.java: -------------------------------------------------------------------------------- 1 | package com.openai; 2 | 3 | import java.time.Duration; 4 | 5 | import javax.security.auth.login.LoginException; 6 | 7 | import org.javacord.api.DiscordApi; 8 | import org.javacord.api.DiscordApiBuilder; 9 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.beans.factory.annotation.Value; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.lang.Nullable; 15 | import org.springframework.scheduling.annotation.AsyncConfigurerSupport; 16 | import org.springframework.scheduling.annotation.EnableAsync; 17 | import org.springframework.web.client.RestTemplate; 18 | 19 | import com.openai.slack.services.AsyncExceptionHandler; 20 | import com.theokanning.openai.service.OpenAiService; 21 | 22 | @Configuration 23 | @EnableAsync 24 | public class OpenAiConfig extends AsyncConfigurerSupport { 25 | 26 | @Autowired 27 | private AsyncExceptionHandler asyncExceptionHandler; 28 | 29 | @Value("${botToken}") 30 | private String botToken; 31 | 32 | @Value("${openaiToken}") 33 | private String openaiToken; 34 | 35 | @Value("${slackBotToken}") 36 | private String slackBotToken; 37 | 38 | @Bean 39 | public DiscordApi javacordclient() throws LoginException { 40 | return new DiscordApiBuilder().setAllIntents().setToken(botToken).login().join(); 41 | } 42 | 43 | @Bean 44 | public OpenAiService openaiClient() throws LoginException { 45 | Duration duration = Duration.ofSeconds(60); 46 | return new OpenAiService(openaiToken, duration); 47 | } 48 | 49 | 50 | @Bean 51 | public RestTemplate restTemplate() { 52 | return new RestTemplate(); 53 | } 54 | 55 | @Override 56 | @Nullable 57 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 58 | return (throwable, method, obj) -> { 59 | asyncExceptionHandler.handleUncaughtException(throwable, method, obj); 60 | }; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/SlackOauthModal.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.Id; 5 | import javax.persistence.IdClass; 6 | 7 | @Entity 8 | @IdClass(SlackUseridTeamid.class) 9 | public class SlackOauthModal { 10 | 11 | @Id 12 | private String teamId; 13 | 14 | @Id 15 | private String userId; 16 | 17 | private String botTokens; 18 | private String botId; 19 | private String scope; 20 | private String appId; 21 | private String tokenType; 22 | private String teamName; 23 | 24 | public String getTeamId() { 25 | return teamId; 26 | } 27 | 28 | public void setTeamId(String teamId) { 29 | this.teamId = teamId; 30 | } 31 | 32 | public String getUserId() { 33 | return userId; 34 | } 35 | 36 | public void setUserId(String userId) { 37 | this.userId = userId; 38 | } 39 | 40 | public String getBotTokens() { 41 | return ""; 42 | } 43 | 44 | public void setBotTokens(String botTokens) { 45 | this.botTokens = botTokens; 46 | } 47 | 48 | public String getBotId() { 49 | return botId; 50 | } 51 | 52 | public void setBotId(String botId) { 53 | this.botId = botId; 54 | } 55 | 56 | public String getScope() { 57 | return scope; 58 | } 59 | 60 | public void setScope(String scope) { 61 | this.scope = scope; 62 | } 63 | 64 | public String getAppId() { 65 | return appId; 66 | } 67 | 68 | public void setAppId(String appId) { 69 | this.appId = appId; 70 | } 71 | 72 | public String getTokenType() { 73 | return tokenType; 74 | } 75 | 76 | public void setTokenType(String tokenType) { 77 | this.tokenType = tokenType; 78 | } 79 | 80 | public String getTeamName() { 81 | return teamName; 82 | } 83 | 84 | public void setTeamName(String teamName) { 85 | this.teamName = teamName; 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "SlackOauthModal [teamId=" + teamId + ", userId=" + userId + ", botTokens=" + botTokens + ", botId=" 91 | + botId + ", scope=" + scope + ", appId=" + appId + ", tokenType=" + tokenType + ", teamName=" 92 | + teamName + "]"; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/FunctionCallBase.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.Optional; 4 | 5 | public abstract class FunctionCallBase { 6 | private Optional rationale; 7 | private Optional imageDescription; 8 | private String action; 9 | private Optional message; 10 | 11 | public FunctionCallBase(Optional rationale, Optional imageDescription, String action, Optional message) { 12 | this.rationale = rationale; 13 | this.imageDescription = imageDescription; 14 | this.action = action; 15 | this.message = message; 16 | } 17 | 18 | public String call(String orderId) { 19 | Order order = OrderUtils.getOrderDetails(orderId); 20 | switch (action) { 21 | case "escalate_to_agent": 22 | return OrderUtils.escalateToAgent(order, message.orElse("")); 23 | case "replace_order": 24 | return OrderUtils.replaceOrder(order); 25 | case "refund_order": 26 | return OrderUtils.refundOrder(order); 27 | default: 28 | throw new IllegalArgumentException("Invalid action: " + action); 29 | } 30 | } 31 | 32 | // Getters and setters 33 | public Optional getRationale() { 34 | return rationale; 35 | } 36 | 37 | public void setRationale(Optional rationale) { 38 | this.rationale = rationale; 39 | } 40 | 41 | public Optional getImageDescription() { 42 | return imageDescription; 43 | } 44 | 45 | public void setImageDescription(Optional imageDescription) { 46 | this.imageDescription = imageDescription; 47 | } 48 | 49 | public String getAction() { 50 | return action; 51 | } 52 | 53 | public void setAction(String action) { 54 | this.action = action; 55 | } 56 | 57 | public Optional getMessage() { 58 | return message; 59 | } 60 | 61 | public void setMessage(Optional message) { 62 | this.message = message; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/SlackOauthService.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.http.HttpEntity; 8 | import org.springframework.http.HttpHeaders; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.util.LinkedMultiValueMap; 12 | import org.springframework.util.MultiValueMap; 13 | import org.springframework.web.client.RestTemplate; 14 | import com.openai.entity.SlackOauthModal; 15 | import com.openai.repository.SlackOauthResponseRepository; 16 | import com.openai.slack.event.dto.SlackOAuthResponse; 17 | import com.openai.utils.SlackDTOConvertor; 18 | 19 | @Service 20 | public class SlackOauthService { 21 | 22 | Logger logger = LoggerFactory.getLogger(SlackOauthService.class); 23 | 24 | @Autowired 25 | RestTemplate restTemplate; 26 | 27 | @Value("${slackClientId}") 28 | private String slackClientId; 29 | 30 | @Value("${slackClientSecret}") 31 | private String slackClientSecret; 32 | 33 | @Autowired 34 | SlackOauthResponseRepository oauthResponseRepository; 35 | 36 | public String saveUserAccessToken(String code) { 37 | logger.info("saveUserAccessToken start: code {}" , code); 38 | String url = "https://slack.com/api/oauth.v2.access"; 39 | MultiValueMap body = new LinkedMultiValueMap<>(); 40 | body.add("code", code); 41 | body.add("client_id", slackClientId); 42 | body.add("client_secret", slackClientSecret); 43 | HttpHeaders headers = new HttpHeaders(); 44 | headers.setContentType(MediaType.MULTIPART_FORM_DATA); 45 | HttpEntity> requestEntity = new HttpEntity<>(body, headers); 46 | SlackOAuthResponse response = restTemplate.postForObject(url, requestEntity, SlackOAuthResponse.class); 47 | SlackOauthModal slackUser = SlackDTOConvertor.convertSlackOauthResponseToSlackUser(response); 48 | oauthResponseRepository.save(slackUser); 49 | logger.info("saveUserAccessToken end: slackUser {}" , slackUser.toString()); 50 | return "https://app.slack.com/client/"+ slackUser.getTeamId() + "/" + slackUser.getAppId(); 51 | } 52 | 53 | public SlackOauthModal getUserAccessToken(String teamId) { 54 | logger.info("getUserAccessToken start: teamId {}" , teamId); 55 | SlackOauthModal slackOauth = oauthResponseRepository.findByTeamId(teamId); 56 | logger.info("getUserAccessToken end"); 57 | return slackOauth; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/SlackOAuthResponse.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | public class SlackOAuthResponse { 4 | 5 | private boolean ok; 6 | private String app_id; 7 | private AuthedUser authed_user; 8 | private String scope; 9 | private String token_type; 10 | private String access_token; 11 | private String bot_user_id; 12 | private Team team; 13 | private Object enterprise; 14 | private boolean is_enterprise_install; 15 | 16 | public boolean isOk() { 17 | return ok; 18 | } 19 | 20 | public void setOk(boolean ok) { 21 | this.ok = ok; 22 | } 23 | 24 | public String getApp_id() { 25 | return app_id; 26 | } 27 | 28 | public void setApp_id(String app_id) { 29 | this.app_id = app_id; 30 | } 31 | 32 | public AuthedUser getAuthed_user() { 33 | return authed_user; 34 | } 35 | 36 | public void setAuthed_user(AuthedUser authed_user) { 37 | this.authed_user = authed_user; 38 | } 39 | 40 | public String getScope() { 41 | return scope; 42 | } 43 | 44 | public void setScope(String scope) { 45 | this.scope = scope; 46 | } 47 | 48 | public String getToken_type() { 49 | return token_type; 50 | } 51 | 52 | public void setToken_type(String token_type) { 53 | this.token_type = token_type; 54 | } 55 | 56 | public String getAccess_token() { 57 | return access_token; 58 | } 59 | 60 | public void setAccess_token(String access_token) { 61 | this.access_token = access_token; 62 | } 63 | 64 | public String getBot_user_id() { 65 | return bot_user_id; 66 | } 67 | 68 | public void setBot_user_id(String bot_user_id) { 69 | this.bot_user_id = bot_user_id; 70 | } 71 | 72 | public Team getTeam() { 73 | return team; 74 | } 75 | 76 | public void setTeam(Team team) { 77 | this.team = team; 78 | } 79 | 80 | public Object getEnterprise() { 81 | return enterprise; 82 | } 83 | 84 | public void setEnterprise(Object enterprise) { 85 | this.enterprise = enterprise; 86 | } 87 | 88 | public boolean isIs_enterprise_install() { 89 | return is_enterprise_install; 90 | } 91 | 92 | public void setIs_enterprise_install(boolean is_enterprise_install) { 93 | this.is_enterprise_install = is_enterprise_install; 94 | } 95 | 96 | @Override 97 | public String toString() { 98 | return "SlackOAuthResponse [ok=" + ok + ", app_id=" + app_id + ", authed_user=" + authed_user + ", scope=" 99 | + scope + ", token_type=" + token_type + ", access_token=" + access_token + ", bot_user_id=" 100 | + bot_user_id + ", team=" + team + ", enterprise=" + enterprise + ", is_enterprise_install=" 101 | + is_enterprise_install + "]"; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/resources/customerservice.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "CustomerService", 6 | "submit": { 7 | "type": "plain_text", 8 | "text": "Submit", 9 | "emoji": true 10 | }, 11 | "close": { 12 | "type": "plain_text", 13 | "text": "Cancel", 14 | "emoji": true 15 | }, 16 | "title": { 17 | "type": "plain_text", 18 | "text": "Wicebot Customer Service", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "section", 24 | "text": { 25 | "type": "plain_text", 26 | "text": ":wave: Hello! Please provide details below to reach out to our customer service.", 27 | "emoji": true 28 | } 29 | }, 30 | { 31 | "type": "divider" 32 | }, 33 | { 34 | "type": "section", 35 | "block_id": "uploadInstructions", 36 | "text": { 37 | "type": "mrkdwn", 38 | "text": "*Upload an image:* Please upload your image directly in this Slack channel and provide the URL of the uploaded image below." 39 | } 40 | }, 41 | { 42 | "type": "input", 43 | "block_id": "imageUrl", 44 | "label": { 45 | "type": "plain_text", 46 | "text": "Image URL", 47 | "emoji": true 48 | }, 49 | "element": { 50 | "type": "plain_text_input", 51 | "action_id": "image_url_value", 52 | "placeholder": { 53 | "type": "plain_text", 54 | "text": "https://example.com/image.png" 55 | } 56 | } 57 | }, 58 | { 59 | "type": "input", 60 | "block_id": "userReason", 61 | "label": { 62 | "type": "plain_text", 63 | "text": "Reason for reaching out", 64 | "emoji": true 65 | }, 66 | "element": { 67 | "type": "plain_text_input", 68 | "action_id": "reason_value", 69 | "multiline": true 70 | } 71 | }, 72 | { 73 | "type": "input", 74 | "block_id": "userEmail", 75 | "element": { 76 | "type": "plain_text_input", 77 | "action_id": "email_value" 78 | }, 79 | "label": { 80 | "type": "plain_text", 81 | "text": "Your Email", 82 | "emoji": true 83 | } 84 | }, 85 | { 86 | "block_id": "channel_id", 87 | "type": "input", 88 | "optional": false, 89 | "label": { 90 | "type": "plain_text", 91 | "text": "Select a channel to post the result on" 92 | }, 93 | "element": { 94 | "action_id": "channel_id", 95 | "type": "conversations_select", 96 | "response_url_enabled": true, 97 | "filter": { 98 | "include": [ 99 | "public", 100 | "im" 101 | ], 102 | "exclude_bot_users": true, 103 | "exclude_external_shared_channels": true 104 | } 105 | } 106 | } 107 | ] 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/resources/feedbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "Feedback", 6 | "submit": { 7 | "type": "plain_text", 8 | "text": "Submit", 9 | "emoji": true 10 | }, 11 | "close": { 12 | "type": "plain_text", 13 | "text": "Cancel", 14 | "emoji": true 15 | }, 16 | "title": { 17 | "type": "plain_text", 18 | "text": "Wicebot", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "section", 24 | "text": { 25 | "type": "plain_text", 26 | "text": ":wave: Hey Pal \n\nWicebot love to hear your thoughts and feedback on your experience!", 27 | "emoji": true 28 | } 29 | }, 30 | { 31 | "type": "divider" 32 | }, 33 | { 34 | "type": "input", 35 | "block_id": "userRating", 36 | "label": { 37 | "type": "plain_text", 38 | "text": "Wicebot help you out with tedious task", 39 | "emoji": true 40 | }, 41 | "element": { 42 | "type": "radio_buttons", 43 | "action_id": "lang_value", 44 | "options": [ 45 | { 46 | "text": { 47 | "type": "plain_text", 48 | "text": "Strongly agree", 49 | "emoji": true 50 | }, 51 | "value": "1" 52 | }, 53 | { 54 | "text": { 55 | "type": "plain_text", 56 | "text": "Agree", 57 | "emoji": true 58 | }, 59 | "value": "2" 60 | }, 61 | { 62 | "text": { 63 | "type": "plain_text", 64 | "text": "Neither agree nor disagree", 65 | "emoji": true 66 | }, 67 | "value": "3" 68 | }, 69 | { 70 | "text": { 71 | "type": "plain_text", 72 | "text": "Disagree", 73 | "emoji": true 74 | }, 75 | "value": "4" 76 | }, 77 | { 78 | "text": { 79 | "type": "plain_text", 80 | "text": "Strongly disagree", 81 | "emoji": true 82 | }, 83 | "value": "5" 84 | } 85 | ] 86 | } 87 | }, 88 | { 89 | "type": "input", 90 | "block_id": "userFeedback", 91 | "label": { 92 | "type": "plain_text", 93 | "text": "Anything else you want to tell us?", 94 | "emoji": true 95 | }, 96 | "element": { 97 | "type": "plain_text_input", 98 | "action_id": "lang_value", 99 | "multiline": true 100 | }, 101 | "optional": true 102 | }, 103 | { 104 | "type": "input", 105 | "block_id": "userEmail", 106 | "element": { 107 | "type": "email_text_input", 108 | "action_id": "lang_value" 109 | }, 110 | "label": { 111 | "type": "plain_text", 112 | "text": "Label", 113 | "emoji": true 114 | }, 115 | "optional": true 116 | } 117 | ] 118 | } 119 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/Constants.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class Constants { 8 | 9 | public static final String FREE_PLAN = "Free"; 10 | public static final String BASIC_PLAN = "Basic"; 11 | public static final String PROFESSIONAL_PLAN = "Professional"; 12 | public static final String ENTERPRISE_PLAN = "Enterprise"; 13 | public static final String UNLIMITED_PLAN = "Unlimited"; 14 | public static final String ELABORATE_ID = "ElaborateMessage"; 15 | public static final String SUMMARIZE_ID = "SummarizeAction"; 16 | public static final String IMAGEVARIATION_ID = "ImageVariation"; 17 | public static final String CUSTOMERSERVICE_ID = "CustomerService"; 18 | public static final String TTS = "Text2Speech"; 19 | public static final String STT = "Speech2Text"; 20 | public static final String SENTIMENT = "Sentiment"; 21 | public static final String ELABORATE = "Elaborate"; 22 | public static final String SUMMARIZE = "Summarize"; 23 | public static final String CONVERSATION = "Conversation"; 24 | public static final String MENTION = "Mention"; 25 | public static final String ELABORATE_COMMAND = "/elaborate"; 26 | public static final String SUMMARIZE_COMMAND = "/summarize"; 27 | public static final String TEXT2IMG = "/imagine"; 28 | public static final String TRANSLATE_CALLBACKID = "translate_code"; 29 | public static final String RAPIDCODE_CALLBACKID = "rapid_coding"; 30 | public static final String LANG_TRANSLATE_CALLBACKID = "LangToTranslate"; 31 | public static final String TRANSLATE_VIEW = "codetoTranslate"; 32 | public static final String CODETOWRITE_VIEW = "codetoWrite"; 33 | public static final String IN_PROGRESS = "IN_PROGRESS"; 34 | public static final String COMPLETED = "COMPLETED"; 35 | public static final String ERROR = "ERROR"; 36 | public static final String TRANSLATECODE = "TransLateCode"; 37 | public static final String EXCEPTION = "EXCEPTION"; 38 | public static final String FEEDBACK = "feedbackView"; 39 | public static final String WRITECODE = "WriteCode"; 40 | public static final String Summriser_Assistant_ID = ""; 41 | public static final String Sentiment_Assistant_ID = ""; 42 | public static final String Coder_Assistant_ID = ""; 43 | public static final String Translator_Assistant_ID = ""; 44 | public static final String Mention_Assistant_ID = ""; 45 | public static final String Laptop_Check_Assistant_ID = ""; 46 | public static final String Prompt_Assistant_ID = ""; 47 | public static final String Live_Search_Assistant_ID = ""; 48 | public static final String Live_Stock_Analysis_ID = ""; 49 | public static final String Live_Stock_Sentiment_ID = ""; 50 | public static final String WELCOMEMESSAGE = "welcomeMessage"; 51 | public static final String QUTACOMPLETEDMESSAGE = "quotaCompleted"; 52 | public static List STOP_SEQUENCE = new ArrayList( 53 | Arrays.asList(":stop:")); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/openai/eventlistner/EventService.java: -------------------------------------------------------------------------------- 1 | package com.openai.eventlistner; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.javacord.api.DiscordApi; 8 | import org.javacord.api.entity.channel.TextChannel; 9 | import org.javacord.api.entity.message.Message; 10 | import org.javacord.api.entity.message.MessageSet; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | 16 | import com.openai.services.OpenAiMessageCreation; 17 | import com.openai.slack.services.SlackMessageServices; 18 | import com.openai.slack.services.SlackUserService; 19 | import com.openai.slack.services.ViewUpdateService; 20 | import com.theokanning.openai.completion.CompletionChoice; 21 | import com.theokanning.openai.completion.CompletionRequest; 22 | 23 | @Service 24 | public class EventService { 25 | 26 | Logger logger = LoggerFactory.getLogger(EventService.class); 27 | 28 | @Autowired 29 | DiscordApi discordApi; 30 | 31 | @Autowired 32 | ViewUpdateService viewUpdateService; 33 | 34 | @Autowired 35 | SlackUserService slackUserService; 36 | 37 | @Autowired 38 | OpenAiMessageCreation openAiMessageCreation; 39 | 40 | @Autowired 41 | SlackMessageServices slackMessageServices; 42 | 43 | 44 | String mood = "The following is a conversation with an AI Cognitron. Cognitron is helpful, creative, clever, and very friendly.\n\nHuman: Hello, who are you?\nCognitron: I am an Cognitron created by OpenAI. How can I help you today?\nHuman: "; 45 | 46 | public void registerEvents() throws Exception { 47 | 48 | discordApi.addMessageCreateListener(event -> { 49 | TextChannel channel = null; 50 | List result = null; 51 | if (!event.getMessage().getUserAuthor().get().isBot()) { 52 | try { 53 | String text = event.getMessageContent(); 54 | channel = event.getChannel(); 55 | MessageSet messages = channel.getMessages(1000).get(); 56 | Map map = new HashMap<>(); 57 | for (Message message : messages) { 58 | if (message.getUserAuthor().get().isBot()) { 59 | map.put("AI assistant:", message.getContent()); 60 | } else { 61 | map.put("Human:", message.getContent()); 62 | } 63 | } 64 | String userId = event.getMessage().getAuthor().getIdAsString(); 65 | CompletionRequest completionRequest = CompletionRequest.builder() 66 | .prompt(mood + "\n\n" + map.toString()).temperature(0.3).maxTokens(500).topP(1.0) 67 | .model("text-davinci-003").echo(true).user(userId).build(); 68 | // result = openAiService.createCompletion(completionRequest).getChoices(); 69 | } catch (Exception e) { 70 | System.out.println("Ho"); 71 | } finally { 72 | String output = result.get(result.size() - 1).getText(); 73 | output = output.substring(output.lastIndexOf("}") + 1, output.length()).trim(); 74 | channel.sendMessage(output); 75 | } 76 | } 77 | }); 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/OpenAiModal.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.Id; 9 | 10 | import com.openai.utils.Constants; 11 | 12 | @Entity 13 | public class OpenAiModal { 14 | 15 | @Id 16 | String command; 17 | String modal; 18 | String prompt; 19 | String postFix; 20 | double temperature; 21 | int max_tokens; 22 | double top_p; 23 | double frequency_penalty; 24 | double presence_penalty; 25 | String stopSequence; 26 | 27 | public String getCommand() { 28 | return command; 29 | } 30 | 31 | public void setCommand(String command) { 32 | this.command = command; 33 | } 34 | 35 | public String getModal() { 36 | return modal; 37 | } 38 | 39 | public void setModal(String modal) { 40 | this.modal = modal; 41 | } 42 | 43 | public String getPrompt() { 44 | return prompt; 45 | } 46 | 47 | public void setPrompt(String prompt) { 48 | this.prompt = prompt; 49 | } 50 | 51 | public double getTemperature() { 52 | return temperature; 53 | } 54 | 55 | public void setTemperature(double d) { 56 | this.temperature = d; 57 | } 58 | 59 | public int getMax_tokens() { 60 | return max_tokens; 61 | } 62 | 63 | public void setMax_tokens(int max_tokens) { 64 | this.max_tokens = max_tokens; 65 | } 66 | 67 | public double getTop_p() { 68 | return top_p; 69 | } 70 | 71 | public double getFrequency_penalty() { 72 | return frequency_penalty; 73 | } 74 | 75 | public double getPresence_penalty() { 76 | return presence_penalty; 77 | } 78 | 79 | public String getPostFix() { 80 | return postFix; 81 | } 82 | 83 | public void setPostFix(String postFix) { 84 | this.postFix = postFix; 85 | } 86 | 87 | public void setTop_p(double top_p) { 88 | this.top_p = top_p; 89 | } 90 | 91 | public void setFrequency_penalty(double frequency_penalty) { 92 | this.frequency_penalty = frequency_penalty; 93 | } 94 | 95 | public void setPresence_penalty(double presence_penalty) { 96 | this.presence_penalty = presence_penalty; 97 | } 98 | 99 | public String getStopSequence() { 100 | return stopSequence; 101 | } 102 | 103 | public void setStopSequence(String stopSequence) { 104 | this.stopSequence = stopSequence; 105 | } 106 | 107 | public List getListOfStopSequence() { 108 | return this.stopSequence == null || this.stopSequence.isEmpty() ? Constants.STOP_SEQUENCE 109 | : new ArrayList<>(Arrays.asList(this.stopSequence.replace("[", "").replace("]", "").split(","))); 110 | } 111 | 112 | @Override 113 | public String toString() { 114 | return "OpenAiModal [command=" + command + ", modal=" + modal + ", prompt=" + prompt + ", postFix=" + postFix 115 | + ", temperature=" + temperature + ", max_tokens=" + max_tokens + ", top_p=" + top_p 116 | + ", frequency_penalty=" + frequency_penalty + ", presence_penalty=" + presence_penalty 117 | + ", stopSequence=" + stopSequence + "]"; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/SlackDTOConvertor.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.util.Date; 4 | 5 | import com.openai.entity.SlackOauthModal; 6 | import com.openai.entity.TextRequestQueue; 7 | import com.openai.slack.event.dto.SlackOAuthResponse; 8 | import com.theokanning.openai.completion.CompletionRequest; 9 | 10 | public class SlackDTOConvertor { 11 | 12 | public static SlackOauthModal convertSlackOauthResponseToSlackUser(SlackOAuthResponse oAuthResponse) { 13 | SlackOauthModal slackUser = new SlackOauthModal(); 14 | slackUser.setAppId(oAuthResponse.getApp_id()); 15 | slackUser.setUserId(oAuthResponse.getAuthed_user().getId()); 16 | slackUser.setScope(oAuthResponse.getScope()); 17 | slackUser.setTokenType(oAuthResponse.getToken_type()); 18 | slackUser.setBotTokens(oAuthResponse.getAccess_token()); 19 | slackUser.setBotId(oAuthResponse.getBot_user_id()); 20 | slackUser.setTeamId(oAuthResponse.getTeam().getId()); 21 | slackUser.setTeamName(oAuthResponse.getTeam().getName()); 22 | return slackUser; 23 | } 24 | 25 | public static TextRequestQueue completionRequestToTextRequestQueue(String teamId, String userId, String channelId, 26 | String status, int retryCount, String requestType, String lastStop, CompletionRequest completionRequest, Date createdDate, String input, String token) { 27 | TextRequestQueue textRequestQueue = new TextRequestQueue(); 28 | textRequestQueue.setChannelId(channelId); 29 | textRequestQueue.setCreatedDate(createdDate); 30 | textRequestQueue.setLastStop(lastStop); 31 | textRequestQueue.setRetryCount(retryCount); 32 | textRequestQueue.setStatus(status); 33 | textRequestQueue.setRequestType(requestType); 34 | textRequestQueue.setTeamId(teamId); 35 | textRequestQueue.setUpdatedDate(createdDate); 36 | textRequestQueue.setUserId(userId); 37 | textRequestQueue.setModel(completionRequest.getModel()); 38 | textRequestQueue.setMaxTokens(completionRequest.getMaxTokens()); 39 | textRequestQueue.setFrequencyPenalty(completionRequest.getFrequencyPenalty()); 40 | textRequestQueue.setPresencePenalty(completionRequest.getPresencePenalty()); 41 | textRequestQueue.setPrompt(completionRequest.getPrompt()); 42 | textRequestQueue.setStop(completionRequest.getStop().toString()); 43 | textRequestQueue.setTemperature(completionRequest.getTemperature()); 44 | textRequestQueue.setTopP(completionRequest.getTopP()); 45 | textRequestQueue.setInput(input); 46 | return textRequestQueue; 47 | } 48 | 49 | public static CompletionRequest textRequestQueueToCompletionRequest(TextRequestQueue textRequestQueue) { 50 | CompletionRequest completionRequest = CompletionRequest.builder().prompt(textRequestQueue.getPrompt()) 51 | .maxTokens(textRequestQueue.getMaxTokens()) 52 | .frequencyPenalty(textRequestQueue.getFrequencyPenalty()) 53 | .presencePenalty(textRequestQueue.getPresencePenalty()) 54 | .model(textRequestQueue.getModel()) 55 | .stop(SlackUtils.stringToList(textRequestQueue.getStop())) 56 | .temperature(textRequestQueue.getTemperature()) 57 | .topP(textRequestQueue.getTopP()) 58 | .build(); 59 | return completionRequest; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/SlackUser.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Id; 8 | import javax.persistence.IdClass; 9 | import javax.persistence.Temporal; 10 | import javax.persistence.TemporalType; 11 | 12 | @Entity 13 | @IdClass(SlackUseridTeamid.class) 14 | public class SlackUser { 15 | 16 | @Id 17 | private String teamId; 18 | 19 | @Id 20 | private String userId; 21 | private String subscriptionId; 22 | private String plan; 23 | private boolean isPrimary; 24 | private int count; 25 | private String dmChannelId; 26 | 27 | @Temporal(TemporalType.TIMESTAMP) 28 | @Column(name = "createdDate", columnDefinition = "DATETIME") 29 | private Date createdDate; 30 | 31 | @Temporal(TemporalType.TIMESTAMP) 32 | @Column(name = "validTill", columnDefinition = "DATETIME") 33 | private Date validTill; 34 | 35 | @Temporal(TemporalType.TIMESTAMP) 36 | @Column(name = "updatedDate", columnDefinition = "DATETIME") 37 | private Date updatedDate; 38 | 39 | public String getTeamId() { 40 | return teamId; 41 | } 42 | 43 | public void setTeamId(String teamId) { 44 | this.teamId = teamId; 45 | } 46 | 47 | public String getUserId() { 48 | return userId; 49 | } 50 | 51 | public void setUserId(String userId) { 52 | this.userId = userId; 53 | } 54 | 55 | public String getSubscriptionId() { 56 | return subscriptionId; 57 | } 58 | 59 | public void setSubscriptionId(String subscriptionId) { 60 | this.subscriptionId = subscriptionId; 61 | } 62 | 63 | public boolean isPrimary() { 64 | return isPrimary; 65 | } 66 | 67 | public void setPrimary(boolean isPrimary) { 68 | this.isPrimary = isPrimary; 69 | } 70 | 71 | public int getCount() { 72 | return count; 73 | } 74 | 75 | public void setCount(int count) { 76 | this.count = count; 77 | } 78 | 79 | public Date getCreatedDate() { 80 | return createdDate; 81 | } 82 | 83 | public void setCreatedDate(Date createdDate) { 84 | this.createdDate = createdDate; 85 | } 86 | 87 | public Date getValidTill() { 88 | return validTill; 89 | } 90 | 91 | public void setValidTill(Date validTill) { 92 | this.validTill = validTill; 93 | } 94 | 95 | public Date getUpdatedDate() { 96 | return updatedDate; 97 | } 98 | 99 | public void setUpdatedDate(Date updatedDate) { 100 | this.updatedDate = updatedDate; 101 | } 102 | 103 | public String getPlan() { 104 | return plan; 105 | } 106 | 107 | public void setPlan(String plan) { 108 | this.plan = plan; 109 | } 110 | 111 | public String getDmChannelId() { 112 | return dmChannelId; 113 | } 114 | 115 | public void setDmChannelId(String dmChannelId) { 116 | this.dmChannelId = dmChannelId; 117 | } 118 | 119 | @Override 120 | public String toString() { 121 | return "SlackUser [teamId=" + teamId + ", userId=" + userId + ", subscriptionId=" + subscriptionId + ", plan=" 122 | + plan + ", isPrimary=" + isPrimary + ", count=" + count + ", dmChannelId=" + dmChannelId 123 | + ", createdDate=" + createdDate + ", validTill=" + validTill + ", updatedDate=" + updatedDate + "]"; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/openai/services/CustomeOpenAIClient.java: -------------------------------------------------------------------------------- 1 | package com.openai.services; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.fasterxml.jackson.databind.JsonNode; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | import com.google.api.client.http.GenericUrl; 13 | import com.google.api.client.http.HttpRequest; 14 | import com.google.api.client.http.HttpRequestFactory; 15 | import com.google.api.client.http.HttpResponse; 16 | import com.google.api.client.http.javanet.NetHttpTransport; 17 | import com.google.api.client.http.json.JsonHttpContent; 18 | import com.google.api.client.json.JsonFactory; 19 | import com.google.api.client.json.jackson2.JacksonFactory; 20 | 21 | @SuppressWarnings("deprecation") 22 | @Service 23 | public class CustomeOpenAIClient { 24 | 25 | @Value("${openaiToken}") 26 | private String openaiToken; 27 | 28 | @SuppressWarnings("serial") 29 | public String processRequest(String prompt, String input, String fileUrl) { 30 | String apiKey = openaiToken;// Replace with your actual OpenAI API key 31 | String endpoint = "https://api.openai.com/v1/chat/completions"; 32 | String result = ""; 33 | // Construct the JSON payload 34 | Map requestData = new HashMap<>(); 35 | requestData.put("model", "gpt-4o"); 36 | 37 | Map systemMessage = new HashMap<>(); 38 | systemMessage.put("role", "system"); 39 | systemMessage.put("content", new Object[] { new HashMap() { 40 | { 41 | put("type", "text"); 42 | put("text", prompt); 43 | } 44 | } }); 45 | 46 | Map userMessage = new HashMap<>(); 47 | userMessage.put("role", "user"); 48 | if (fileUrl != null && !fileUrl.isEmpty()) { 49 | userMessage.put("content", new Object[] { new HashMap() { 50 | { 51 | put("type", "image_url"); 52 | put("image_url", new HashMap() { 53 | { 54 | put("url", fileUrl); 55 | } 56 | }); 57 | } 58 | } }); 59 | } 60 | 61 | if (input != null && !input.isEmpty()) { 62 | userMessage.put("content", new Object[] { new HashMap() { 63 | { 64 | put("type", "text"); 65 | put("text", input); 66 | } 67 | } }); 68 | } 69 | 70 | requestData.put("messages", new Object[] { systemMessage, userMessage }); 71 | requestData.put("temperature", 1); 72 | requestData.put("max_tokens", 256); 73 | requestData.put("top_p", 1); 74 | requestData.put("frequency_penalty", 0); 75 | requestData.put("presence_penalty", 0); 76 | 77 | @SuppressWarnings("deprecation") 78 | JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); 79 | HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory(); 80 | 81 | try { 82 | HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(endpoint), 83 | new JsonHttpContent(jsonFactory, requestData)); 84 | request.getHeaders().setContentType("application/json"); 85 | request.getHeaders().setAuthorization("Bearer " + apiKey); 86 | 87 | HttpResponse response = request.execute(); 88 | String responseBody = response.parseAsString(); 89 | 90 | // Parse the response and extract the content 91 | ObjectMapper objectMapper = new ObjectMapper(); 92 | JsonNode rootNode = objectMapper.readTree(responseBody); 93 | result = rootNode.path("choices").path(0).path("message").path("content").asText(); 94 | } catch (IOException e) { 95 | e.printStackTrace(); 96 | } 97 | 98 | return result; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/resources/moodselection.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "MoodSelection", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "Mood Selector", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "section", 24 | "text": { 25 | "type": "mrkdwn", 26 | "text": ":smiley: *Select Your Mood* :smiley:" 27 | } 28 | }, 29 | { 30 | "type": "actions", 31 | "elements": [ 32 | { 33 | "type": "button", 34 | "text": { 35 | "type": "plain_text", 36 | "text": ":grinning: Happy", 37 | "emoji": true 38 | }, 39 | "value": "happy", 40 | "action_id": "happy_button" 41 | }, 42 | { 43 | "type": "button", 44 | "text": { 45 | "type": "plain_text", 46 | "text": ":disappointed: Sad", 47 | "emoji": true 48 | }, 49 | "value": "sad", 50 | "action_id": "sad_button" 51 | }, 52 | { 53 | "type": "button", 54 | "text": { 55 | "type": "plain_text", 56 | "text": ":star-struck: Excited", 57 | "emoji": true 58 | }, 59 | "value": "excited", 60 | "action_id": "excited_button" 61 | }, 62 | { 63 | "type": "button", 64 | "text": { 65 | "type": "plain_text", 66 | "text": ":worried: Anxious", 67 | "emoji": true 68 | }, 69 | "value": "anxious", 70 | "action_id": "anxious_button" 71 | }, 72 | { 73 | "type": "button", 74 | "text": { 75 | "type": "plain_text", 76 | "text": ":neutral_face: Neutral", 77 | "emoji": true 78 | }, 79 | "value": "neutral", 80 | "action_id": "neutral_button" 81 | }, 82 | { 83 | "type": "button", 84 | "text": { 85 | "type": "plain_text", 86 | "text": ":angry: Angry", 87 | "emoji": true 88 | }, 89 | "value": "angry", 90 | "action_id": "angry_button" 91 | }, 92 | { 93 | "type": "button", 94 | "text": { 95 | "type": "plain_text", 96 | "text": ":sleeping: Sleepy", 97 | "emoji": true 98 | }, 99 | "value": "sleepy", 100 | "action_id": "sleepy_button" 101 | }, 102 | { 103 | "type": "button", 104 | "text": { 105 | "type": "plain_text", 106 | "text": ":sunglasses: Cool", 107 | "emoji": true 108 | }, 109 | "value": "cool", 110 | "action_id": "cool_button" 111 | }, 112 | { 113 | "type": "button", 114 | "text": { 115 | "type": "plain_text", 116 | "text": ":cry: Crying", 117 | "emoji": true 118 | }, 119 | "value": "crying", 120 | "action_id": "crying_button" 121 | } 122 | ] 123 | } 124 | ] 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/resources/SectorSelection.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "industry_select_modal", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "Wicebot", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "input", 24 | "block_id": "industry_select_block", 25 | "label": { 26 | "type": "plain_text", 27 | "text": "Select Your Field", 28 | "emoji": true 29 | }, 30 | "element": { 31 | "type": "static_select", 32 | "action_id": "industry_select_action", 33 | "placeholder": { 34 | "type": "plain_text", 35 | "text": "Choose an industry", 36 | "emoji": true 37 | }, 38 | "options": [ 39 | { 40 | "text": { 41 | "type": "plain_text", 42 | "text": "Sports Spotlight", 43 | "emoji": true 44 | }, 45 | "value": "sports_spotlight" 46 | }, 47 | { 48 | "text": { 49 | "type": "plain_text", 50 | "text": "Real Estate Radar", 51 | "emoji": true 52 | }, 53 | "value": "real_estate_radar" 54 | }, 55 | { 56 | "text": { 57 | "type": "plain_text", 58 | "text": "Marketing Maven", 59 | "emoji": true 60 | }, 61 | "value": "marketing_maven" 62 | }, 63 | { 64 | "text": { 65 | "type": "plain_text", 66 | "text": "Stock Market Scoop", 67 | "emoji": true 68 | }, 69 | "value": "stock_market_scoop" 70 | }, 71 | { 72 | "text": { 73 | "type": "plain_text", 74 | "text": "Software Sphere", 75 | "emoji": true 76 | }, 77 | "value": "software_sphere" 78 | }, 79 | { 80 | "text": { 81 | "type": "plain_text", 82 | "text": "Hardware Hub", 83 | "emoji": true 84 | }, 85 | "value": "hardware_hub" 86 | }, 87 | { 88 | "text": { 89 | "type": "plain_text", 90 | "text": "Tech Trends", 91 | "emoji": true 92 | }, 93 | "value": "tech_trends" 94 | }, 95 | { 96 | "text": { 97 | "type": "plain_text", 98 | "text": "Finance Focus", 99 | "emoji": true 100 | }, 101 | "value": "finance_focus" 102 | }, 103 | { 104 | "text": { 105 | "type": "plain_text", 106 | "text": "Health Highlights", 107 | "emoji": true 108 | }, 109 | "value": "health_highlights" 110 | }, 111 | { 112 | "text": { 113 | "type": "plain_text", 114 | "text": "Auto Arena", 115 | "emoji": true 116 | }, 117 | "value": "auto_arena" 118 | } 119 | ] 120 | } 121 | } 122 | ] 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/resources/codetoTranslate.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "industry_select_modal", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "Wicebot", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "input", 24 | "block_id": "industry_select_block", 25 | "label": { 26 | "type": "plain_text", 27 | "text": "Select Your Field", 28 | "emoji": true 29 | }, 30 | "element": { 31 | "type": "static_select", 32 | "action_id": "industry_select_action", 33 | "placeholder": { 34 | "type": "plain_text", 35 | "text": "Choose an industry", 36 | "emoji": true 37 | }, 38 | "options": [ 39 | { 40 | "text": { 41 | "type": "plain_text", 42 | "text": "Sports Spotlight", 43 | "emoji": true 44 | }, 45 | "value": "sports_spotlight" 46 | }, 47 | { 48 | "text": { 49 | "type": "plain_text", 50 | "text": "Real Estate Radar", 51 | "emoji": true 52 | }, 53 | "value": "real_estate_radar" 54 | }, 55 | { 56 | "text": { 57 | "type": "plain_text", 58 | "text": "Marketing Maven", 59 | "emoji": true 60 | }, 61 | "value": "marketing_maven" 62 | }, 63 | { 64 | "text": { 65 | "type": "plain_text", 66 | "text": "Stock Market Scoop", 67 | "emoji": true 68 | }, 69 | "value": "stock_market_scoop" 70 | }, 71 | { 72 | "text": { 73 | "type": "plain_text", 74 | "text": "Software Sphere", 75 | "emoji": true 76 | }, 77 | "value": "software_sphere" 78 | }, 79 | { 80 | "text": { 81 | "type": "plain_text", 82 | "text": "Hardware Hub", 83 | "emoji": true 84 | }, 85 | "value": "hardware_hub" 86 | }, 87 | { 88 | "text": { 89 | "type": "plain_text", 90 | "text": "Tech Trends", 91 | "emoji": true 92 | }, 93 | "value": "tech_trends" 94 | }, 95 | { 96 | "text": { 97 | "type": "plain_text", 98 | "text": "Finance Focus", 99 | "emoji": true 100 | }, 101 | "value": "finance_focus" 102 | }, 103 | { 104 | "text": { 105 | "type": "plain_text", 106 | "text": "Health Highlights", 107 | "emoji": true 108 | }, 109 | "value": "health_highlights" 110 | }, 111 | { 112 | "text": { 113 | "type": "plain_text", 114 | "text": "Auto Arena", 115 | "emoji": true 116 | }, 117 | "value": "auto_arena" 118 | } 119 | ] 120 | } 121 | } 122 | ] 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/View.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class View { 9 | private String id; 10 | private String team_id; 11 | private String type; 12 | private List blocks; 13 | private String private_metadata; 14 | private String callback_id; 15 | private String hash; 16 | private boolean clear_on_close; 17 | private boolean notify_on_close; 18 | private String root_view_id; 19 | private String app_id; 20 | private String external_id; 21 | private String app_installed_team_id; 22 | private String bot_id; 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public void setId(String id) { 29 | this.id = id; 30 | } 31 | 32 | public String getTeam_id() { 33 | return team_id; 34 | } 35 | 36 | public void setTeam_id(String team_id) { 37 | this.team_id = team_id; 38 | } 39 | 40 | public String getType() { 41 | return type; 42 | } 43 | 44 | public void setType(String type) { 45 | this.type = type; 46 | } 47 | 48 | public List getBlocks() { 49 | return blocks; 50 | } 51 | 52 | public void setBlocks(List blocks) { 53 | this.blocks = blocks; 54 | } 55 | 56 | public String getPrivate_metadata() { 57 | return private_metadata; 58 | } 59 | 60 | public void setPrivate_metadata(String private_metadata) { 61 | this.private_metadata = private_metadata; 62 | } 63 | 64 | public String getCallback_id() { 65 | return callback_id; 66 | } 67 | 68 | public void setCallback_id(String callback_id) { 69 | this.callback_id = callback_id; 70 | } 71 | 72 | public String getHash() { 73 | return hash; 74 | } 75 | 76 | public void setHash(String hash) { 77 | this.hash = hash; 78 | } 79 | 80 | public boolean isClear_on_close() { 81 | return clear_on_close; 82 | } 83 | 84 | public void setClear_on_close(boolean clear_on_close) { 85 | this.clear_on_close = clear_on_close; 86 | } 87 | 88 | public boolean isNotify_on_close() { 89 | return notify_on_close; 90 | } 91 | 92 | public void setNotify_on_close(boolean notify_on_close) { 93 | this.notify_on_close = notify_on_close; 94 | } 95 | 96 | public String getRoot_view_id() { 97 | return root_view_id; 98 | } 99 | 100 | public void setRoot_view_id(String root_view_id) { 101 | this.root_view_id = root_view_id; 102 | } 103 | 104 | public String getApp_id() { 105 | return app_id; 106 | } 107 | 108 | public void setApp_id(String app_id) { 109 | this.app_id = app_id; 110 | } 111 | 112 | public String getExternal_id() { 113 | return external_id; 114 | } 115 | 116 | public void setExternal_id(String external_id) { 117 | this.external_id = external_id; 118 | } 119 | 120 | public String getApp_installed_team_id() { 121 | return app_installed_team_id; 122 | } 123 | 124 | public void setApp_installed_team_id(String app_installed_team_id) { 125 | this.app_installed_team_id = app_installed_team_id; 126 | } 127 | 128 | public String getBot_id() { 129 | return bot_id; 130 | } 131 | 132 | public void setBot_id(String bot_id) { 133 | this.bot_id = bot_id; 134 | } 135 | 136 | @Override 137 | public String toString() { 138 | return "View [id=" + id + ", team_id=" + team_id + ", type=" + type + ", blocks=" + blocks 139 | + ", private_metadata=" + private_metadata + ", callback_id=" + callback_id + ", hash=" + hash 140 | + ", clear_on_close=" + clear_on_close + ", notify_on_close=" + notify_on_close + ", root_view_id=" 141 | + root_view_id + ", app_id=" + app_id + ", external_id=" + external_id + ", app_installed_team_id=" 142 | + app_installed_team_id + ", bot_id=" + bot_id + "]"; 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/resources/afterpaymentview.json: -------------------------------------------------------------------------------- 1 | { 2 | "view_id": "viewId", 3 | "hash": "hashId", 4 | "type": "home", 5 | "blocks": [ 6 | { 7 | "type": "header", 8 | "text": { 9 | "type": "plain_text", 10 | "text": "Unleash the power of :bulb: GPT with :robot_face: Wicebot, your ultimate AI companion :speech_balloon:", 11 | "emoji": true 12 | } 13 | }, 14 | { 15 | "type": "divider" 16 | }, 17 | { 18 | "type": "actions", 19 | "elements": [ 20 | { 21 | "type": "button", 22 | "style": "danger", 23 | "text": { 24 | "type": "plain_text", 25 | "text": "Manage Subscription" 26 | }, 27 | "action_id": "pay1", 28 | "value": "upgrade_basic", 29 | "url": "customerPortalUrl" 30 | } 31 | ] 32 | }, 33 | { 34 | "type": "divider" 35 | }, 36 | { 37 | "type": "section", 38 | "text": { 39 | "type": "mrkdwn", 40 | "text": "*Usage:*\n\nYou are currently on the planName plan and have used usedRequest out of totalRequest this month." 41 | } 42 | }, 43 | { 44 | "type": "divider" 45 | }, 46 | { 47 | "type": "section", 48 | "text": { 49 | "type": "mrkdwn", 50 | "text": "*Feedback:*\n\nTell me how can I improvise." 51 | } 52 | }, 53 | { 54 | "type": "actions", 55 | "elements": [ 56 | { 57 | "type": "button", 58 | "style": "danger", 59 | "text": { 60 | "type": "plain_text", 61 | "text": "Give a Feedback" 62 | }, 63 | "action_id": "feedback", 64 | "value": "upgrade_pro" 65 | } 66 | ] 67 | }, 68 | { 69 | "type": "divider" 70 | }, 71 | { 72 | "type": "section", 73 | "text": { 74 | "type": "mrkdwn", 75 | "text": "*Welcome to Wicebot!*\nHere are some of our features:" 76 | } 77 | }, 78 | { 79 | "type": "section", 80 | "text": { 81 | "type": "mrkdwn", 82 | "text": ":speech_balloon: Wicebot can answer questions and respond to requests when mentioned in a message.\n:briefcase: Wicebot can engage in conversational interactions with users in the message tab.\n:brain: Wicebot can generate code quickly in response to a shortcut click, allowing users to save time and increase productivity.\n:electric_plug: Wicebot can translate code from one programming language to another, helping users who work with multiple languages.\n:newspaper: Wicebot can summarize thread conversations, making it easier for users to quickly understand the main points of a long discussion." 83 | } 84 | }, 85 | { 86 | "type": "divider" 87 | }, 88 | { 89 | "type": "section", 90 | "text": { 91 | "type": "mrkdwn", 92 | "text": "*1. Wicebot mention in action!*" 93 | } 94 | }, 95 | { 96 | "type": "image", 97 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/%40mention.gif", 98 | "alt_text": "Wicebot in action" 99 | }, 100 | { 101 | "type": "divider" 102 | }, 103 | { 104 | "type": "section", 105 | "text": { 106 | "type": "mrkdwn", 107 | "text": "*2. Chat with Wicebot, it's easy as pie!*" 108 | } 109 | }, 110 | { 111 | "type": "image", 112 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/conversation.gif", 113 | "alt_text": "Chat with Wicebot, it's easy as pie!" 114 | }, 115 | { 116 | "type": "divider" 117 | }, 118 | { 119 | "type": "section", 120 | "text": { 121 | "type": "mrkdwn", 122 | "text": "*3. Need to code, but don't have the time?*" 123 | } 124 | }, 125 | { 126 | "type": "image", 127 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/rapidcode.gif", 128 | "alt_text": "Need to code, but don't have the time?" 129 | }, 130 | { 131 | "type": "divider" 132 | }, 133 | { 134 | "type": "section", 135 | "text": { 136 | "type": "mrkdwn", 137 | "text": "*4. From Java to Python, we've got you covered!*" 138 | } 139 | }, 140 | { 141 | "type": "image", 142 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/translatecode.gif", 143 | "alt_text": "From Java to Python, we've got you covered!" 144 | } 145 | ] 146 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/services/PowerPointCreator.java: -------------------------------------------------------------------------------- 1 | 2 | package com.openai.services; 3 | 4 | import java.awt.Color; 5 | import java.awt.Dimension; 6 | import java.awt.geom.Rectangle2D; 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; 14 | import org.apache.poi.util.IOUtils; 15 | import org.apache.poi.xslf.usermodel.SlideLayout; 16 | import org.apache.poi.xslf.usermodel.XMLSlideShow; 17 | import org.apache.poi.xslf.usermodel.XSLFBackground; 18 | import org.apache.poi.xslf.usermodel.XSLFPictureData; 19 | import org.apache.poi.xslf.usermodel.XSLFSlide; 20 | import org.apache.poi.xslf.usermodel.XSLFSlideLayout; 21 | import org.apache.poi.xslf.usermodel.XSLFSlideMaster; 22 | import org.apache.poi.xslf.usermodel.XSLFTextBox; 23 | import org.apache.poi.xslf.usermodel.XSLFTextParagraph; 24 | import org.apache.poi.xslf.usermodel.XSLFTextRun; 25 | import org.springframework.stereotype.Service; 26 | 27 | import com.openai.slack.event.dto.SlideData; 28 | 29 | @Service 30 | public class PowerPointCreator { 31 | 32 | static { 33 | // Set a higher override value for the maximum allowable size 34 | IOUtils.setByteArrayMaxOverride(1000 * 1024 * 1024); // 100 MB 35 | } 36 | 37 | public String createPresentation(List slideDataList) throws IOException { 38 | XMLSlideShow ppt = new XMLSlideShow(); 39 | 40 | for (SlideData slideData : slideDataList) { 41 | createSlide(ppt, slideData); 42 | } 43 | String outputFilePath = "output.pptx"; // Specify the output file path 44 | // Save the presentation 45 | try (FileOutputStream out = new FileOutputStream(outputFilePath)) { 46 | ppt.write(out); 47 | } 48 | ppt.close(); 49 | return outputFilePath; 50 | } 51 | 52 | private void createSlide(XMLSlideShow ppt, SlideData slideData) throws IOException { 53 | // Create a blank slide layout 54 | XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0); 55 | XSLFSlideLayout blankLayout = defaultMaster.getLayout(SlideLayout.BLANK); 56 | XSLFSlide slide = ppt.createSlide(blankLayout); 57 | 58 | // Set the background color of the slide to white (optional) 59 | XSLFBackground background = slide.getBackground(); 60 | background.setFillColor(Color.WHITE); 61 | 62 | // Define dimensions 63 | Dimension pgsize = ppt.getPageSize(); 64 | 65 | // Add title text box 66 | double left = 0.5 * 72; // 0.5 inches 67 | double top = 0.5 * 72; // 0.5 inches 68 | double width = pgsize.getWidth() - 1 * 72; // full width minus 1 inch 69 | double height = 1 * 72; // 1 inch 70 | 71 | XSLFTextBox titleBox = slide.createTextBox(); 72 | titleBox.setAnchor(new Rectangle2D.Double(left, top, width, height)); 73 | XSLFTextParagraph titleP = titleBox.addNewTextParagraph(); 74 | titleP.setTextAlign(TextAlign.CENTER); 75 | XSLFTextRun r1 = titleP.addNewTextRun(); 76 | r1.setText(slideData.getTitle()); 77 | r1.setFontSize(24.0); 78 | r1.setBold(true); 79 | r1.setFontColor(Color.BLACK); 80 | 81 | // Add text box 82 | top = 1.5 * 72; // 1.5 inches 83 | height = 2 * 72; // 2 inches 84 | 85 | XSLFTextBox textBox = slide.createTextBox(); 86 | textBox.setAnchor(new Rectangle2D.Double(left, top, width, height)); 87 | XSLFTextParagraph textP = textBox.addNewTextParagraph(); 88 | textP.setTextAlign(TextAlign.LEFT); 89 | XSLFTextRun r2 = textP.addNewTextRun(); 90 | r2.setText(slideData.getText()); 91 | r2.setFontSize(18.0); 92 | r2.setFontColor(Color.BLACK); 93 | 94 | // Add image 95 | if (slideData.getImagePath() != null && !slideData.getImagePath().isEmpty()) { 96 | File imageFile = new File(slideData.getImagePath()); 97 | if (imageFile.exists()) { 98 | XSLFPictureData pd = ppt.addPicture(imageFile, XSLFPictureData.PictureType.JPEG); 99 | width = pgsize.getWidth() - 1 * 72; // full width minus 1 inch 100 | height = pgsize.getHeight() - 4 * 72; // height minus margins for title and text 101 | left = 0.5 * 72; // 0.5 inches 102 | top = 3.5 * 72; // 3.5 inches 103 | 104 | slide.createPicture(pd).setAnchor(new Rectangle2D.Double(left, top, width, height)); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/openai/services/OpenAiMessageRequestCreator.java: -------------------------------------------------------------------------------- 1 | package com.openai.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | import com.openai.entity.TextRequestQueue; 12 | import com.openai.repository.OpenAiModalRepository; 13 | import com.openai.repository.TextRequestQueueRepository; 14 | import com.openai.utils.Constants; 15 | import com.openai.utils.SlackDTOConvertor; 16 | import com.theokanning.openai.completion.CompletionRequest; 17 | import com.theokanning.openai.completion.chat.ChatMessage; 18 | import com.theokanning.openai.service.OpenAiService; 19 | 20 | @Service 21 | public class OpenAiMessageRequestCreator { 22 | 23 | Logger logger = LoggerFactory.getLogger(OpenAiMessageCreation.class); 24 | 25 | @Autowired 26 | OpenAiService openAiService; 27 | 28 | @Autowired 29 | OpenAiModalRepository aiModalRepository; 30 | 31 | @Autowired 32 | TextRequestQueueRepository queueRepository; 33 | 34 | public List writeCode(String teamId, String userId, String channelId, String toLang, String instruction, 35 | String token) { 36 | logger.info("teamI: {} userId: {} channelId: {} toLang: {} instruction {} token {}", teamId, userId, channelId, 37 | toLang, instruction, token); 38 | List chatMessages = new ArrayList<>(); 39 | chatMessages.add(new ChatMessage("system","The following is a conversation with an AI programming assistant. The assistant is helpful, creative, clever, very friendly and only response to coding question.")); 40 | String prompt = "Write code for following instruction in " + toLang + " language\n" + instruction; 41 | prompt = prompt.trim(); 42 | logger.info("input to open a Modal: {} ", prompt); 43 | chatMessages.add(new ChatMessage("user",prompt)); 44 | return chatMessages; 45 | } 46 | 47 | public String writeCodeGPT4(String teamId, String userId, String channelId, String toLang, String instruction, 48 | String token) { 49 | logger.info("teamI: {} userId: {} channelId: {} toLang: {} instruction {} token {}", teamId, userId, channelId, 50 | toLang, instruction, token); 51 | String prompt = "Write code for following instruction in " + toLang + " language\n" + instruction; 52 | prompt = prompt.trim(); 53 | return prompt; 54 | } 55 | 56 | public List transLateCode(String teamId, String userId, String channelId, String fromLang, 57 | String toLang, String code, String token) { 58 | logger.info("teamId: {} userId: {} channelId: {} fromLang {} toLang: {} code {} token {}", teamId, userId, 59 | channelId, fromLang, toLang, code, token); 60 | List chatMessages = new ArrayList<>(); 61 | chatMessages.add(new ChatMessage("system","The following is a conversation with an AI programming assistant. The assistant is helpful, creative, clever, very friendly and only response to coding question.")); 62 | String prompt = "Translate below code from from_lang into to_lang\n" 63 | + " codedetails"; 64 | prompt = prompt.replaceAll("from_lang", fromLang).replaceAll("to_lang", toLang).replace("codedetails", code); 65 | chatMessages.add(new ChatMessage("user", prompt)); 66 | logger.info("input to open a Modal: {} ", prompt); 67 | return chatMessages; 68 | } 69 | 70 | public String transLateCodeGPT4(String teamId, String userId, String channelId, String fromLang, 71 | String toLang, String code, String token) { 72 | String prompt = "Translate below code from from_lang into to_lang\n" 73 | + " codedetails"; 74 | prompt = prompt.replaceAll("from_lang", fromLang).replaceAll("to_lang", toLang).replace("codedetails", code); 75 | prompt = prompt.trim(); 76 | return prompt; 77 | } 78 | 79 | 80 | public String translateTextGPT4(String teamId, String userId, String channelId, String fromLang, 81 | String toLang, String code, String token) { 82 | String prompt = "Translate below text from from_lang into to_lang. Only give translated text in result no other words."; 83 | prompt = prompt.replaceAll("from_lang", fromLang).replaceAll("to_lang", toLang).replace("codedetails", code); 84 | prompt = prompt.trim(); 85 | return prompt; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/EventPayload.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class EventPayload { 10 | 11 | private String token; 12 | private String team_id; 13 | private String api_app_id; 14 | private Event event; 15 | private String type; 16 | private String event_id; 17 | private int event_time; 18 | private ArrayList authorizations; 19 | private boolean is_ext_shared_channel; 20 | private String event_context; 21 | private String trigger_id; 22 | private String callback_id; 23 | private List actions; 24 | private User user; 25 | private View view; 26 | private String response_url; 27 | private Channel channel; 28 | private Container container; 29 | private String message_ts; 30 | 31 | public String getToken() { 32 | return token; 33 | } 34 | 35 | public void setToken(String token) { 36 | this.token = token; 37 | } 38 | 39 | public String getTeam_id() { 40 | return team_id; 41 | } 42 | 43 | public void setTeam_id(String team_id) { 44 | this.team_id = team_id; 45 | } 46 | 47 | public String getApi_app_id() { 48 | return api_app_id; 49 | } 50 | 51 | public void setApi_app_id(String api_app_id) { 52 | this.api_app_id = api_app_id; 53 | } 54 | 55 | public Event getEvent() { 56 | return event; 57 | } 58 | 59 | public void setEvent(Event event) { 60 | this.event = event; 61 | } 62 | 63 | public String getType() { 64 | return type; 65 | } 66 | 67 | public void setType(String type) { 68 | this.type = type; 69 | } 70 | 71 | public String getEvent_id() { 72 | return event_id; 73 | } 74 | 75 | public void setEvent_id(String event_id) { 76 | this.event_id = event_id; 77 | } 78 | 79 | public int getEvent_time() { 80 | return event_time; 81 | } 82 | 83 | public void setEvent_time(int event_time) { 84 | this.event_time = event_time; 85 | } 86 | 87 | public ArrayList getAuthorizations() { 88 | return authorizations; 89 | } 90 | 91 | public void setAuthorizations(ArrayList authorizations) { 92 | this.authorizations = authorizations; 93 | } 94 | 95 | public boolean isIs_ext_shared_channel() { 96 | return is_ext_shared_channel; 97 | } 98 | 99 | public void setIs_ext_shared_channel(boolean is_ext_shared_channel) { 100 | this.is_ext_shared_channel = is_ext_shared_channel; 101 | } 102 | 103 | public String getEvent_context() { 104 | return event_context; 105 | } 106 | 107 | public void setEvent_context(String event_context) { 108 | this.event_context = event_context; 109 | } 110 | 111 | public String getTrigger_id() { 112 | return trigger_id; 113 | } 114 | 115 | public void setTrigger_id(String trigger_id) { 116 | this.trigger_id = trigger_id; 117 | } 118 | 119 | public String getCallback_id() { 120 | return callback_id; 121 | } 122 | 123 | public void setCallback_id(String callback_id) { 124 | this.callback_id = callback_id; 125 | } 126 | 127 | public List getActions() { 128 | return actions; 129 | } 130 | 131 | public void setActions(List actions) { 132 | this.actions = actions; 133 | } 134 | 135 | public User getUser() { 136 | return user; 137 | } 138 | 139 | public void setUser(User user) { 140 | this.user = user; 141 | } 142 | 143 | public View getView() { 144 | return view; 145 | } 146 | 147 | public void setView(View view) { 148 | this.view = view; 149 | } 150 | 151 | public String getResponse_url() { 152 | return response_url; 153 | } 154 | 155 | public void setResponse_url(String response_url) { 156 | this.response_url = response_url; 157 | } 158 | 159 | public Channel getChannel() { 160 | return channel; 161 | } 162 | 163 | public void setChannel(Channel channel) { 164 | this.channel = channel; 165 | } 166 | 167 | public Container getContainer() { 168 | return container; 169 | } 170 | 171 | public void setContainer(Container container) { 172 | this.container = container; 173 | } 174 | 175 | public String getMessage_ts() { 176 | return message_ts; 177 | } 178 | 179 | public void setMessage_ts(String message_ts) { 180 | this.message_ts = message_ts; 181 | } 182 | 183 | 184 | 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/ViewUpdateService.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import java.io.IOException; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.core.io.ResourceLoader; 10 | import org.springframework.http.HttpEntity; 11 | import org.springframework.http.HttpHeaders; 12 | import org.springframework.http.MediaType; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.web.client.RestTemplate; 15 | import com.openai.repository.SlackViewRepository; 16 | 17 | @Service 18 | public class ViewUpdateService { 19 | Logger logger = LoggerFactory.getLogger(ViewUpdateService.class); 20 | 21 | @Autowired 22 | ResourceLoader resourceLoader; 23 | 24 | @Autowired 25 | RestTemplate restTemplate; 26 | 27 | @Autowired 28 | SlackViewRepository slackViewRepository; 29 | 30 | @Value("${slackAppToken}") 31 | private String slackAppToken; 32 | 33 | // View for user whoes not primary 34 | public void updateViewForUserWithoutPrimeAccess(String viewId, String userId, String hashId, String token) throws IOException { 35 | logger.info("updateViewForUserWithoutPrimeAccess staretd with viewId {} userId {} hash {}", viewId, userId, 36 | hashId); 37 | String jsonPayload = slackViewRepository.findById("userwithnoprimeaccess").get().getView(); 38 | jsonPayload = jsonPayload.replace("viewId", viewId).replace("hashId", hashId); 39 | HttpHeaders headers = new HttpHeaders(); 40 | headers.setContentType(MediaType.APPLICATION_JSON); 41 | headers.setBearerAuth(token); 42 | HttpEntity request = new HttpEntity<>(jsonPayload, headers); 43 | String response = restTemplate.postForObject( 44 | "https://slack.com/api/views.update?user_id={userId}&view_id={viewId}", request, String.class, userId, 45 | viewId); 46 | logger.info("updateViewForUserWithoutPrimeAccess completed with responnse {} ", response); 47 | } 48 | 49 | public void openManageUserModal(String triggerId, int totalcountOfLicenses, String intiallySelectedUsers, String token) 50 | { 51 | logger.info("openManageUserModal staretd with triggerId {} totalcountOfLicenses {} intiallySelectedUsers {}", 52 | triggerId, totalcountOfLicenses, intiallySelectedUsers); 53 | String jsonPayload = slackViewRepository.findById("userSelection").get().getView(); 54 | jsonPayload = jsonPayload.replace("triggerId", triggerId) 55 | .replace("\"totalcountOfLicenses\"", totalcountOfLicenses + "") 56 | .replace("intialUsersId", intiallySelectedUsers); 57 | HttpHeaders headers = new HttpHeaders(); 58 | headers.setContentType(MediaType.APPLICATION_JSON); 59 | headers.setBearerAuth(token); 60 | HttpEntity request = new HttpEntity<>(jsonPayload, headers); 61 | String response = restTemplate.postForObject("https://slack.com/api/views.open", request, String.class); 62 | logger.info("pushViewFirstTime completed with response {} ", response); 63 | } 64 | 65 | public void openFeedbackModal(String userId, String triggerId, String viewName, String token) { 66 | logger.info("codeViewModal start: triggerId {}", 67 | triggerId); 68 | String jsonPayload = slackViewRepository.findById(viewName).get().getView(); 69 | jsonPayload = jsonPayload.replace("triggerId", triggerId).replace("userId", userId); 70 | HttpHeaders headers = new HttpHeaders(); 71 | headers.setContentType(MediaType.APPLICATION_JSON); 72 | headers.setBearerAuth(token); 73 | HttpEntity request = new HttpEntity<>(jsonPayload, headers); 74 | String response = restTemplate.postForObject("https://slack.com/api/views.open", request, String.class); 75 | logger.info("codeViewModal end: response {} ", response); 76 | } 77 | 78 | public void codeViewModal(String triggerId, String viewName, String token) { 79 | logger.info("codeViewModal start: triggerId {}", 80 | triggerId); 81 | String jsonPayload = slackViewRepository.findById(viewName).get().getView(); 82 | jsonPayload = jsonPayload.replace("triggerId", triggerId); 83 | HttpHeaders headers = new HttpHeaders(); 84 | headers.setContentType(MediaType.APPLICATION_JSON); 85 | headers.setBearerAuth(token); 86 | HttpEntity request = new HttpEntity<>(jsonPayload, headers); 87 | String response = restTemplate.postForObject("https://slack.com/api/views.open", request, String.class); 88 | logger.info("codeViewModal end: response {} ", response); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/event/dto/Event.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.event.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class Event { 10 | 11 | private String client_msg_id; 12 | private String type; 13 | private String text; 14 | private String user; 15 | private String ts; 16 | private String thread_ts; 17 | private ArrayList blocks; 18 | private String team; 19 | private String channel; 20 | private String event_ts; 21 | private String tab; 22 | private View view; 23 | private String channel_type; 24 | private String bot_id; 25 | private String app_id; 26 | private BotProfile bot_profile; 27 | private String parent_user_id; 28 | private String file_id; 29 | private List files; 30 | 31 | public String getClient_msg_id() { 32 | return client_msg_id; 33 | } 34 | 35 | public void setClient_msg_id(String client_msg_id) { 36 | this.client_msg_id = client_msg_id; 37 | } 38 | 39 | public String getType() { 40 | return type; 41 | } 42 | 43 | public void setType(String type) { 44 | this.type = type; 45 | } 46 | 47 | public String getText() { 48 | return text; 49 | } 50 | 51 | public void setText(String text) { 52 | this.text = text; 53 | } 54 | 55 | public String getUser() { 56 | return user; 57 | } 58 | 59 | public void setUser(String user) { 60 | this.user = user; 61 | } 62 | 63 | public String getTs() { 64 | return ts; 65 | } 66 | 67 | public void setTs(String ts) { 68 | this.ts = ts; 69 | } 70 | 71 | public ArrayList getBlocks() { 72 | return blocks; 73 | } 74 | 75 | public void setBlocks(ArrayList blocks) { 76 | this.blocks = blocks; 77 | } 78 | 79 | public String getTeam() { 80 | return team; 81 | } 82 | 83 | public void setTeam(String team) { 84 | this.team = team; 85 | } 86 | 87 | public String getChannel() { 88 | return channel; 89 | } 90 | 91 | public void setChannel(String channel) { 92 | this.channel = channel; 93 | } 94 | 95 | public String getEvent_ts() { 96 | return event_ts; 97 | } 98 | 99 | public void setEvent_ts(String event_ts) { 100 | this.event_ts = event_ts; 101 | } 102 | 103 | public String getThread_ts() { 104 | return thread_ts; 105 | } 106 | 107 | public void setThread_ts(String thread_ts) { 108 | this.thread_ts = thread_ts; 109 | } 110 | 111 | public String getTab() { 112 | return tab; 113 | } 114 | 115 | public void setTab(String tab) { 116 | this.tab = tab; 117 | } 118 | 119 | public View getView() { 120 | return view; 121 | } 122 | 123 | public void setView(View view) { 124 | this.view = view; 125 | } 126 | 127 | 128 | public String getChannel_type() { 129 | return channel_type; 130 | } 131 | 132 | public void setChannel_type(String channel_type) { 133 | this.channel_type = channel_type; 134 | } 135 | 136 | 137 | 138 | public String getBot_id() { 139 | return bot_id; 140 | } 141 | 142 | public void setBot_id(String bot_id) { 143 | this.bot_id = bot_id; 144 | } 145 | 146 | public String getApp_id() { 147 | return app_id; 148 | } 149 | 150 | public void setApp_id(String app_id) { 151 | this.app_id = app_id; 152 | } 153 | 154 | public BotProfile getBot_profile() { 155 | return bot_profile; 156 | } 157 | 158 | public void setBot_profile(BotProfile bot_profile) { 159 | this.bot_profile = bot_profile; 160 | } 161 | 162 | public String getParent_user_id() { 163 | return parent_user_id; 164 | } 165 | 166 | public void setParent_user_id(String parent_user_id) { 167 | this.parent_user_id = parent_user_id; 168 | } 169 | 170 | public String getFile_id() { 171 | return file_id; 172 | } 173 | 174 | public void setFile_id(String file_id) { 175 | this.file_id = file_id; 176 | } 177 | 178 | public List getFiles() { 179 | return files; 180 | } 181 | 182 | public void setFiles(List files) { 183 | this.files = files; 184 | } 185 | 186 | @Override 187 | public String toString() { 188 | return "Event [client_msg_id=" + client_msg_id + ", type=" + type + ", text=" + text + ", user=" + user 189 | + ", ts=" + ts + ", thread_ts=" + thread_ts + ", blocks=" + blocks + ", team=" + team + ", channel=" 190 | + channel + ", event_ts=" + event_ts + ", tab=" + tab + ", view=" + view + ", channel_type=" 191 | + channel_type + ", bot_id=" + bot_id + ", app_id=" + app_id + ", bot_profile=" + bot_profile 192 | + ", parent_user_id=" + parent_user_id + ", file_id=" + file_id + ", files=" + files + "]"; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /src/main/resources/firstTimeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "user_id": "userId", 3 | "view": { 4 | "type": "home", 5 | "blocks": [ 6 | { 7 | "type": "header", 8 | "text": { 9 | "type": "plain_text", 10 | "text": "Unleash the power of :bulb: GPT with :robot_face: Wicebot.", 11 | "emoji": true 12 | } 13 | }, 14 | { 15 | "type": "divider" 16 | }, 17 | 18 | { 19 | "type": "context", 20 | "elements": [ 21 | { 22 | "type": "mrkdwn", 23 | "text": "*Free Plan*: free for 7 days with 100 request" 24 | } 25 | ] 26 | }, 27 | { 28 | "type": "divider" 29 | }, 30 | { 31 | "type": "context", 32 | "elements": [ 33 | { 34 | "type": "mrkdwn", 35 | "text": "*Basic Plan*: $4.99 1000 request/month" 36 | } 37 | ] 38 | }, 39 | { 40 | "type": "actions", 41 | "elements": [ 42 | { 43 | "type": "button", 44 | "style": "danger", 45 | "text": { 46 | "type": "plain_text", 47 | "text": "Upgrade to Basic Plan" 48 | }, 49 | "action_id": "basicUrl", 50 | "value": "upgrade_basic", 51 | "url": "basicUrl" 52 | } 53 | ] 54 | }, 55 | { 56 | "type": "divider" 57 | }, 58 | { 59 | "type": "context", 60 | "elements": [ 61 | { 62 | "type": "mrkdwn", 63 | "text": "*Pro Plan*: $8.99 3000 request/month" 64 | } 65 | ] 66 | }, 67 | { 68 | "type": "actions", 69 | "elements": [ 70 | { 71 | "type": "button", 72 | "style": "danger", 73 | "text": { 74 | "type": "plain_text", 75 | "text": "Upgrade to Pro Plan" 76 | }, 77 | "action_id": "proUrl", 78 | "value": "upgrade_pro", 79 | "url": "proUrl" 80 | } 81 | ] 82 | }, 83 | { 84 | "type": "divider" 85 | }, 86 | { 87 | "type": "section", 88 | "text": { 89 | "type": "mrkdwn", 90 | "text": "*Usage:*\n\nYou are currently on the planName plan and have used usedRequest out of totalRequest this month." 91 | } 92 | }, 93 | { 94 | "type": "divider" 95 | }, 96 | { 97 | "type": "section", 98 | "text": { 99 | "type": "mrkdwn", 100 | "text": "*Feedback:*\n\nTell me how can I improvise." 101 | } 102 | }, 103 | { 104 | "type": "actions", 105 | "elements": [ 106 | { 107 | "type": "button", 108 | "style": "danger", 109 | "text": { 110 | "type": "plain_text", 111 | "text": "Give a Feedback" 112 | }, 113 | "action_id": "feedback", 114 | "value": "upgrade_pro" 115 | } 116 | ] 117 | }, 118 | { 119 | "type": "divider" 120 | }, 121 | { 122 | "type": "section", 123 | "text": { 124 | "type": "mrkdwn", 125 | "text": "*Welcome to Wicebot!*\nHere are some of our features:" 126 | } 127 | }, 128 | { 129 | "type": "section", 130 | "text": { 131 | "type": "mrkdwn", 132 | "text": ":speech_balloon: Wicebot can answer questions and respond to requests when mentioned in a message.\n:briefcase: Wicebot can engage in conversational interactions with users in the message tab.\n:brain: Wicebot can generate code quickly in response to a shortcut click, allowing users to save time and increase productivity.\n:electric_plug: Wicebot can translate code from one programming language to another, helping users who work with multiple languages.\n:newspaper: Wicebot can summarize thread conversations, making it easier for users to quickly understand the main points of a long discussion." 133 | } 134 | }, 135 | { 136 | "type": "divider" 137 | }, 138 | { 139 | "type": "section", 140 | "text": { 141 | "type": "mrkdwn", 142 | "text": "*1. Wicebot mention in action!*" 143 | } 144 | }, 145 | { 146 | "type": "image", 147 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/%40mention.gif", 148 | "alt_text": "Wicebot in action" 149 | }, 150 | { 151 | "type": "divider" 152 | }, 153 | { 154 | "type": "section", 155 | "text": { 156 | "type": "mrkdwn", 157 | "text": "*2. Chat with Wicebot, it's easy as pie!*" 158 | } 159 | }, 160 | { 161 | "type": "image", 162 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/conversation.gif", 163 | "alt_text": "Chat with Wicebot, it's easy as pie!" 164 | }, 165 | { 166 | "type": "divider" 167 | }, 168 | { 169 | "type": "section", 170 | "text": { 171 | "type": "mrkdwn", 172 | "text": "*3. Need to code, but don't have the time?*" 173 | } 174 | }, 175 | { 176 | "type": "image", 177 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/rapidcode.gif", 178 | "alt_text": "Need to code, but don't have the time?" 179 | }, 180 | { 181 | "type": "divider" 182 | }, 183 | { 184 | "type": "section", 185 | "text": { 186 | "type": "mrkdwn", 187 | "text": "*4. From Java to Python, we've got you covered!*" 188 | } 189 | }, 190 | { 191 | "type": "image", 192 | "image_url": "https://wicebotinactiongifs.s3.us-east-2.amazonaws.com/translatecode.gif", 193 | "alt_text": "From Java to Python, we've got you covered!" 194 | } 195 | ] 196 | } 197 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/SlackUserService.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Service; 13 | 14 | import com.openai.entity.SlackUser; 15 | import com.openai.repository.SlackUserRepository; 16 | import com.openai.repository.SlackViewRepository; 17 | import com.openai.repository.UserRequestDetailsRepository; 18 | import com.openai.utils.Constants; 19 | import com.openai.utils.TimeUtils; 20 | 21 | @Service 22 | public class SlackUserService { 23 | 24 | Logger logger = LoggerFactory.getLogger(SlackUserService.class); 25 | 26 | @Autowired 27 | SlackUserRepository slackUserRepository; 28 | 29 | @Autowired 30 | UserRequestDetailsRepository userRequestDetailsRepository; 31 | 32 | @Autowired 33 | SlackMessageServices messageServices; 34 | 35 | @Autowired 36 | SlackViewRepository slackViewRepository; 37 | 38 | @Autowired 39 | SlackOauthService slackOauthService; 40 | 41 | public SlackUser getSlackUser(String teamId, String userId) { 42 | logger.info("getSlackUser start: teamId {} userId {}", teamId, userId); 43 | SlackUser slackUser = slackUserRepository.findByTeamIdAndUserId(teamId, userId); 44 | if (slackUser == null) { 45 | logger.info("getSlackUser: creating user beacuse it does not exist"); 46 | slackUser = new SlackUser(); 47 | slackUser.setTeamId(teamId); 48 | slackUser.setUserId(userId); 49 | slackUser.setCreatedDate(new Date()); 50 | slackUser.setUpdatedDate(new Date()); 51 | slackUser.setPlan(Constants.FREE_PLAN); 52 | slackUser.setCount(100); 53 | slackUserRepository.save(slackUser); 54 | } 55 | logger.info("getSlackUser end: teamId {} userId {}", teamId, userId); 56 | return slackUser; 57 | } 58 | 59 | public boolean isMessagesTabFirstTime(SlackUser slackUser, String dmChannelId) { 60 | logger.info("getSlackUser start: dmChannelId{}", dmChannelId); 61 | boolean result = false; 62 | if(slackUser.getDmChannelId() == null) { 63 | slackUser.setDmChannelId(dmChannelId); 64 | slackUser = slackUserRepository.save(slackUser); 65 | result = true; 66 | } 67 | logger.info("getSlackUser start: result {}", result); 68 | return result; 69 | } 70 | 71 | public void updateUserAccess(List userList, String teamId, String primeUserId) { 72 | logger.info("updateUserAccess start: userList {} teamId {} primeUserId {} ", userList.toString(), teamId, 73 | primeUserId); 74 | SlackUser primeUser = slackUserRepository.findByTeamIdAndUserId(teamId, primeUserId); 75 | List existingUsers = slackUserRepository.findByTeamId(teamId); 76 | SlackUser slackUser = null; 77 | List slackUserList = new ArrayList<>(); 78 | Map userMap = new HashMap<>(); 79 | List deleteUsers = new ArrayList<>(); 80 | for (String userId : userList) { 81 | // If its primary dont touch 82 | if (primeUser.getUserId().equals(userId)) { 83 | continue; 84 | } 85 | slackUser = new SlackUser(); 86 | slackUser.setUserId(userId); 87 | slackUser.setTeamId(teamId); 88 | slackUser.setValidTill(TimeUtils.addSevenDays()); 89 | slackUser.setSubscriptionId(primeUser.getSubscriptionId()); 90 | slackUser.setPrimary(false); 91 | slackUser.setCreatedDate(new Date()); 92 | slackUser.setUpdatedDate(new Date()); 93 | userMap.put(userId, slackUser); 94 | slackUserList.add(slackUser); 95 | } 96 | for (SlackUser existingUser : existingUsers) { 97 | if (!userMap.containsKey(existingUser.getUserId()) && !existingUser.isPrimary()) { 98 | deleteUsers.add(existingUser); 99 | } 100 | } 101 | slackUserRepository.deleteAll(deleteUsers); 102 | slackUserRepository.saveAll(slackUserList); 103 | logger.info("updateUserAccess end"); 104 | } 105 | 106 | public List getSubscribedUsersInTeam(String teamId, String userId) { 107 | logger.info("getSubscribedUsersInTeam start: teamId {} userId {}", teamId, userId); 108 | SlackUser slackUser = slackUserRepository.findByTeamIdAndUserId(teamId, userId); 109 | logger.info("getSubscribedUsersInTeam completed"); 110 | return slackUserRepository.findByTeamIdAndSubscriptionId(teamId, slackUser.getSubscriptionId()); 111 | } 112 | 113 | public Boolean updateSubscriptionDetails(String teamId, String userId, String subscriptionId, String plan) { 114 | logger.info("updateSubscriptionDetails start: teamId {} userId {} subscriptionId {}", teamId, userId, 115 | subscriptionId); 116 | SlackUser slackUser = slackUserRepository.findByTeamIdAndUserId(teamId, userId); 117 | slackUser.setSubscriptionId(subscriptionId); 118 | slackUser.setUpdatedDate(new Date()); 119 | slackUser.setPrimary(true); 120 | slackUser.setPlan(plan); 121 | if(Constants.BASIC_PLAN.equalsIgnoreCase(plan)) { 122 | slackUser.setCount(1000); 123 | }else if(Constants.PROFESSIONAL_PLAN.equalsIgnoreCase(plan)) { 124 | slackUser.setCount(3000); 125 | } 126 | slackUserRepository.save(slackUser); 127 | logger.info("updateSubscriptionDetais completed"); 128 | return true; 129 | } 130 | 131 | 132 | } 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wicebot : Slack Assistant 💬🤖 2 | 3 |

4 | Wicebot banner 5 |

6 | 7 | ![Java](https://img.shields.io/badge/Java-1.8-blue?style=for-the-badge&logo=java) 8 | ![Spring Boot](https://img.shields.io/badge/Spring--Boot-2.6.2-success?style=for-the-badge&logo=spring) 9 | ![Maven](https://img.shields.io/badge/Maven-Build-red?style=for-the-badge&logo=apachemaven) 10 | ![Slack](https://img.shields.io/badge/Slack-API-blueviolet?style=for-the-badge&logo=slack) 11 | ![OpenAI](https://img.shields.io/badge/OpenAI-Integration-FF9900?style=for-the-badge&logo=openai) 12 | 13 | > **Wicebot** is a feature-rich, Java-powered Slack assistant that automates everyday workflows, answers questions with GPT-4o, and keeps your workspace humming. 14 | 15 | [![Watch the demo](https://img.youtube.com/vi/Sdwv4zx4LJs/0.jpg)](https://youtu.be/Sdwv4zx4LJs?si=X5UJKzbqvjM2TIIE) 16 | 17 | --- 18 | 19 | ## 📒 Table of Contents 20 | 21 | 1. [Features](#features) 22 | 2. [Screenshots](#screenshots) 23 | 3. [How It Works (Architecture)](#architecture) 24 | 4. [Quick Start](#quick-start) 25 | 5. [Project Structure](#project-structure) 26 | 6. [Command Reference](#command-reference) 27 | 7. [Development Workflow](#development-workflow) 28 | 8. [Roadmap](#roadmap) 29 | 9. [Contributing](#contributing) 30 | 10. [License & Acknowledgements](#license--acknowledgements) 31 | 32 | 33 | ## ✨ Features 34 | 35 | | Category | Description | 36 | | --- | --- | 37 | | 🤖 AI Assistant | Natural-language Q&A, summarization, sentiment analysis (OpenAI GPT-4o) | 38 | | 💬 Slash Commands | `/wice help`, `/wice sentiment`, `/wice jira`, `/wice weather`, `/wice standup` | 39 | | 🗓️ Schedulers | Cron-style reminders & daily stand-up digest | 40 | | 📌 Interactive Blocks | Modals & dialogs (e.g. create Jira ticket) | 41 | | 🔌 Plug-in System | Add new commands via Spring `@Component` without touching core | 42 | | 📡 Event Listeners | Reacts to message_added, reaction_added, member_joined events | 43 | | 🔭 Observability | Prometheus metrics + structured JSON logs | 44 | | 🛡️ Security | Slack signing secret validation & OAuth 2.0 token rotation | 45 | 46 | 47 | ## 🏗️ How It Works (Architecture) 48 | 49 |

50 | Wicebot banner 51 |

52 | 53 | ## 🚀 Quick Start 54 | 55 | > **Prerequisites:** Java 17, Maven, a Slack workspace, and an OpenAI API key. 56 | 57 | ```bash 58 | git clone https://github.com/yashjani/slackbot.git && cd slackbot 59 | cp .env.sample .env # fill in secrets 60 | ./mvnw spring-boot:run 61 | ``` 62 | 63 | > **Docker compose** 64 | > `docker compose up -d` will spin up Wicebot + Postgres + Redis. 65 | 66 | 67 | ## 📂 Project Structure 68 | 69 | ```text 70 | slackbot/ 71 | ├── docs/ # Images / GIFs / extra docs 72 | ├── src/main/java/ 73 | │ ├── bot/ # Core Bolt app & config 74 | │ ├── commands/ # Slash command handlers 75 | │ ├── events/ # Event listeners 76 | │ ├── schedulers/ # Quartz jobs 77 | │ └── plugins/ # Drop-in feature modules 78 | ├── src/test/java/ # Unit & integration tests 79 | ├── .github/workflows/ # CI pipeline 80 | └── docker-compose.yml 81 | ``` 82 | 83 | ## 🗂️ Command Reference 84 | 85 | | Command | Purpose | Example | 86 | | --- | --- | --- | 87 | | `/wice help` | Show help & feature list | — | 88 | | `/wice sentiment ` | Detect sentiment via GPT-4o | `/wice sentiment good job` | 89 | | `/wice jira ; <desc>` | Open Jira modal to file ticket | `/wice jira Login bug; Login fails on 2FA` | 90 | | `/wice weather <city>` | Current weather via Open-Meteo | `/wice weather Vancouver` | 91 | | `/wice standup` | Start daily stand-up thread | — | 92 | 93 | > **Tip:** Enable shortcuts to surface commands in message composer. 94 | 95 | ## 🔧 Development Workflow 96 | 97 | GitHub Actions → `mvn test` → Build JAR → Containerize → Push to **ghcr.io/yashjani/slackbot**. 98 | 99 | ```mermaid 100 | gantt 101 | dateFormat YYYY-MM-DD 102 | section CI/CD Pipeline 103 | Checkout Code :done, 2025-05-10, 5m 104 | Unit Tests :done, after Checkout Code, 3m 105 | Build JAR :done, after Unit Tests, 4m 106 | Docker Build :done, after Build JAR, 4m 107 | Deploy to Staging :active, after Docker Build, 5m 108 | ``` 109 | 110 | ## 🛣️ Roadmap 111 | 112 | - [ ] **AI Thread Summaries** – auto-summarize active channels every 6 h 113 | - [ ] **GitHub Releases Feed** – notify on new tags 114 | - [ ] **Voice Transcription** – convert voice messages to text (Whisper-cpp) 115 | - [ ] **Custom Helm Chart** – push to Artifact Hub 116 | 117 | ## 🤝 Contributing 118 | 119 | <details> 120 | <summary>Guidelines</summary> 121 | 122 | 1. Fork → create feature branch 123 | 2. Write tests (`@SpringBootTest` + `SlackAppTest`) 124 | 3. Run `./mvnw spotless:apply` 125 | 4. Submit PR – **GitHub Actions** must pass 🟢 126 | 127 | Feel free to open issues & feature requests. We love 🥑 first-timers! 128 | </details> 129 | 130 | ## ⚖️ License & Acknowledgements 131 | 132 | Licensed under the **MIT License** – see [`LICENSE`](LICENSE). 133 | 134 | > Built with ❤ by [@yashjani](https://github.com/yashjani) & community. 135 | 136 | Special thanks to Slack Bolt team, Spring Boot maintainers, and OpenAI. 137 | -------------------------------------------------------------------------------- /src/main/resources/codetoWrite.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "CodeToWrite", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "My App", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "input", 24 | "block_id": "in_lang", 25 | "label": { 26 | "type": "plain_text", 27 | "text": "Language", 28 | "emoji": true 29 | }, 30 | "optional": false, 31 | "dispatch_action": false, 32 | "element": { 33 | "type": "static_select", 34 | "action_id": "lang_value", 35 | "placeholder": { 36 | "type": "plain_text", 37 | "text": "Choose Language", 38 | "emoji": true 39 | }, 40 | "initial_option": { 41 | "text": { 42 | "type": "plain_text", 43 | "text": "React", 44 | "emoji": true 45 | }, 46 | "value": "React" 47 | }, 48 | "options": [ 49 | { 50 | "text": { 51 | "type": "plain_text", 52 | "text": "C#", 53 | "emoji": true 54 | }, 55 | "value": "C#" 56 | }, 57 | { 58 | "text": { 59 | "type": "plain_text", 60 | "text": "C++", 61 | "emoji": true 62 | }, 63 | "value": "C++" 64 | }, 65 | { 66 | "text": { 67 | "type": "plain_text", 68 | "text": "Erlang", 69 | "emoji": true 70 | }, 71 | "value": "Erlang" 72 | }, 73 | { 74 | "text": { 75 | "type": "plain_text", 76 | "text": "Go", 77 | "emoji": true 78 | }, 79 | "value": "Go" 80 | }, 81 | { 82 | "text": { 83 | "type": "plain_text", 84 | "text": "Haskell", 85 | "emoji": true 86 | }, 87 | "value": "Haskell" 88 | }, 89 | { 90 | "text": { 91 | "type": "plain_text", 92 | "text": "Java", 93 | "emoji": true 94 | }, 95 | "value": "Java" 96 | }, 97 | { 98 | "text": { 99 | "type": "plain_text", 100 | "text": "JavaScript", 101 | "emoji": true 102 | }, 103 | "value": "JavaScript" 104 | }, 105 | { 106 | "text": { 107 | "type": "plain_text", 108 | "text": "Kotlin", 109 | "emoji": true 110 | }, 111 | "value": "Kotlin" 112 | }, 113 | { 114 | "text": { 115 | "type": "plain_text", 116 | "text": "Objective-C", 117 | "emoji": true 118 | }, 119 | "value": "Objective-C" 120 | }, 121 | { 122 | "text": { 123 | "type": "plain_text", 124 | "text": "PHP", 125 | "emoji": true 126 | }, 127 | "value": "PHP" 128 | }, 129 | { 130 | "text": { 131 | "type": "plain_text", 132 | "text": "Python", 133 | "emoji": true 134 | }, 135 | "value": "Python" 136 | }, 137 | { 138 | "text": { 139 | "type": "plain_text", 140 | "text": "Ruby", 141 | "emoji": true 142 | }, 143 | "value": "Ruby" 144 | }, 145 | { 146 | "text": { 147 | "type": "plain_text", 148 | "text": "Rust", 149 | "emoji": true 150 | }, 151 | "value": "Rust" 152 | }, 153 | { 154 | "text": { 155 | "type": "plain_text", 156 | "text": "Scala", 157 | "emoji": true 158 | }, 159 | "value": "Scala" 160 | }, 161 | { 162 | "text": { 163 | "type": "plain_text", 164 | "text": "SQL", 165 | "emoji": true 166 | }, 167 | "value": "SQL" 168 | }, 169 | { 170 | "text": { 171 | "type": "plain_text", 172 | "text": "Swift", 173 | "emoji": true 174 | }, 175 | "value": "Swift" 176 | }, 177 | { 178 | "text": { 179 | "type": "plain_text", 180 | "text": "TypeScript", 181 | "emoji": true 182 | }, 183 | "value": "TypeScript" 184 | }, 185 | { 186 | "text": { 187 | "type": "plain_text", 188 | "text": "React", 189 | "emoji": true 190 | }, 191 | "value": "React" 192 | } 193 | ] 194 | } 195 | }, 196 | { 197 | "type": "input", 198 | "block_id": "instruction", 199 | "label": { 200 | "type": "plain_text", 201 | "text": "Instruction", 202 | "emoji": true 203 | }, 204 | "element": { 205 | "type": "plain_text_input", 206 | "initial_value": "1. Create FirstName component. \n2. Create LastName component.\n3. Add them to App component.", 207 | "action_id": "lang_value", 208 | "max_length": 500, 209 | "multiline": true 210 | } 211 | }, 212 | { 213 | "block_id": "channel_id", 214 | "type": "input", 215 | "optional": false, 216 | "label": { 217 | "type": "plain_text", 218 | "text": "Select a channel to post the result on" 219 | }, 220 | "element": { 221 | "action_id": "channel_id", 222 | "type": "conversations_select", 223 | "response_url_enabled": true, 224 | "filter": { 225 | "include": [ 226 | "public", 227 | "im" 228 | ], 229 | "exclude_bot_users" : true, 230 | "exclude_external_shared_channels": true 231 | } 232 | } 233 | } 234 | ]} 235 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/utils/SlackUtils.java: -------------------------------------------------------------------------------- 1 | package com.openai.utils; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.security.InvalidKeyException; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.HashSet; 9 | import java.util.List; 10 | import java.util.Set; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | import javax.crypto.Mac; 15 | import javax.crypto.spec.SecretKeySpec; 16 | 17 | import com.slack.api.model.Message; 18 | 19 | public class SlackUtils { 20 | 21 | public static List<String> getChunkFromMessages(List<Message> messages) { 22 | List<String> chunks = new ArrayList<>(); 23 | StringBuilder message = new StringBuilder(); 24 | messages.stream().map(s -> cleanUpString(s)).forEach(s -> { 25 | if (s.length() > 4000) { 26 | getChunk(s, chunks); 27 | } else { 28 | if (message.length() + s.length() > 4000) { 29 | chunks.add(message.toString()); 30 | message.setLength(0); 31 | } 32 | message.append(s + "\n"); 33 | } 34 | }); 35 | if (message.length() > 4000) { 36 | getChunk(message.toString(), chunks); 37 | } else { 38 | chunks.add(message.toString()); 39 | } 40 | return chunks; 41 | } 42 | 43 | public static List<String> getFileUrls(List<Message> messages) { 44 | List<String> fileUrls = new ArrayList<>(); 45 | for(Message message : messages) { 46 | if(message.getFiles() != null && !message.getFiles().isEmpty()) { 47 | message.getFiles().forEach(item -> fileUrls.add(item.getUrlPrivate())); 48 | } 49 | } 50 | return fileUrls; 51 | } 52 | 53 | public static void getChunk(String message, List<String> chunks) { 54 | if (message.length() > 0) { 55 | int index = 0; 56 | while (index < message.length()) { 57 | int endIndex = index + 4000; 58 | if (endIndex >= message.length()) { 59 | chunks.add(message.substring(index)); 60 | } else { 61 | chunks.add(message.substring(index, endIndex)); 62 | } 63 | index = endIndex; 64 | } 65 | } 66 | } 67 | 68 | public static String cleanUpString(Message message) { 69 | String input = getBotAndUserId(message) + ": " + message.getText(); 70 | Pattern pattern = Pattern.compile("<@\\w+>"); 71 | Matcher matcher = pattern.matcher(input); 72 | while (matcher.find()) { 73 | String userTag = matcher.group(); 74 | String userId = replaceUserTagsWithId(userTag); 75 | input = input.replaceAll(userTag, userId); 76 | } 77 | return removeUrl(input + " "); 78 | 79 | } 80 | 81 | public static String removeUrl(String input) { 82 | String pattern = "<[^>]+\\|([^>]+)>"; // regex pattern to match the text between '<' and '>' and after '|' 83 | String replacement = "$1"; // replacement string 84 | return input.replaceAll(pattern, replacement).trim().replaceAll("\n", " "); 85 | } 86 | 87 | public static Set<String> getUsersFromMessages(List<Message> messages) { 88 | Set<String> userIdSet = new HashSet<>(); 89 | Pattern pattern = Pattern.compile("<@\\w+>"); 90 | for (Message message : messages) { 91 | userIdSet.add(replaceUserTagsWithId(getBotAndUserId(message))); 92 | Matcher matcher = pattern.matcher(message.getText()); 93 | while (matcher.find()) { 94 | userIdSet.add(replaceUserTagsWithId(matcher.group())); 95 | } 96 | } 97 | return userIdSet; 98 | } 99 | 100 | public static String replaceUserIdWithTags(String output, Set<String> userIdSet) { 101 | for (String userId : userIdSet) { 102 | if (userId == null) 103 | continue; 104 | output = output.replaceAll(userId, "<@" + userId + ">"); 105 | } 106 | return output; 107 | } 108 | 109 | public static String replaceUserTagsWithId(String userTag) { 110 | String userId = userTag; 111 | return userId != null && !userId.isEmpty() ? userId.replaceAll("<@", "").replace(">", "") : userId; 112 | } 113 | 114 | public static String getBotAndUserId(Message messsage) { 115 | return messsage.getUser() == null ? messsage.getBotId() : messsage.getUser(); 116 | } 117 | 118 | public static List<String> stringToList(String input) { 119 | List<String> result = Arrays.asList(input.substring(1, input.length() - 1).split(",")); 120 | return result; 121 | } 122 | 123 | public static boolean verifySlackRequest(String slackSec, String timeStamp, String request, String slackSign) { 124 | 125 | long timestamp = Long.parseLong(timeStamp); 126 | long currentTime = System.currentTimeMillis() / 1000; 127 | if (Math.abs(currentTime - timestamp) > 60 * 5) { 128 | return false; 129 | } 130 | String sigBasestring = "v0:" + timestamp + ':' + request; 131 | String key = slackSec.getBytes(StandardCharsets.UTF_8).toString(); 132 | SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); 133 | Mac hmac = null; 134 | try { 135 | hmac = Mac.getInstance("HmacSHA256"); 136 | hmac.init(secretKey); 137 | } catch (Exception e) { 138 | // TODO Auto-generated catch block 139 | e.printStackTrace(); 140 | } 141 | byte[] hashBytes = hmac.doFinal(sigBasestring.getBytes(StandardCharsets.UTF_8)); 142 | String mySignature = "v0=" + bytesToHex(hashBytes).toLowerCase(); 143 | return slackSign.compareTo(mySignature) == 0; 144 | } 145 | 146 | public static String bytesToHex(byte[] bytes) { 147 | StringBuilder hex = new StringBuilder(); 148 | for (byte b : bytes) { 149 | hex.append(String.format("%02x", b)); 150 | } 151 | return hex.toString(); 152 | } 153 | } -------------------------------------------------------------------------------- /src/main/java/com/openai/entity/TextRequestQueue.java: -------------------------------------------------------------------------------- 1 | package com.openai.entity; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Lob; 11 | import javax.persistence.Temporal; 12 | import javax.persistence.TemporalType; 13 | 14 | @Entity 15 | public class TextRequestQueue { 16 | 17 | @Id 18 | @Column(name = "id") 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Long id; 21 | private String userId; 22 | private String channelId; 23 | @Temporal(TemporalType.TIMESTAMP) 24 | @Column(name = "createdDate", columnDefinition = "DATETIME") 25 | private Date createdDate; 26 | @Temporal(TemporalType.TIMESTAMP) 27 | @Column(name = "updatedDate", columnDefinition = "DATETIME") 28 | private Date updatedDate; 29 | @Lob 30 | private String input; 31 | private String lastStop; 32 | private String requestType; 33 | private int retryCount; 34 | private String status; 35 | private String teamId; 36 | @Column(name = "`usage`") 37 | private long usage; 38 | private String model; 39 | @Lob 40 | private String prompt; 41 | private String suffix; 42 | private Integer maxTokens; 43 | private Double temperature; 44 | private Double topP; 45 | private Integer n; 46 | private Boolean stream; 47 | private Integer logprobs; 48 | private Boolean echo; 49 | private String stop; 50 | private Double presencePenalty; 51 | private Double frequencyPenalty; 52 | private Integer bestOf; 53 | public Long getId() { 54 | return id; 55 | } 56 | public void setId(Long id) { 57 | this.id = id; 58 | } 59 | public String getUserId() { 60 | return userId; 61 | } 62 | public void setUserId(String userId) { 63 | this.userId = userId; 64 | } 65 | public String getChannelId() { 66 | return channelId; 67 | } 68 | public void setChannelId(String channelId) { 69 | this.channelId = channelId; 70 | } 71 | public Date getCreatedDate() { 72 | return createdDate; 73 | } 74 | public void setCreatedDate(Date createdDate) { 75 | this.createdDate = createdDate; 76 | } 77 | public Date getUpdatedDate() { 78 | return updatedDate; 79 | } 80 | public void setUpdatedDate(Date updatedDate) { 81 | this.updatedDate = updatedDate; 82 | } 83 | public String getLastStop() { 84 | return lastStop; 85 | } 86 | public void setLastStop(String lastStop) { 87 | this.lastStop = lastStop; 88 | } 89 | public String getRequestType() { 90 | return requestType; 91 | } 92 | public void setRequestType(String requestType) { 93 | this.requestType = requestType; 94 | } 95 | public int getRetryCount() { 96 | return retryCount; 97 | } 98 | public void setRetryCount(int retryCount) { 99 | this.retryCount = retryCount; 100 | } 101 | public String getStatus() { 102 | return status; 103 | } 104 | public void setStatus(String status) { 105 | this.status = status; 106 | } 107 | public String getTeamId() { 108 | return teamId; 109 | } 110 | public void setTeamId(String teamId) { 111 | this.teamId = teamId; 112 | } 113 | public long getUsage() { 114 | return usage; 115 | } 116 | public void setUsage(long usage) { 117 | this.usage = usage; 118 | } 119 | public String getModel() { 120 | return model; 121 | } 122 | public void setModel(String model) { 123 | this.model = model; 124 | } 125 | public String getPrompt() { 126 | return prompt; 127 | } 128 | public void setPrompt(String prompt) { 129 | this.prompt = prompt; 130 | } 131 | public String getSuffix() { 132 | return suffix; 133 | } 134 | public void setSuffix(String suffix) { 135 | this.suffix = suffix; 136 | } 137 | public Integer getMaxTokens() { 138 | return maxTokens; 139 | } 140 | public void setMaxTokens(Integer maxTokens) { 141 | this.maxTokens = maxTokens; 142 | } 143 | public Double getTemperature() { 144 | return temperature; 145 | } 146 | public void setTemperature(Double temperature) { 147 | this.temperature = temperature; 148 | } 149 | public Double getTopP() { 150 | return topP; 151 | } 152 | public void setTopP(Double topP) { 153 | this.topP = topP; 154 | } 155 | public Integer getN() { 156 | return n; 157 | } 158 | public void setN(Integer n) { 159 | this.n = n; 160 | } 161 | public Boolean getStream() { 162 | return stream; 163 | } 164 | public void setStream(Boolean stream) { 165 | this.stream = stream; 166 | } 167 | public Integer getLogprobs() { 168 | return logprobs; 169 | } 170 | public void setLogprobs(Integer logprobs) { 171 | this.logprobs = logprobs; 172 | } 173 | public Boolean getEcho() { 174 | return echo; 175 | } 176 | public void setEcho(Boolean echo) { 177 | this.echo = echo; 178 | } 179 | public String getStop() { 180 | return stop; 181 | } 182 | public void setStop(String stop) { 183 | this.stop = stop; 184 | } 185 | public Double getPresencePenalty() { 186 | return presencePenalty; 187 | } 188 | public void setPresencePenalty(Double presencePenalty) { 189 | this.presencePenalty = presencePenalty; 190 | } 191 | public Double getFrequencyPenalty() { 192 | return frequencyPenalty; 193 | } 194 | public void setFrequencyPenalty(Double frequencyPenalty) { 195 | this.frequencyPenalty = frequencyPenalty; 196 | } 197 | public Integer getBestOf() { 198 | return bestOf; 199 | } 200 | public void setBestOf(Integer bestOf) { 201 | this.bestOf = bestOf; 202 | } 203 | public String getInput() { 204 | return input; 205 | } 206 | public void setInput(String input) { 207 | this.input = input; 208 | } 209 | @Override 210 | public String toString() { 211 | return "TextRequestQueue [id=" + id + ", userId=" + userId + ", channelId=" + channelId + ", createdDate=" 212 | + createdDate + ", updatedDate=" + updatedDate + ", input=" + input + ", lastStop=" + lastStop 213 | + ", requestType=" + requestType + ", retryCount=" + retryCount + ", status=" + status + ", teamId=" 214 | + teamId + ", usage=" + usage + ", model=" + model + ", prompt=" + prompt + ", suffix=" + suffix 215 | + ", maxTokens=" + maxTokens + ", temperature=" + temperature + ", topP=" + topP + ", n=" + n 216 | + ", stream=" + stream + ", logprobs=" + logprobs + ", echo=" + echo + ", stop=" + stop 217 | + ", presencePenalty=" + presencePenalty + ", frequencyPenalty=" + frequencyPenalty + ", bestOf=" 218 | + bestOf + "]"; 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/main/resources/langtranslation.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger_id": "triggerId", 3 | "view": { 4 | "type": "modal", 5 | "callback_id": "LangToTranslate", 6 | "title": { 7 | "type": "plain_text", 8 | "text": "Wicebot", 9 | "emoji": true 10 | }, 11 | "submit": { 12 | "type": "plain_text", 13 | "text": "Submit", 14 | "emoji": true 15 | }, 16 | "close": { 17 | "type": "plain_text", 18 | "text": "Cancel", 19 | "emoji": true 20 | }, 21 | "blocks": [ 22 | { 23 | "type": "input", 24 | "block_id": "from_block", 25 | "label": { 26 | "type": "plain_text", 27 | "text": "From", 28 | "emoji": true 29 | }, 30 | "optional": false, 31 | "dispatch_action": false, 32 | "element": { 33 | "type": "static_select", 34 | "action_id": "lang_value", 35 | "placeholder": { 36 | "type": "plain_text", 37 | "text": "Choose Language", 38 | "emoji": true 39 | }, 40 | "initial_option": { 41 | "text": { 42 | "type": "plain_text", 43 | "text": "English", 44 | "emoji": true 45 | }, 46 | "value": "English" 47 | }, 48 | "options": [ 49 | { 50 | "text": { 51 | "type": "plain_text", 52 | "text": "English", 53 | "emoji": true 54 | }, 55 | "value": "English" 56 | }, 57 | { 58 | "text": { 59 | "type": "plain_text", 60 | "text": "Spanish", 61 | "emoji": true 62 | }, 63 | "value": "Spanish" 64 | }, 65 | { 66 | "text": { 67 | "type": "plain_text", 68 | "text": "French", 69 | "emoji": true 70 | }, 71 | "value": "French" 72 | }, 73 | { 74 | "text": { 75 | "type": "plain_text", 76 | "text": "German", 77 | "emoji": true 78 | }, 79 | "value": "German" 80 | }, 81 | { 82 | "text": { 83 | "type": "plain_text", 84 | "text": "Chinese", 85 | "emoji": true 86 | }, 87 | "value": "Chinese" 88 | }, 89 | { 90 | "text": { 91 | "type": "plain_text", 92 | "text": "Japanese", 93 | "emoji": true 94 | }, 95 | "value": "Japanese" 96 | }, 97 | { 98 | "text": { 99 | "type": "plain_text", 100 | "text": "Korean", 101 | "emoji": true 102 | }, 103 | "value": "Korean" 104 | }, 105 | { 106 | "text": { 107 | "type": "plain_text", 108 | "text": "Russian", 109 | "emoji": true 110 | }, 111 | "value": "Russian" 112 | }, 113 | { 114 | "text": { 115 | "type": "plain_text", 116 | "text": "Portuguese", 117 | "emoji": true 118 | }, 119 | "value": "Portuguese" 120 | }, 121 | { 122 | "text": { 123 | "type": "plain_text", 124 | "text": "Arabic", 125 | "emoji": true 126 | }, 127 | "value": "Arabic" 128 | } 129 | ] 130 | } 131 | }, 132 | { 133 | "type": "input", 134 | "block_id": "to_block", 135 | "label": { 136 | "type": "plain_text", 137 | "text": "To", 138 | "emoji": true 139 | }, 140 | "optional": false, 141 | "dispatch_action": false, 142 | "element": { 143 | "type": "static_select", 144 | "action_id": "lang_value", 145 | "placeholder": { 146 | "type": "plain_text", 147 | "text": "Choose Language", 148 | "emoji": true 149 | }, 150 | "initial_option": { 151 | "text": { 152 | "type": "plain_text", 153 | "text": "Spanish", 154 | "emoji": true 155 | }, 156 | "value": "Spanish" 157 | }, 158 | "options": [ 159 | { 160 | "text": { 161 | "type": "plain_text", 162 | "text": "English", 163 | "emoji": true 164 | }, 165 | "value": "English" 166 | }, 167 | { 168 | "text": { 169 | "type": "plain_text", 170 | "text": "Spanish", 171 | "emoji": true 172 | }, 173 | "value": "Spanish" 174 | }, 175 | { 176 | "text": { 177 | "type": "plain_text", 178 | "text": "French", 179 | "emoji": true 180 | }, 181 | "value": "French" 182 | }, 183 | { 184 | "text": { 185 | "type": "plain_text", 186 | "text": "German", 187 | "emoji": true 188 | }, 189 | "value": "German" 190 | }, 191 | { 192 | "text": { 193 | "type": "plain_text", 194 | "text": "Chinese", 195 | "emoji": true 196 | }, 197 | "value": "Chinese" 198 | }, 199 | { 200 | "text": { 201 | "type": "plain_text", 202 | "text": "Japanese", 203 | "emoji": true 204 | }, 205 | "value": "Japanese" 206 | }, 207 | { 208 | "text": { 209 | "type": "plain_text", 210 | "text": "Korean", 211 | "emoji": true 212 | }, 213 | "value": "Korean" 214 | }, 215 | { 216 | "text": { 217 | "type": "plain_text", 218 | "text": "Russian", 219 | "emoji": true 220 | }, 221 | "value": "Russian" 222 | }, 223 | { 224 | "text": { 225 | "type": "plain_text", 226 | "text": "Portuguese", 227 | "emoji": true 228 | }, 229 | "value": "Portuguese" 230 | }, 231 | { 232 | "text": { 233 | "type": "plain_text", 234 | "text": "Arabic", 235 | "emoji": true 236 | }, 237 | "value": "Arabic" 238 | } 239 | ] 240 | } 241 | }, 242 | { 243 | "type": "input", 244 | "block_id": "code", 245 | "label": { 246 | "type": "plain_text", 247 | "text": "Text to translate", 248 | "emoji": true 249 | }, 250 | "element": { 251 | "type": "plain_text_input", 252 | "action_id": "lang_value", 253 | "max_length": 1000, 254 | "multiline": true 255 | } 256 | }, 257 | { 258 | "block_id": "channel_id", 259 | "type": "input", 260 | "optional": false, 261 | "label": { 262 | "type": "plain_text", 263 | "text": "Select a channel to post the result on" 264 | }, 265 | "element": { 266 | "action_id": "channel_id", 267 | "type": "conversations_select", 268 | "response_url_enabled": true, 269 | "filter": { 270 | "include": [ 271 | "public", 272 | "im" 273 | ], 274 | "exclude_bot_users": true, 275 | "exclude_external_shared_channels": true 276 | } 277 | } 278 | } 279 | ] 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 | <modelVersion>4.0.0</modelVersion> 6 | <parent> 7 | <groupId>org.springframework.boot</groupId> 8 | <artifactId>spring-boot-starter-parent</artifactId> 9 | <version>2.6.2</version> 10 | <relativePath /> <!-- lookup parent from repository --> 11 | </parent> 12 | <groupId>com.example</groupId> 13 | <artifactId>openaiapi</artifactId> 14 | <version>0.0.1-SNAPSHOT</version> 15 | <name>openaiapi</name> 16 | <description>OpenAi integration</description> 17 | <properties> 18 | <java.version>1.8</java.version> 19 | <maven.compiler.target>1.8</maven.compiler.target> 20 | <maven.compiler.source>1.8</maven.compiler.source> 21 | </properties> 22 | <repositories> 23 | <repository> 24 | <id>jitpack.io</id> 25 | <url>https://jitpack.io</url> 26 | </repository> 27 | </repositories> 28 | 29 | <dependencies> 30 | <dependency> 31 | <groupId>com.google.http-client</groupId> 32 | <artifactId>google-http-client-jackson2</artifactId> 33 | <version>1.41.8</version> 34 | </dependency> 35 | <dependency> 36 | <groupId>com.google.http-client</groupId> 37 | <artifactId>google-http-client</artifactId> 38 | <version>1.41.8</version> 39 | </dependency> 40 | 41 | <dependency> 42 | <groupId>com.github.kokorin.jaffree</groupId> 43 | <artifactId>jaffree</artifactId> 44 | <version>2023.09.10</version> 45 | </dependency> 46 | 47 | <dependency> 48 | <groupId>org.springframework.boot</groupId> 49 | <artifactId>spring-boot-starter</artifactId> 50 | </dependency> 51 | <dependency> 52 | <groupId>org.springframework.boot</groupId> 53 | <artifactId>spring-boot-starter-web</artifactId> 54 | </dependency> 55 | <dependency> 56 | <groupId>com.theokanning.openai-gpt3-java</groupId> 57 | <artifactId>service</artifactId> 58 | <version>0.18.2</version> 59 | </dependency> 60 | <dependency> 61 | <groupId>com.theokanning.openai-gpt3-java</groupId> 62 | <artifactId>api</artifactId> 63 | <version>0.18.2</version> 64 | </dependency> 65 | <dependency> 66 | <groupId>com.theokanning.openai-gpt3-java</groupId> 67 | <artifactId>client</artifactId> 68 | <version>0.18.2</version> 69 | </dependency> 70 | 71 | 72 | <dependency> 73 | <groupId>org.javacord</groupId> 74 | <artifactId>javacord</artifactId> 75 | <version>3.7.0</version> 76 | <type>pom</type> 77 | </dependency> 78 | <dependency> 79 | <groupId>com.squareup.retrofit2</groupId> 80 | <artifactId>adapter-rxjava2</artifactId> 81 | <version>2.11.0</version> 82 | </dependency> 83 | <dependency> 84 | <groupId>com.squareup.retrofit2</groupId> 85 | <artifactId>converter-jackson</artifactId> 86 | <version>2.11.0</version> 87 | </dependency> 88 | <dependency> 89 | <groupId>com.kjetland</groupId> 90 | <artifactId>mbknor-jackson-jsonschema_2.13</artifactId> 91 | <version>1.0.36</version> 92 | </dependency> 93 | <dependency> 94 | <groupId>io.reactivex.rxjava2</groupId> 95 | <artifactId>rxjava</artifactId> 96 | <version>2.2.21</version> 97 | </dependency> 98 | <dependency> 99 | <groupId>com.knuddels</groupId> 100 | <artifactId>jtokkit</artifactId> 101 | <version>1.0.0</version> 102 | </dependency> 103 | <dependency> 104 | <groupId>org.projectlombok</groupId> 105 | <artifactId>lombok</artifactId> 106 | <version>1.18.32</version> 107 | <scope>provided</scope> 108 | </dependency> 109 | <dependency> 110 | <groupId>com.slack.api</groupId> 111 | <artifactId>bolt</artifactId> 112 | <version>1.27.3</version> 113 | <exclusions> 114 | <exclusion> 115 | <groupId>com.squareup.okhttp3</groupId> 116 | <artifactId>okhttp</artifactId> 117 | </exclusion> 118 | </exclusions> 119 | </dependency> 120 | <dependency> 121 | <groupId>com.squareup.okhttp3</groupId> 122 | <artifactId>okhttp</artifactId> 123 | <version>4.9.3</version> 124 | </dependency> 125 | <dependency> 126 | <groupId>org.springframework.boot</groupId> 127 | <artifactId>spring-boot-starter-test</artifactId> 128 | <scope>test</scope> 129 | </dependency> 130 | <dependency> 131 | <groupId>org.yaml</groupId> 132 | <artifactId>snakeyaml</artifactId> 133 | <version>1.33</version> 134 | </dependency> 135 | <dependency> 136 | <groupId>com.amazonaws</groupId> 137 | <artifactId>aws-java-sdk-sqs</artifactId> 138 | <version>1.12.150</version> 139 | </dependency> 140 | <dependency> 141 | <groupId>junit</groupId> 142 | <artifactId>junit</artifactId> 143 | <scope>test</scope> 144 | </dependency> 145 | <dependency> 146 | <groupId>org.junit.vintage</groupId> 147 | <artifactId>junit-vintage-engine</artifactId> 148 | <scope>test</scope> 149 | <exclusions> 150 | <exclusion> 151 | <groupId>org.hamcrest</groupId> 152 | <artifactId>hamcrest-core</artifactId> 153 | </exclusion> 154 | </exclusions> 155 | </dependency> 156 | <dependency> 157 | <groupId>com.stripe</groupId> 158 | <artifactId>stripe-java</artifactId> 159 | <version>20.128.0</version> 160 | </dependency> 161 | <dependency> 162 | <groupId>org.springframework.boot</groupId> 163 | <artifactId>spring-boot-starter-data-jpa</artifactId> 164 | </dependency> 165 | 166 | <dependency> 167 | <groupId>mysql</groupId> 168 | <artifactId>mysql-connector-java</artifactId> 169 | <version>8.0.26</version> 170 | </dependency> 171 | <dependency> 172 | <groupId>com.github.vladimir-bukhtoyarov</groupId> 173 | <artifactId>bucket4j-core</artifactId> 174 | <version>7.6.0</version> 175 | </dependency> 176 | <dependency> 177 | <groupId>com.github.serpapi</groupId> 178 | <artifactId>google-search-results-java</artifactId> 179 | <version>2.0.0</version> 180 | </dependency> 181 | <dependency> 182 | <groupId>org.twitter4j</groupId> 183 | <artifactId>twitter4j-core</artifactId> 184 | <version>4.0.7</version> 185 | </dependency> 186 | <dependency> 187 | <groupId>com.google.api-client</groupId> 188 | <artifactId>google-api-client</artifactId> 189 | <version>2.5.1</version> 190 | </dependency> 191 | <dependency> 192 | <groupId>org.apache.poi</groupId> 193 | <artifactId>poi-ooxml</artifactId> 194 | <version>5.2.3</version> 195 | </dependency> 196 | <dependency> 197 | <groupId>org.apache.xmlbeans</groupId> 198 | <artifactId>xmlbeans</artifactId> 199 | <version>5.1.1</version> 200 | </dependency> 201 | <dependency> 202 | <groupId>org.apache.poi</groupId> 203 | <artifactId>poi-ooxml-schemas</artifactId> 204 | <version>4.1.2</version> 205 | </dependency> 206 | </dependencies> 207 | 208 | 209 | <build> 210 | <plugins> 211 | <plugin> 212 | <groupId>org.springframework.boot</groupId> 213 | <artifactId>spring-boot-maven-plugin</artifactId> 214 | </plugin> 215 | </plugins> 216 | </build> 217 | </project> 218 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /src/main/java/com/openai/services/OpenAiMessageCreation.java: -------------------------------------------------------------------------------- 1 | package com.openai.services; 2 | 3 | import java.io.FileOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | import java.nio.file.Paths; 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.stereotype.Service; 18 | 19 | import com.fasterxml.jackson.core.JsonProcessingException; 20 | import com.fasterxml.jackson.databind.JsonMappingException; 21 | import com.fasterxml.jackson.databind.ObjectMapper; 22 | import com.google.gson.JsonObject; 23 | import com.google.gson.JsonParser; 24 | import com.openai.entity.OpenAiModal; 25 | import com.openai.repository.OpenAiModalRepository; 26 | import com.openai.slack.event.dto.SlideData; 27 | import com.openai.utils.Constants; 28 | import com.openai.utils.FileTypeChecker; 29 | import com.openai.utils.FileTypeChecker.FileType; 30 | import com.openai.utils.VideoToAudioConverter; 31 | import com.theokanning.openai.OpenAiResponse; 32 | import com.theokanning.openai.Usage; 33 | import com.theokanning.openai.assistants.ModifyAssistantRequest; 34 | import com.theokanning.openai.audio.CreateSpeechRequest; 35 | import com.theokanning.openai.audio.CreateTranscriptionRequest; 36 | import com.theokanning.openai.completion.chat.ChatCompletionChoice; 37 | import com.theokanning.openai.completion.chat.ChatCompletionRequest; 38 | import com.theokanning.openai.completion.chat.ChatCompletionResult; 39 | import com.theokanning.openai.completion.chat.ChatMessage; 40 | import com.theokanning.openai.image.CreateImageRequest; 41 | import com.theokanning.openai.image.CreateImageVariationRequest; 42 | import com.theokanning.openai.messages.Message; 43 | import com.theokanning.openai.messages.MessageRequest; 44 | import com.theokanning.openai.runs.Run; 45 | import com.theokanning.openai.runs.RunCreateRequest; 46 | import com.theokanning.openai.service.OpenAiService; 47 | import com.theokanning.openai.threads.ThreadRequest; 48 | 49 | import okhttp3.OkHttpClient; 50 | import okhttp3.Request; 51 | import okhttp3.Response; 52 | import okhttp3.ResponseBody; 53 | import serpapi.GoogleSearch; 54 | import serpapi.SerpApiSearchException; 55 | 56 | @Service 57 | public class OpenAiMessageCreation { 58 | 59 | Logger logger = LoggerFactory.getLogger(OpenAiMessageCreation.class); 60 | 61 | @Autowired 62 | OpenAiService openAiService; 63 | 64 | @Autowired 65 | OpenAiModalRepository aiModalRepository; 66 | 67 | 68 | 69 | static String token = ""; 70 | private static final String API_KEY = ""; 71 | private static final String BASE_URL = "https://www.alphavantage.co/query"; 72 | 73 | public String processGPT4Request(String input, String userId, String assistantId, boolean isStopRequired, 74 | List<String> fileUrls) { 75 | 76 | ThreadRequest threadRequest = ThreadRequest.builder().build(); 77 | com.theokanning.openai.threads.Thread thread = openAiService.createThread(threadRequest); 78 | com.theokanning.openai.file.File file = null; 79 | List<String> fileList = new ArrayList<>(); 80 | if (fileUrls != null && !fileUrls.isEmpty()) { 81 | for (String fileUrl : fileUrls) { 82 | try { 83 | String filePath = downloadFile(fileUrl); 84 | FileType fileType = FileTypeChecker.getFileType(filePath); 85 | switch (fileType) { 86 | case IMAGE: 87 | if(!Constants.Laptop_Check_Assistant_ID.equals(assistantId)) 88 | assistantId = ""; 89 | file = openAiService.uploadFile("assistants", filePath); 90 | break; 91 | case VIDEO: 92 | String path = ""; 93 | VideoToAudioConverter.convertMp4ToMp3(filePath, path); 94 | input = CreateSpeeach2Text("", null, path); 95 | file = openAiService.uploadFile("assistants", filePath); 96 | break; 97 | case AUDIO: 98 | String path2 = ""; 99 | VideoToAudioConverter.convertMp4ToMp3(filePath, path2); 100 | input = CreateSpeeach2Text("", null, path2); 101 | file = openAiService.uploadFile("assistants", filePath); 102 | case UNKNOWN: 103 | file = openAiService.uploadFile("assistants", filePath); 104 | break; 105 | } 106 | 107 | if (file != null) 108 | fileList.add(file.getId()); 109 | } catch (Exception e) { 110 | e.printStackTrace(); 111 | } 112 | } 113 | } 114 | 115 | MessageRequest messageRequest = MessageRequest.builder().content(input).fileIds(fileList).build(); 116 | 117 | openAiService.createMessage(thread.getId(), messageRequest); 118 | 119 | RunCreateRequest runCreateRequest = RunCreateRequest.builder().assistantId(assistantId).model("gpt-4-turbo").build(); 120 | 121 | Run run = openAiService.createRun(thread.getId(), runCreateRequest); 122 | 123 | Run retrievedRun; 124 | do { 125 | retrievedRun = openAiService.retrieveRun(thread.getId(), run.getId()); 126 | } while (!(retrievedRun.getStatus().equals("completed")) && !(retrievedRun.getStatus().equals("failed"))); 127 | 128 | OpenAiResponse<Message> response = openAiService.listMessages(thread.getId()); 129 | 130 | List<Message> messages = response.getData(); 131 | 132 | return messages.get(0).getContent().get(0).getText().getValue(); 133 | 134 | } 135 | 136 | public String CreateTextToImage(String prompt) throws IOException { 137 | CreateImageRequest request = CreateImageRequest.builder().model("dall-e-3").prompt(prompt).build(); 138 | return downloadFileOpenAi(openAiService.createImage(request).getData().get(0).getUrl()); 139 | } 140 | 141 | public String CreateImageVariation(String fileUrl) throws IOException { 142 | String path = downloadFile(fileUrl); 143 | CreateImageVariationRequest request = CreateImageVariationRequest.builder().size("1024x1024") 144 | .responseFormat("url").build(); 145 | return downloadFileOpenAi(openAiService.createImageVariation(request, path).getData().get(0).getUrl()); 146 | } 147 | 148 | public String updateAssistant(String sector) { 149 | String template = "You are a Slack bot named Wicebot who has tremendous knowledge on {{placeholder}} and only answer questions about {{placeholder}}."; 150 | String result = template.replace("{{placeholder}}", sector.replace("_", " ")); 151 | ModifyAssistantRequest modifyAssistantRequest = ModifyAssistantRequest.builder().instructions(result).build(); 152 | openAiService.modifyAssistant(Constants.Mention_Assistant_ID, modifyAssistantRequest); 153 | return ""; 154 | } 155 | 156 | public String CreateText2Speech(String input) throws IOException { 157 | CreateSpeechRequest request = CreateSpeechRequest.builder().model("tts-1").voice("onyx").input(input) 158 | .responseFormat("mp3").build(); 159 | // Execute the request 160 | ResponseBody response = openAiService.createSpeech(request); 161 | 162 | // Get the input stream of the response 163 | InputStream inputStream = response.byteStream(); 164 | // Get the file name from the URL 165 | String fileName = Math.random() + ".mp3"; 166 | Path localPath = Paths.get(".", fileName); 167 | 168 | // Create directories if they do not exist 169 | Files.createDirectories(localPath.getParent()); 170 | // Write the input stream to a file 171 | try (FileOutputStream fileOutputStream = new FileOutputStream(localPath.toString())) { 172 | byte[] buffer = new byte[4096]; 173 | int bytesRead; 174 | while ((bytesRead = inputStream.read(buffer)) != -1) { 175 | fileOutputStream.write(buffer, 0, bytesRead); 176 | } 177 | } 178 | return localPath.toAbsolutePath().normalize().toString(); 179 | 180 | } 181 | 182 | public String CreateSpeeach2Text(String input, String fileUrl, String filePath) throws IOException { 183 | 184 | String path = filePath ; 185 | if(filePath == null || filePath.isEmpty()) 186 | path = downloadFile(fileUrl); 187 | CreateTranscriptionRequest request = CreateTranscriptionRequest.builder().model("whisper-1").prompt(input) 188 | .responseFormat("text").build(); 189 | return openAiService.createTranscription(request, path).getText(); 190 | } 191 | 192 | public List<SlideData> pptDetails(String input) throws JsonMappingException, JsonProcessingException { 193 | 194 | String jsonResponse = processGPT4Request(input, "", "",false, null); 195 | // Extract JSON from the response (assuming response is formatted with a preamble) 196 | int jsonStart = jsonResponse.indexOf("["); 197 | int jsonEnd = jsonResponse.lastIndexOf("]") + 1; 198 | String jsonContent = jsonResponse.substring(jsonStart, jsonEnd); 199 | 200 | // Parse the JSON content to a list of SlideData objects 201 | ObjectMapper objectMapper = new ObjectMapper(); 202 | List<SlideData> slides = objectMapper.readValue(jsonContent, objectMapper.getTypeFactory().constructCollectionType(List.class, SlideData.class)); 203 | return slides; 204 | } 205 | 206 | public String downloadFile(String fileUrl) throws IOException { 207 | OkHttpClient client = new OkHttpClient(); 208 | 209 | // Build the request with authorization header 210 | Request request = new Request.Builder().url(fileUrl).addHeader("Authorization", "Bearer " + token).build(); 211 | 212 | // Execute the request 213 | try (Response response = client.newCall(request).execute()) { 214 | if (!response.isSuccessful()) { 215 | throw new IOException("Unexpected code " + response); 216 | } 217 | 218 | // Get the input stream of the response 219 | InputStream inputStream = response.body().byteStream(); 220 | // Get the file name from the URL 221 | String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1); 222 | Path localPath = Paths.get(".", fileName); 223 | 224 | // Create directories if they do not exist 225 | Files.createDirectories(localPath.getParent()); 226 | // Write the input stream to a file 227 | try (FileOutputStream fileOutputStream = new FileOutputStream(localPath.toString())) { 228 | byte[] buffer = new byte[4096]; 229 | int bytesRead; 230 | while ((bytesRead = inputStream.read(buffer)) != -1) { 231 | fileOutputStream.write(buffer, 0, bytesRead); 232 | } 233 | return localPath.toAbsolutePath().normalize().toString(); 234 | } 235 | } 236 | } 237 | 238 | public String downloadFileOpenAi(String fileUrl) throws IOException { 239 | OkHttpClient client = new OkHttpClient(); 240 | 241 | // Build the request with authorization header 242 | Request request = new Request.Builder().url(fileUrl).build(); 243 | 244 | // Execute the request 245 | try (Response response = client.newCall(request).execute()) { 246 | if (!response.isSuccessful()) { 247 | throw new IOException("Unexpected code " + response); 248 | } 249 | 250 | // Get the input stream of the response 251 | InputStream inputStream = response.body().byteStream(); 252 | // Get the file name from the URL 253 | String fileName = Math.random() + ".jpeg"; 254 | Path localPath = Paths.get(".", fileName); 255 | 256 | // Create directories if they do not exist 257 | Files.createDirectories(localPath.getParent()); 258 | // Write the input stream to a file 259 | try (FileOutputStream fileOutputStream = new FileOutputStream(localPath.toString())) { 260 | byte[] buffer = new byte[4096]; 261 | int bytesRead; 262 | while ((bytesRead = inputStream.read(buffer)) != -1) { 263 | fileOutputStream.write(buffer, 0, bytesRead); 264 | } 265 | return localPath.toAbsolutePath().normalize().toString(); 266 | } 267 | } 268 | } 269 | 270 | public String liveSearch(String query) { 271 | Map<String, String> parameter = new HashMap<>(); 272 | 273 | parameter.put("q", query); 274 | parameter.put("location", "Austin, Texas, United States"); 275 | parameter.put("hl", "en"); 276 | parameter.put("gl", "us"); 277 | parameter.put("google_domain", "google.com"); 278 | parameter.put("api_key", ""); 279 | 280 | GoogleSearch search = new GoogleSearch(parameter); 281 | 282 | try { 283 | JsonObject results = search.getJson(); 284 | return results.toString(); 285 | } catch (SerpApiSearchException ex) { 286 | System.out.println(ex.toString()); 287 | } 288 | return ""; 289 | } 290 | 291 | public String getStockData(String symbol) throws IOException { 292 | OkHttpClient client = new OkHttpClient(); 293 | 294 | String url = BASE_URL + "?function=TIME_SERIES_INTRADAY&symbol=" + symbol + "&interval=5min&apikey=" + API_KEY; 295 | 296 | Request request = new Request.Builder().url(url).build(); 297 | 298 | try (Response response = client.newCall(request).execute()) { 299 | if (!response.isSuccessful()) 300 | throw new IOException("Unexpected code " + response); 301 | 302 | String responseBody = response.body().string(); 303 | return JsonParser.parseString(responseBody).getAsJsonObject().toString(); 304 | } 305 | } 306 | 307 | public String getStockAnalysis(String symbol) throws IOException { 308 | OkHttpClient client = new OkHttpClient(); 309 | String url = BASE_URL + "?function=NEWS_SENTIMENT&tickers=" + symbol + "&interval=5min&apikey=" + API_KEY; 310 | 311 | Request request = new Request.Builder().url(url).build(); 312 | 313 | try (Response response = client.newCall(request).execute()) { 314 | if (!response.isSuccessful()) 315 | throw new IOException("Unexpected code " + response); 316 | 317 | String responseBody = response.body().string(); 318 | System.out.println(responseBody); 319 | return JsonParser.parseString(responseBody).getAsJsonObject().toString(); 320 | } 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /src/main/java/com/openai/slack/services/SlackMessageServices.java: -------------------------------------------------------------------------------- 1 | package com.openai.slack.services; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.http.HttpEntity; 15 | import org.springframework.http.HttpHeaders; 16 | import org.springframework.http.HttpMethod; 17 | import org.springframework.http.MediaType; 18 | import org.springframework.http.ResponseEntity; 19 | import org.springframework.stereotype.Service; 20 | import org.springframework.web.client.RestTemplate; 21 | 22 | import com.fasterxml.jackson.core.JsonProcessingException; 23 | import com.fasterxml.jackson.databind.JsonNode; 24 | import com.fasterxml.jackson.databind.ObjectMapper; 25 | import com.openai.repository.SlackViewRepository; 26 | import com.slack.api.Slack; 27 | import com.slack.api.methods.MethodsClient; 28 | import com.slack.api.methods.SlackApiException; 29 | import com.slack.api.methods.request.conversations.ConversationsCreateRequest; 30 | import com.slack.api.methods.request.conversations.ConversationsHistoryRequest; 31 | import com.slack.api.methods.request.conversations.ConversationsListRequest; 32 | import com.slack.api.methods.request.conversations.ConversationsRepliesRequest; 33 | import com.slack.api.methods.request.files.FilesUploadV2Request; 34 | import com.slack.api.methods.response.chat.ChatGetPermalinkResponse; 35 | import com.slack.api.methods.response.chat.ChatPostEphemeralResponse; 36 | import com.slack.api.methods.response.chat.ChatPostMessageResponse; 37 | import com.slack.api.methods.response.conversations.ConversationsCreateResponse; 38 | import com.slack.api.methods.response.conversations.ConversationsHistoryResponse; 39 | import com.slack.api.methods.response.conversations.ConversationsListResponse; 40 | import com.slack.api.methods.response.conversations.ConversationsRepliesResponse; 41 | import com.slack.api.methods.response.files.FilesUploadV2Response; 42 | import com.slack.api.model.Conversation; 43 | import com.slack.api.model.ConversationType; 44 | import com.slack.api.model.block.LayoutBlock; 45 | import com.slack.api.model.block.SectionBlock; 46 | import com.slack.api.model.block.composition.MarkdownTextObject; 47 | import com.theokanning.openai.completion.chat.ChatMessage; 48 | 49 | @Service 50 | public class SlackMessageServices { 51 | Logger logger = LoggerFactory.getLogger(SlackMessageServices.class); 52 | 53 | @Autowired 54 | RestTemplate restTemplate; 55 | 56 | @Autowired 57 | SlackViewRepository slackViewRepository; 58 | 59 | public void replyMessage(String requestType, String userId, String channelId, String ts, 60 | MethodsClient methodsClient, String output, String token) { 61 | logger.info("replyMessage started with channelId {} ts {} output {}", channelId, ts, output); 62 | try { 63 | ChatPostMessageResponse chatPostMessageResponse = methodsClient 64 | .chatPostMessage(r -> r.token(token).channel(channelId).threadTs(ts).text(output)); 65 | if (chatPostMessageResponse.isOk()) { 66 | logger.info("replyMessage completed"); 67 | } 68 | } catch (Exception e) { 69 | logger.error("replyMessage throw exception : " + e.toString()); 70 | } 71 | } 72 | 73 | public void postMessage(String requestType, String userId, String channelId, MethodsClient methodsClient, 74 | String output, String token) { 75 | logger.info("replyMessage started with channelId {} output {}", channelId, output); 76 | try { 77 | List<LayoutBlock> blocks = createBlocks(output); 78 | ChatPostMessageResponse chatPostMessageResponse = methodsClient 79 | .chatPostMessage(r -> r.token(token).channel(channelId).blocks(blocks)); 80 | 81 | if (chatPostMessageResponse.isOk()) { 82 | logger.info("replyMessage completed"); 83 | } 84 | } catch (Exception e) { 85 | logger.error("replyMessage threw exception: " + e.toString()); 86 | } 87 | } 88 | 89 | private List<LayoutBlock> createBlocks(String output) { 90 | return Arrays.asList(SectionBlock.builder().text(MarkdownTextObject.builder().text(output).build()).build()); 91 | } 92 | 93 | public String getDmChannelId(MethodsClient client, String userId, String token) 94 | throws IOException, SlackApiException { 95 | List<ConversationType> types = Arrays.asList(ConversationType.IM); 96 | 97 | ConversationsListResponse response = client 98 | .conversationsList(ConversationsListRequest.builder().token(token).types(types).build()); 99 | 100 | if (response.isOk() && response.getChannels() != null) { 101 | Optional<Conversation> dmChannel = response.getChannels().stream() 102 | .filter(channel -> channel.getUser().equals(userId)).findFirst(); 103 | 104 | return dmChannel.map(Conversation::getId).orElse(null); 105 | } 106 | return ""; 107 | } 108 | 109 | public void postFile(String title, String prompt, String channelId, MethodsClient client, String path, 110 | String token) { 111 | File file = new File(path); 112 | 113 | try { 114 | FilesUploadV2Request request = FilesUploadV2Request.builder().token(token).channel(channelId).file(file) 115 | .filename(file.getName()).title(title).initialComment(prompt).build(); 116 | 117 | FilesUploadV2Response response = client.filesUploadV2(request); 118 | 119 | if (response.isOk()) { 120 | System.out.println("File uploaded successfully."); 121 | } else { 122 | System.err.println("Error uploading file: " + response.getError()); 123 | } 124 | } catch (IOException | SlackApiException e) { 125 | e.printStackTrace(); 126 | } 127 | } 128 | 129 | public void postEphemeralMessage(String requestType, String channelId, MethodsClient methodsClient, String output, 130 | String userId, String token) { 131 | logger.info("replyMessage started with channelId {} output {}", channelId, output); 132 | try { 133 | ChatPostEphemeralResponse chatPostMessageResponse = methodsClient 134 | .chatPostEphemeral(r -> r.token(token).channel(channelId).user(userId).text(output)); 135 | if (chatPostMessageResponse.isOk()) { 136 | logger.info("replyMessage completed"); 137 | } 138 | } catch (Exception e) { 139 | logger.error("replyMessage throw exception : " + e.toString()); 140 | } 141 | } 142 | 143 | public void postEphemeralBlock(String requestType, String channelId, MethodsClient methodsClient, String output, 144 | String userId, String token) { 145 | logger.info("replyMessage started with channelIs {} output {}", channelId, output); 146 | ObjectMapper mapper = new ObjectMapper(); 147 | JsonNode actualObj = null; 148 | try { 149 | actualObj = mapper.readTree(output); 150 | } catch (JsonProcessingException e1) { 151 | // TODO Auto-generated catch block 152 | e1.printStackTrace(); 153 | } 154 | String blocks = actualObj.get("blocks").toString(); 155 | try { 156 | ChatPostEphemeralResponse chatPostEphemeralResponse = methodsClient 157 | .chatPostEphemeral(r -> r.token(token).channel(channelId).user(userId).blocksAsString(blocks)); 158 | if (chatPostEphemeralResponse.isOk()) { 159 | logger.info("replyMessage completed"); 160 | } 161 | } catch (Exception e) { 162 | logger.error("replyMessage throw exception : " + e.toString()); 163 | } 164 | } 165 | 166 | public void replyEphemeralMessage(String requestType, String channelId, String ts, MethodsClient methodsClient, 167 | String output, String userId, String token) { 168 | logger.info("replyMessage started with channelId {} ts {} output {}", channelId, ts, output); 169 | try { 170 | ChatPostEphemeralResponse chatPostEphemeralResponse = methodsClient 171 | .chatPostEphemeral(r -> r.token(token).channel(channelId).threadTs(ts).text(output).user(userId)); 172 | if (chatPostEphemeralResponse.isOk()) { 173 | logger.info("replyMessage completed"); 174 | } 175 | } catch (Exception e) { 176 | logger.error("replyMessage throw exception : " + e.toString()); 177 | } 178 | } 179 | 180 | public void dmMessage(String userId, MethodsClient methodsClient, String output, String token) { 181 | logger.info("dmMessage start: userId {}", userId); 182 | try { 183 | methodsClient.chatPostMessage(r -> r.token(token).channel(userId).text(output)); 184 | } catch (Exception e) { 185 | logger.error("dmMessage throws exception : " + e.toString()); 186 | } 187 | logger.info("dmMessage end"); 188 | } 189 | 190 | public String getPermalink(String channelId, String ts, MethodsClient methodsClient, String token) { 191 | logger.info("getPermalink started with channelId {} ts {}", channelId, ts); 192 | ChatGetPermalinkResponse response = null; 193 | try { 194 | response = methodsClient.chatGetPermalink(r -> r.token(token).channel(channelId).messageTs(ts)); 195 | return response.getPermalink(); 196 | } catch (Exception e) { 197 | logger.error("dmMessage throws exception : " + e.toString()); 198 | } 199 | return ""; 200 | } 201 | 202 | public List<ChatMessage> getDmMessages(String channelId, String ts, MethodsClient methodsClient, String botId, 203 | String token) { 204 | logger.info("getDmMessages started with ts {} , conversationId {} botId {}", ts, channelId, botId); 205 | List<ChatMessage> chat = new ArrayList<>(); 206 | ConversationsHistoryRequest historyRequest = ConversationsHistoryRequest.builder().token(token) 207 | .channel(channelId).limit(10).build(); 208 | ConversationsHistoryResponse historyResponse = null; 209 | try { 210 | historyResponse = methodsClient.conversationsHistory(historyRequest); 211 | List<com.slack.api.model.Message> messages = historyResponse.getMessages(); 212 | Collections.reverse(messages); 213 | if (messages != null) { 214 | ChatMessage chatMessage = null; 215 | for (com.slack.api.model.Message message : messages) { 216 | chatMessage = new ChatMessage(); 217 | chatMessage.setRole(message.getBotId() == null ? "user" : "assistant"); 218 | chatMessage.setContent(message.getText()); 219 | chat.add(chatMessage); 220 | } 221 | } 222 | logger.info("getDmMessages completed with ts {} , channelId {} botId {}", ts, channelId, botId); 223 | } catch (Exception e) { 224 | logger.error("getDmMessages throws exception : " + e.toString()); 225 | } 226 | return chat; 227 | } 228 | 229 | public List<com.slack.api.model.Message> getThreadMessages(String channelId, String ts, MethodsClient methodsClient, 230 | String input, String token) { 231 | logger.info("getThreadMessages started with ts {} , conversationId {} input {}", ts, channelId, input); 232 | ConversationsRepliesRequest builder = ConversationsRepliesRequest.builder().token(token).channel(channelId) 233 | .ts(ts).build(); 234 | ConversationsRepliesResponse response = null; 235 | try { 236 | response = methodsClient.conversationsReplies(builder); 237 | return response.getMessages(); 238 | } catch (Exception e) { 239 | logger.error("getThreadMessages throws exception : " + e.toString()); 240 | } 241 | return null; 242 | } 243 | 244 | public com.slack.api.model.Message getMessageByTimestamp(String channelId, String ts, MethodsClient methodsClient, 245 | String token) { 246 | logger.info("getMessageByTimestamp started with ts {} , channelId {}", ts, channelId); 247 | 248 | ConversationsHistoryRequest request = ConversationsHistoryRequest.builder().token(token).channel(channelId) 249 | .inclusive(true).latest(ts).limit(1).build(); 250 | 251 | ConversationsHistoryResponse response; 252 | try { 253 | response = methodsClient.conversationsHistory(request); 254 | if (response.isOk() && response.getMessages() != null && !response.getMessages().isEmpty()) { 255 | return response.getMessages().get(0); 256 | } else { 257 | logger.error("Error retrieving message: " + response.getError()); 258 | } 259 | } catch (IOException | SlackApiException e) { 260 | logger.error("getMessageByTimestamp throws exception: " + e.toString()); 261 | } 262 | 263 | return null; 264 | } 265 | 266 | public List<com.slack.api.model.Message> getMessagesWithTimeLimit(String channelId, String oldest, 267 | MethodsClient methodsClient, int limit, String token) { 268 | logger.info("getMessagesWithTimeLimit started with channelId {} , oldest {} limit {}", channelId, oldest, 269 | limit); 270 | ConversationsHistoryRequest historyRequest = ConversationsHistoryRequest.builder().token(token) 271 | .channel(channelId).oldest(oldest).limit(limit).build(); 272 | ConversationsHistoryResponse historyResponse = null; 273 | try { 274 | historyResponse = methodsClient.conversationsHistory(historyRequest); 275 | return historyResponse.getMessages(); 276 | } catch (Exception e) { 277 | logger.error("getThreadMessages throws exception : " + e.toString()); 278 | } 279 | return null; 280 | } 281 | 282 | public void createChannel(MethodsClient client, String channelName, String token) 283 | throws IOException, SlackApiException { 284 | Slack slack = Slack.getInstance(); 285 | 286 | ConversationsCreateRequest request = ConversationsCreateRequest.builder().token(token).name(channelName) 287 | .isPrivate(false) // Set to true if you want to create a private channel 288 | .build(); 289 | 290 | ConversationsCreateResponse response = slack.methods().conversationsCreate(request); 291 | 292 | if (response.isOk()) { 293 | System.out.println("Channel created successfully: " + response.getChannel().getId()); 294 | } else { 295 | System.err.println("Error creating channel: " + response.getError()); 296 | } 297 | } 298 | 299 | // Not in use 300 | public String xyz(String responseUrl, String output, String token) { 301 | HttpHeaders headers = new HttpHeaders(); 302 | headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 303 | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); 304 | String info = "{\"response_type\": \"in_channel\", \"replace_original\": \"false\", \"text\" : \" yo\" }"; 305 | 306 | headers.setBearerAuth(token); 307 | HttpEntity<String> request = new HttpEntity<>(info, headers); 308 | ResponseEntity<String> result = restTemplate.exchange(responseUrl, HttpMethod.POST, request, String.class); 309 | return ""; 310 | } 311 | 312 | } 313 | --------------------------------------------------------------------------------