Don't want to read so many words? Jump to Demo.
This is personal assistant with both dialogue and command interface.
Strictly speaking, DCDos is a combination of framework and application. In the near future, I will release part of the framework separately as spring-boot-starter to make its functions easier to use.
Disk Control And Decision Operating System.
When working and living, I very much hope that I can have a personal assistant to help me organize notes and to-dos. Although Notion is powerful, it is still difficult to operate this complex and huge machine efficiently during meetings or busy times.
DCDos will act as a controller between the brain and the notes, just like the hard disk controller processes data from the disk to the memory.
- Project status: Active, major side project
- Not currently recommended for use: Before I refactored the code of the framework into spring-boot-starter, there are many functions tailored for myself, and most of these functions cannot be used directly in other environments
- AdoptOpenJDK 11 with HotSpot JVM
- Software Development Kit Manager: SDKMAN!
- Build System: Gradle 6.8.3
- Database: MariaDB
- CI/CD:
- gitlab-ci.yml - This GitHub repository is actually a mirror from my GitLab
- Dockerfile - The gitlab-ci will package the application into an image
- Spring Boot 2.4.5
- Spring Boot Starter Web
- Spring Boot Starter Security
- Spring Boot Starter Data JPA
- JSch - A pure Java implementation of SSH2. Used to control the unofficial API server
- Apache Commons Validator - A powerful and customized data verification framework. Used to verify whether the request sent to the API server conforms to the format
- Picocli - Used to build rich command line applications then connect to communication software
- TelegramBots - Java library to create bots using Telegram Bots API
- Project Lombok - Getter, Setter, ToString, AllArgsConstructor and more..
Program doesn’t know where the message it sends will go, also doesn’t know where the message it receives comes from. All operations are dependent on the abstract class AbstractSession
.
So as long as any class extends AbstractSession
and implements the above method, then it can assume the responsibility of message transmission like TelegramSession
.
git clone https://github.com/YukinaMochizuki/DCDos.git
./gradlew assemble
After gradlew assemble
docker build --tag dcdos .
Put it in src/main/resources
, or in /app/config
in the container.
dcdos.debug=false
telegram.username=Your_Bot_Username
telegram.token=12345:ABCDEF
telegram.permission.master=123456789
notion.api.baseurl=http://your-dcdos-notion-api-url
You may need to modify these commands for your own environment.
docker pull registry.lan.yukina.tw/shuvi/dcdos:latest
docker start dcdos-notion-api
docker run -d \
-v /path/DCDos/config:/app/config \
-v /path/DCDos/ssh:/app/ssh \
--link dcdos-notion-api \
--name dcdos \
registry.lan.yukina.tw/shuvi/dcdos:latest
In theory, most functions of Picocli are supported. The implementation of the execution command is in the TelegramManager
. You can adjust according to your needs.
@Component
public class TelegramManager {
public void messageInput(Update update){
...other code
// find all of the command, assistantCommands is initialized at constructor injection
Optional<AbstractAssistantCommand> assistantCommandOptional =
assistantCommands.stream()
.filter(command -> parameter.get(0).equals(command.getCommandName())).findAny();
...other code
// execute command
if(assistantCommandOptional.isPresent()) {
new CommandLine(assistantCommand).setOut(writer).setErr(writer)
.setCaseInsensitiveEnumValuesAllowed(true)
.setUsageHelpWidth(100).execute(args);
}
}
}
So you can simply extend AbstractAssistantCommand
and implements Runnable
to create a command.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import picocli.CommandLine.Command;
import tw.yukina.dcdos.command.AbstractAssistantCommand;
import tw.yukina.dcdos.constants.Role;
import tw.yukina.dcdos.manager.telegram.TelegramUserInfoManager;
@Component
@Command(name = "start", description = "Say Hello")
public class Start extends AbstractAssistantCommand implements Runnable {
@Override
public void run() {
sendMessageToChatId("Your telegram user id is " + getChatId());
sendMessageToChatId("If you want to get some help, please send /help for me");
}
@Override
public String getCommandName() {
return "start";
}
@Override
public Role[] getPermissions() {
return new Role[]{Role.GUEST};
}
}
Just like creating a command, you can create a program by extends AbstractProgramCode
.
package tw.yukina.dcdos.program.test;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import tw.yukina.dcdos.program.AbstractProgramCode;
import tw.yukina.dcdos.util.ReplyKeyboard;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestProgram extends AbstractProgramCode {
@Override
public String[] getKeyword() {
return new String[]{"測試軟體1"};
}
@Override
public void run() {
stdout("HelloWorld");
stdout(getInput());
stdout("HelloWorld after HelloWorld2");
}
}
Notice getInput()
is synchronous, so blocking occurs in stdout(programController.getInput());
.
Only need to provide the id when sending the message, and then you can use that id to edit the message.
@Override
public void run() {
stdout("testMessage", "uuid1");
stdout("testMessage2", "uuid2");
try {
Thread.sleep(1000);
stdout("after");
updateStdout("after edit", "uuid1");
updateStdout("after edit2", "uuid2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}