From 9f567316afa5e5525d120dc167773634d58b602f Mon Sep 17 00:00:00 2001 From: Levi Miller Date: Mon, 15 Feb 2021 19:43:57 -0800 Subject: [PATCH] Release 0.1.0 (#30) - Handle incoming attachments --- README.md | 6 +- pom.xml | 4 +- .../smsbridge/config/AppConfig.java | 6 ++ .../data/dto/TwilioSmsDtoConverter.java | 88 +++++++++++++++++++ .../smsbridge/rest/TwilioController.java | 9 +- .../smsbridge/rest/impl/TwilioApi.java | 3 + .../smsbridge/service/AttachmentService.java | 20 +++++ .../impl/matrix/MatrixChatService.java | 27 ++++-- .../attachment/AbstractAttachmentService.java | 80 +++++++++++++++++ .../attachment/AudioAttachmentService.java | 36 ++++++++ .../CompositeAttachmentService.java | 48 ++++++++++ .../attachment/DefaultAttachmentService.java | 41 +++++++++ .../attachment/FileAttachmentService.java | 36 ++++++++ .../attachment/ImageAttachmentService.java | 38 ++++++++ .../attachment/VideoAttachmentService.java | 39 ++++++++ 15 files changed, 468 insertions(+), 13 deletions(-) create mode 100644 src/main/java/ca/levimiller/smsbridge/data/dto/TwilioSmsDtoConverter.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/AttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AbstractAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AudioAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/CompositeAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/DefaultAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/FileAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/ImageAttachmentService.java create mode 100644 src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/VideoAttachmentService.java diff --git a/README.md b/README.md index 242acea..3875133 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # sms-bridge -Matrix Sms Bridge +Matrix SMS Bridge -Bridges the sms service Twilio to matrix, but could be extended to other services/chat servers +Bridges SMS to matrix. Run App @@ -52,7 +52,7 @@ app_service_config_files: - "/path/to/appservice/registration.yaml" ``` -### Sms Bridge Database Setup: +### SMS Bridge Database Setup: Create a database called sms_bridge (with appropriate users/roles if required) E.g., in postgres: ``` diff --git a/pom.xml b/pom.xml index e46fc23..8152ff5 100644 --- a/pom.xml +++ b/pom.xml @@ -11,13 +11,13 @@ ca.levimiller sms-bridge - 0.0.8-SNAPSHOT + 0.1.0 sms-bridge Sms Bridge for Matrix 11 - 1.3.1.Final + 1.4.1.Final 1.18.10 2.30 diff --git a/src/main/java/ca/levimiller/smsbridge/config/AppConfig.java b/src/main/java/ca/levimiller/smsbridge/config/AppConfig.java index 204443d..ce689eb 100644 --- a/src/main/java/ca/levimiller/smsbridge/config/AppConfig.java +++ b/src/main/java/ca/levimiller/smsbridge/config/AppConfig.java @@ -7,6 +7,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.retry.annotation.EnableRetry; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -40,4 +41,9 @@ public CommonsRequestLoggingFilter requestLoggingFilter() { public ObjectMapper mapper() { return new JacksonContextResolver().getContext(null); } + + @Bean + public FormHttpMessageConverter formHttpMessageConverter() { + return new FormHttpMessageConverter(); + } } diff --git a/src/main/java/ca/levimiller/smsbridge/data/dto/TwilioSmsDtoConverter.java b/src/main/java/ca/levimiller/smsbridge/data/dto/TwilioSmsDtoConverter.java new file mode 100644 index 0000000..ea676b2 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/data/dto/TwilioSmsDtoConverter.java @@ -0,0 +1,88 @@ +package ca.levimiller.smsbridge.data.dto; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.FormHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.stereotype.Component; + +@Component +public class TwilioSmsDtoConverter extends AbstractHttpMessageConverter { + private final FormHttpMessageConverter formHttpMessageConverter; + + @Inject + public TwilioSmsDtoConverter(FormHttpMessageConverter formHttpMessageConverter) { + super(new MediaType("application","x-www-form-urlencoded", StandardCharsets.UTF_8)); + this.formHttpMessageConverter = formHttpMessageConverter; + } + + @Override + protected boolean supports(Class clazz) { + return TwilioSmsDto.class == clazz; + } + + @Override + protected TwilioSmsDto readInternal(Class clazz, + HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { + Map vals = formHttpMessageConverter.read(null, inputMessage).toSingleValueMap(); + + Integer numMedia = getInteger(vals, "NumMedia"); + + return TwilioSmsDto.builder() + .messageSid(vals.get("MessageSid")) + .messageSid(vals.get("MessageSid")) + .accountSid(vals.get("AccountSid")) + .from(vals.get("From")) + .to(vals.get("To")) + .body(vals.get("Body")) + .numSegments(getInteger(vals, "NumSegments")) + .numMedia(numMedia) + .mediaContentTypes(getList(vals, "MediaContentType", numMedia)) + .mediaUrls(getList(vals, "MediaUrl", numMedia)) + .messagingServiceSid(vals.get("MessagingServiceSid")) + .fromCity(vals.get("FromCity")) + .fromState(vals.get("FromState")) + .fromZip(vals.get("FromZip")) + .fromCountry(vals.get("FromCountry")) + .toCity(vals.get("ToCity")) + .toState(vals.get("ToState")) + .toZip(vals.get("ToZip")) + .toCountry(vals.get("ToCountry")) + .build(); + } + + @Override + protected void writeInternal(TwilioSmsDto twilioSmsDto, HttpOutputMessage httpOutputMessage) + throws HttpMessageNotWritableException { + // TwilioSmsDto is currently only for incoming requests. + } + + private Integer getInteger(Map vals, String key) { + try { + return Integer.parseInt(vals.get(key)); + } catch (NumberFormatException e) { + return null; + } + } + + private List getList(Map vals, String key, Integer size) { + if (size == null) { + return Collections.emptyList(); + } + List result = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + result.add(vals.get(key + i)); + } + return result; + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/rest/TwilioController.java b/src/main/java/ca/levimiller/smsbridge/rest/TwilioController.java index acbe375..c653036 100644 --- a/src/main/java/ca/levimiller/smsbridge/rest/TwilioController.java +++ b/src/main/java/ca/levimiller/smsbridge/rest/TwilioController.java @@ -6,7 +6,9 @@ import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import javax.validation.Valid; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -15,10 +17,13 @@ @Api(value = "/twilio", tags = "Api for requests from Twilio") public interface TwilioController { - @PostMapping("/sms") + @PostMapping( + value = "/sms", + consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE + ) @ApiOperation("Create an sms message") @ApiResponses(value = { @ApiResponse(code = 201, message = "Created", response = String.class), @ApiResponse(code = 400, message = "Request not valid")}) - void createSms(@Valid TwilioSmsDto sms); + void createSms(@Valid @RequestBody TwilioSmsDto sms); } diff --git a/src/main/java/ca/levimiller/smsbridge/rest/impl/TwilioApi.java b/src/main/java/ca/levimiller/smsbridge/rest/impl/TwilioApi.java index 7350727..5b91a30 100644 --- a/src/main/java/ca/levimiller/smsbridge/rest/impl/TwilioApi.java +++ b/src/main/java/ca/levimiller/smsbridge/rest/impl/TwilioApi.java @@ -34,6 +34,9 @@ public TwilioApi( public void createSms(TwilioSmsDto sms) { log.debug("Received sms: {}", sms); Message message = messageTransformer.transform(sms); + if (message.getMedia() != null) { + message.getMedia().forEach(media -> media.setMessage(message)); + } messageService.save(message); chatService.sendMessage(message); } diff --git a/src/main/java/ca/levimiller/smsbridge/service/AttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/AttachmentService.java new file mode 100644 index 0000000..69e6c17 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/AttachmentService.java @@ -0,0 +1,20 @@ +package ca.levimiller.smsbridge.service; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; + +public interface AttachmentService { + + /** + * Sends the given attachment. + * @param attachment - attachment to send + */ + void sendAttachment(ChatUser user, String roomId, Media attachment); + + /** + * Returns true if the given content type is supported by the attachment service. + * @param contentType - content type to check + * @return - true if supported + */ + boolean supportsType(String contentType); +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/MatrixChatService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/MatrixChatService.java index 475031f..cf1f689 100644 --- a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/MatrixChatService.java +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/MatrixChatService.java @@ -4,11 +4,13 @@ import ca.levimiller.smsbridge.data.model.ChatUser; import ca.levimiller.smsbridge.data.model.Message; import ca.levimiller.smsbridge.error.NotFoundException; +import ca.levimiller.smsbridge.service.AttachmentService; import ca.levimiller.smsbridge.service.ChatService; import ca.levimiller.smsbridge.service.RoomService; import ca.levimiller.smsbridge.service.UserService; import io.github.ma1uta.matrix.client.AppServiceClient; import javax.inject.Inject; +import liquibase.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -22,16 +24,19 @@ public class MatrixChatService implements ChatService { private final RoomService roomService; private final UserService userService; private final AppServiceClient matrixClient; + private final AttachmentService attachmentService; @Inject public MatrixChatService( ChatUserRepository chatUserRepository, RoomService roomService, UserService userService, - AppServiceClient matrixClient) { + AppServiceClient matrixClient, + AttachmentService attachmentService) { this.chatUserRepository = chatUserRepository; this.roomService = roomService; this.userService = userService; this.matrixClient = matrixClient; + this.attachmentService = attachmentService; } @Override @@ -46,10 +51,20 @@ public void sendMessage(Message message) { // Get room id and user id (ensure created/joined/etc.) ChatUser from = userService.getUser(message.getFromContact()); String roomId = roomService.getRoom(to, from); - matrixClient.userId(from.getOwnerId()).event().sendMessage(roomId, message.getBody()) - .exceptionally(throwable -> { - log.error("Error sending message to matrix: ", throwable); - return null; - }); + + if (!StringUtils.isEmpty(message.getBody())) { + matrixClient.userId(from.getOwnerId()).event().sendMessage(roomId, message.getBody()) + .exceptionally(throwable -> { + log.error("Error sending message to matrix: ", throwable); + return null; + }); + } + + // send attachments + if (message.getMedia() != null) { + message.getMedia().forEach(media -> { + attachmentService.sendAttachment(from, roomId, media); + }); + } } } diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AbstractAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AbstractAttachmentService.java new file mode 100644 index 0000000..da92fb8 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AbstractAttachmentService.java @@ -0,0 +1,80 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import ca.levimiller.smsbridge.service.AttachmentService; +import io.github.ma1uta.matrix.client.AppServiceClient; +import io.github.ma1uta.matrix.event.content.EventContent; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletionException; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; + +@Slf4j +public abstract class AbstractAttachmentService implements AttachmentService { + protected final AppServiceClient matrixClient; + + public AbstractAttachmentService(AppServiceClient matrixClient) { + this.matrixClient = matrixClient; + } + + /** + * Builds the event content from the attachment. + * @param attachment - attachment to send + * @return - event content for attachment + */ + protected abstract EventContent getContent(ChatUser user, Media attachment); + + @Override + public void sendAttachment(ChatUser user, String roomId, Media attachment) { + matrixClient.userId(user.getOwnerId()).event() + .sendEvent(roomId, "m.room.message", getContent(user, attachment)) + .exceptionally(throwable -> { + log.error( + String.format("Error sending attachment to matrix (%s): ", getClass()), + throwable); + return null; + }); + } + + /** + * Tries to upload the file at the given url to the matrix homeserver. + *

+ * If an exception occurs during the upload, the original url is returned. + * @param user - user uploading the file + * @param media - file to upload + * @return - new url from matrix + */ + protected String uploadFileToMatrix(ChatUser user, Media media) { + try { + String fileName = media.getUrl().substring(media.getUrl().lastIndexOf("/") + 1); + + // Download file + URL url = new URL(media.getUrl()); + CloseableHttpClient httpclient = HttpClients.custom() + .setRedirectStrategy(new LaxRedirectStrategy()) + .build(); + HttpGet get = new HttpGet(url.toURI()); + HttpResponse response = httpclient.execute(get); + InputStream source = response.getEntity().getContent(); + + return matrixClient.userId(user.getOwnerId()).content() + .upload(source, fileName, media.getContentType()) + .join(); + } catch (IOException | URISyntaxException | CancellationException | CompletionException error) { + log.error( + String.format("Error uploading file to matrix homeserver (%s): ", getClass()), + error); + // Fallback to initial url, so matrix message is sent instead of just a twilio error. + return media.getUrl(); + } + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AudioAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AudioAttachmentService.java new file mode 100644 index 0000000..2676d7a --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/AudioAttachmentService.java @@ -0,0 +1,36 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import io.github.ma1uta.matrix.client.AppServiceClient; +import io.github.ma1uta.matrix.event.content.EventContent; +import io.github.ma1uta.matrix.event.message.Audio; +import io.github.ma1uta.matrix.event.nested.AudioInfo; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class AudioAttachmentService extends AbstractAttachmentService { + + @Inject + public AudioAttachmentService(AppServiceClient matrixClient) { + super(matrixClient); + } + + @Override + protected EventContent getContent(ChatUser user, Media attachment) { + Audio audio = new Audio(); + audio.setBody("audio attachment"); + audio.setUrl(uploadFileToMatrix(user, attachment)); + + AudioInfo info = new AudioInfo(); + info.setMimetype(attachment.getContentType()); + audio.setInfo(info); + return audio; + } + + @Override + public boolean supportsType(String contentType) { + return contentType.startsWith("audio"); + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/CompositeAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/CompositeAttachmentService.java new file mode 100644 index 0000000..2366323 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/CompositeAttachmentService.java @@ -0,0 +1,48 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import ca.levimiller.smsbridge.service.AttachmentService; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.inject.Inject; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +@Primary +@Service +public class CompositeAttachmentService implements AttachmentService { + + private final AttachmentService defaultAttachmentService; + private final List attachmentServices; + + @Inject + public CompositeAttachmentService( + @Qualifier("defaultAttachmentService") AttachmentService defaultAttachmentService, + List attachmentServices) { + this.defaultAttachmentService = defaultAttachmentService; + this.attachmentServices = attachmentServices; + } + + @Override + public void sendAttachment(ChatUser user, String roomId, Media attachment) { + AtomicBoolean hasSupportedService = new AtomicBoolean(false); + attachmentServices.stream() + .filter(service -> service.supportsType(attachment.getContentType())) + .forEach(service -> { + hasSupportedService.set(true); + service.sendAttachment(user, roomId, attachment); + }); + + // If not sent by anything else, send using default + if (!hasSupportedService.get()) { + defaultAttachmentService.sendAttachment(user, roomId, attachment); + } + } + + @Override + public boolean supportsType(String contentType) { + return true; + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/DefaultAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/DefaultAttachmentService.java new file mode 100644 index 0000000..ef4447d --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/DefaultAttachmentService.java @@ -0,0 +1,41 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import ca.levimiller.smsbridge.service.AttachmentService; +import io.github.ma1uta.matrix.client.AppServiceClient; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@Qualifier("defaultAttachmentService") +public class DefaultAttachmentService implements AttachmentService { + private final AppServiceClient matrixClient; + + @Inject + public DefaultAttachmentService(AppServiceClient matrixClient) { + this.matrixClient = matrixClient; + } + + @Override + public void sendAttachment(ChatUser user, String roomId, Media attachment) { + String messageBody = String.format( + "%s - %s", + attachment.getContentType(), + attachment.getUrl()); + + matrixClient.userId(user.getOwnerId()).event().sendMessage(roomId, messageBody) + .exceptionally(throwable -> { + log.error("Error sending attachment to matrix (DefaultAttachmentService): ", throwable); + return null; + }); + } + + @Override + public boolean supportsType(String contentType) { + return false; + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/FileAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/FileAttachmentService.java new file mode 100644 index 0000000..3a57893 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/FileAttachmentService.java @@ -0,0 +1,36 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import io.github.ma1uta.matrix.client.AppServiceClient; +import io.github.ma1uta.matrix.event.content.EventContent; +import io.github.ma1uta.matrix.event.message.File; +import io.github.ma1uta.matrix.event.nested.FileInfo; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class FileAttachmentService extends AbstractAttachmentService { + + @Inject + public FileAttachmentService(AppServiceClient matrixClient) { + super(matrixClient); + } + + @Override + protected EventContent getContent(ChatUser user, Media attachment) { + File file = new File(); + file.setBody("file attachment"); + file.setUrl(uploadFileToMatrix(user, attachment)); + + FileInfo info = new FileInfo(); + info.setMimetype(attachment.getContentType()); + file.setInfo(info); + return file; + } + + @Override + public boolean supportsType(String contentType) { + return contentType.startsWith("application"); + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/ImageAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/ImageAttachmentService.java new file mode 100644 index 0000000..52cefcf --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/ImageAttachmentService.java @@ -0,0 +1,38 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import io.github.ma1uta.matrix.client.AppServiceClient; +import io.github.ma1uta.matrix.event.content.EventContent; +import io.github.ma1uta.matrix.event.message.Image; +import io.github.ma1uta.matrix.event.nested.ImageInfo; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class ImageAttachmentService extends AbstractAttachmentService { + + @Inject + public ImageAttachmentService(AppServiceClient matrixClient) { + super(matrixClient); + } + + @Override + protected EventContent getContent(ChatUser user, Media attachment) { + Image image = new Image(); + image.setBody("image attachment"); + image.setUrl(uploadFileToMatrix(user, attachment)); + + ImageInfo info = new ImageInfo(); + info.setMimetype(attachment.getContentType()); + image.setInfo(info); + return image; + } + + @Override + public boolean supportsType(String contentType) { + return contentType.startsWith("image"); + } +} diff --git a/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/VideoAttachmentService.java b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/VideoAttachmentService.java new file mode 100644 index 0000000..2140a89 --- /dev/null +++ b/src/main/java/ca/levimiller/smsbridge/service/impl/matrix/attachment/VideoAttachmentService.java @@ -0,0 +1,39 @@ +package ca.levimiller.smsbridge.service.impl.matrix.attachment; + +import ca.levimiller.smsbridge.data.model.ChatUser; +import ca.levimiller.smsbridge.data.model.Media; +import io.github.ma1uta.matrix.client.AppServiceClient; +import io.github.ma1uta.matrix.event.content.EventContent; +import io.github.ma1uta.matrix.event.message.Video; +import io.github.ma1uta.matrix.event.nested.VideoInfo; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class VideoAttachmentService extends AbstractAttachmentService { + + @Inject + public VideoAttachmentService(AppServiceClient matrixClient) { + super(matrixClient); + } + + @Override + protected EventContent getContent(ChatUser user, Media attachment) { + Video video = new Video(); + video.setBody("video attachment"); + video.setUrl(uploadFileToMatrix(user, attachment)); + + VideoInfo info = new VideoInfo(); + info.setMimetype(attachment.getContentType()); + video.setInfo(info); + return video; + } + + + @Override + public boolean supportsType(String contentType) { + return contentType.startsWith("video"); + } +}