Skip to content

Commit

Permalink
Merge pull request #35 from wireapp/staging
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
dkovacevic authored Feb 11, 2021
2 parents d37225e + 8780cf1 commit 0beb877
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 183 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ COPY . ./

RUN mvn -Dmaven.test.skip=true package

FROM dejankovacevic/bots.runtime:2.10.3
FROM wirebot/runtime

COPY --from=build /app/target/roman.jar /opt/roman/
# COPY target/roman.jar /opt/roman/roman.jar
Expand All @@ -30,5 +30,5 @@ WORKDIR /opt/roman

EXPOSE 8080 8081 8082

ENTRYPOINT ["java", "-javaagent:/opt/wire/lib/jmx_prometheus_javaagent.jar=8082:/opt/wire/lib/metrics.yaml", "-jar", "roman.jar", "server", "/etc/roman/roman.yaml"]
ENTRYPOINT ["java", "-javaagent:/opt/wire/lib/prometheus-agent.jar=8082:/opt/wire/lib/metrics.yaml", "-jar", "roman.jar", "server", "/etc/roman/roman.yaml"]

11 changes: 8 additions & 3 deletions src/main/java/com/wire/bots/roman/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
public class Application extends Server<Config> {
private static Application instance;
private Key key;
private MessageHandler messageHandler;

public static void main(String[] args) throws Exception {
new Application().run(args);
Expand All @@ -66,7 +67,8 @@ public void initialize(Bootstrap<Config> bootstrap) {

@Override
protected MessageHandlerBase createHandler(Config config, Environment env) {
return new MessageHandler(jdbi, getClient());
this.messageHandler = new MessageHandler(jdbi, getClient());
return messageHandler;
}

@Override
Expand All @@ -86,13 +88,16 @@ protected void initialize(Config config, Environment env) {
@Override
protected void onRun(Config config, Environment env) {
ProviderClient providerClient = new ProviderClient(getClient(), config.apiHost);
Sender sender = new Sender(getRepo());

addResource(new ProviderResource(jdbi, providerClient));
addResource(new ServiceResource(jdbi, providerClient));
addResource(new ConversationResource(getRepo()));
addResource(new ConversationResource(sender));
addResource(new UsersResource(getRepo()));
addResource(new BroadcastResource(jdbi, getRepo()));
addResource(new BroadcastResource(jdbi, sender));
addResource(new MessagesResource());

messageHandler.setSender(sender);
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/wire/bots/roman/CachedClientRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.wire.bots.sdk.models.otr.Missing;
import com.wire.bots.sdk.models.otr.Recipients;
import com.wire.bots.sdk.server.model.NewBot;
import com.wire.bots.sdk.tools.Logger;

import javax.ws.rs.client.Client;
import java.util.UUID;
Expand All @@ -34,6 +35,7 @@ public WireClient getClient(UUID botId) {
API api = new API(httpClient, state.token);
return new _BotClient(state, crypto, api);
} catch (Exception e) {
Logger.warning("CachedClientRepo: bot: %s %s", botId, e);
return null;
}
}
Expand Down
68 changes: 38 additions & 30 deletions src/main/java/com/wire/bots/roman/MessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.waz.model.Messages;
import com.wire.bots.roman.DAO.BotsDAO;
import com.wire.bots.roman.DAO.ProvidersDAO;
import com.wire.bots.roman.model.IncomingMessage;
import com.wire.bots.roman.model.OutgoingMessage;
import com.wire.bots.roman.model.Poll;
import com.wire.bots.roman.model.Provider;
Expand All @@ -17,12 +18,10 @@
import com.wire.bots.sdk.tools.Logger;
import org.skife.jdbi.v2.DBI;

import javax.websocket.EncodeException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.UUID;
Expand All @@ -37,6 +36,7 @@ public class MessageHandler extends MessageHandlerBase {
private final Client jerseyClient;
private final ProvidersDAO providersDAO;
private final BotsDAO botsDAO;
private Sender sender;

MessageHandler(DBI jdbi, Client jerseyClient) {
this.jerseyClient = jerseyClient;
Expand Down Expand Up @@ -278,36 +278,40 @@ private OutgoingMessage getOutgoingMessage(UUID botId, String type, MessageBase

private boolean send(OutgoingMessage message) {
UUID providerId = botsDAO.getProviderId(message.botId);
Provider provider = providersDAO.get(providerId);
if (provider == null) {
Logger.error("MessageHandler.send: provider == null. providerId: %s, bot: %s",
providerId, message.botId);
return false;
}

trace(message);

// Webhook
if (provider.serviceUrl != null) {
Response post = jerseyClient.target(provider.serviceUrl)
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + provider.serviceAuth)
.post(Entity.entity(message, MediaType.APPLICATION_JSON));

Logger.debug("MessageHandler.send: `%s` bot: %s, provider: %s, status: %d",
message.type,
message.botId,
providerId,
post.getStatus());

final String entity = post.readEntity(String.class);
post.close();
return post.getStatus() == 200;
}

try {
return WebSocket.send(provider.id, message);
} catch (IOException | EncodeException e) {
Provider provider = providersDAO.get(providerId);
if (provider == null) {
Logger.error("MessageHandler.send: provider == null. providerId: %s, bot: %s",
providerId, message.botId);
return false;
}

trace(message);

// Webhook
if (provider.serviceUrl != null) {
Response post = jerseyClient.target(provider.serviceUrl)
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + provider.serviceAuth)
.post(Entity.entity(message, MediaType.APPLICATION_JSON));

Logger.debug("MessageHandler.send: `%s` bot: %s, provider: %s, status: %d",
message.type,
message.botId,
providerId,
post.getStatus());

final IncomingMessage incomingMessage = post.readEntity(IncomingMessage.class);
if (incomingMessage != null) {
sender.send(incomingMessage, message.botId);
}

return post.getStatus() == 200;
} else {
return WebSocket.send(provider.id, message);
}
} catch (Exception e) {
Logger.error("MessageHandler.send: bot: %s, provider: %s, error %s", message.botId, providerId, e);
return false;
}
Expand Down Expand Up @@ -347,4 +351,8 @@ private UUID validate(UUID botId) {
throw new RuntimeException("Unknown botId: " + botId.toString());
return providerId;
}

public void setSender(Sender sender) {
this.sender = sender;
}
}
127 changes: 127 additions & 0 deletions src/main/java/com/wire/bots/roman/Sender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package com.wire.bots.roman;


import com.wire.bots.cryptobox.CryptoException;
import com.wire.bots.roman.model.Attachment;
import com.wire.bots.roman.model.IncomingMessage;
import com.wire.bots.roman.model.Mention;
import com.wire.bots.sdk.ClientRepo;
import com.wire.bots.sdk.WireClient;
import com.wire.bots.sdk.assets.*;
import com.wire.bots.sdk.models.AssetKey;
import com.wire.bots.sdk.server.model.Conversation;
import com.wire.bots.sdk.tools.Logger;

import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Base64;
import java.util.UUID;

public class Sender {

private final ClientRepo repo;

public Sender(ClientRepo repo) {
this.repo = repo;
}

public UUID send(IncomingMessage message, UUID botId) throws Exception {
try (WireClient client = repo.getClient(botId)) {
return send(message, client);
}
}

@Nullable
private UUID send(IncomingMessage message, @Nullable WireClient client) throws Exception {
if (client == null)
return null;

switch (message.type) {
case "text": {
MessageText text = new MessageText(message.text.data);
if (message.text.mentions != null) {
for (Mention mention : message.text.mentions)
text.addMention(mention.userId, mention.offset, mention.length);
}
client.send(text);
return text.getMessageId();
}
case "attachment": {
if (message.attachment.mimeType.startsWith("image")) {
final byte[] decode = Base64.getDecoder().decode(message.attachment.data);
return client.sendPicture(decode, message.attachment.mimeType);
}

return sendAttachment(message, client);
}
case "poll": {
if (message.poll.type.equals("create")) {
return sendNewPoll(message, client);
}
if (message.poll.type.equals("confirmation")) {
return sendPollConfirmation(message, client);
}
}
break;
}

return null;
}

private UUID sendNewPoll(IncomingMessage message, WireClient client) throws Exception {
MessageText messageText = new MessageText(message.text.data);
if (message.text.mentions != null) {
for (Mention mention : message.text.mentions)
messageText.addMention(mention.userId, mention.offset, mention.length);
}

Poll poll = new Poll(message.poll.id);
poll.addText(messageText);

int i = 0;
for (String caption : message.poll.buttons) {
poll.addButton("" + i++, caption);
}

Logger.info("poll.create: id: %s", message.poll.id);

client.send(poll);

return poll.getMessageId();
}

private UUID sendAttachment(IncomingMessage message, WireClient client) throws Exception {
UUID messageId = UUID.randomUUID();

final Attachment attachment = message.attachment;
final byte[] decode = Base64.getDecoder().decode(attachment.data);

FileAssetPreview preview = new FileAssetPreview(attachment.filename, attachment.mimeType, decode.length, messageId);
FileAsset asset = new FileAsset(decode, attachment.mimeType, messageId);

client.send(preview);
final AssetKey assetKey = client.uploadAsset(asset);
asset.setAssetKey(assetKey.key);
asset.setAssetToken(assetKey.token);
client.send(asset);
return messageId;
}

private UUID sendPollConfirmation(IncomingMessage message, WireClient client) throws Exception {
ButtonActionConfirmation confirmation = new ButtonActionConfirmation(
message.poll.id,
message.poll.offset.toString());

Logger.info("poll.confirmation: pollId: %s, offset: %s", message.poll.id, message.poll.offset);

client.send(confirmation, message.poll.userId);

return confirmation.getMessageId();
}

public Conversation getConversation(UUID botId) throws IOException, CryptoException {
try (WireClient client = repo.getClient(botId)) {
return client.getConversation();
}
}
}
33 changes: 7 additions & 26 deletions src/main/java/com/wire/bots/roman/resources/BroadcastResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wire.bots.roman.DAO.BotsDAO;
import com.wire.bots.roman.DAO.ProvidersDAO;
import com.wire.bots.roman.Sender;
import com.wire.bots.roman.filters.ServiceTokenAuthorization;
import com.wire.bots.roman.model.IncomingMessage;
import com.wire.bots.roman.model.Mention;
import com.wire.bots.roman.model.Provider;
import com.wire.bots.sdk.ClientRepo;
import com.wire.bots.sdk.WireClient;
import com.wire.bots.sdk.assets.MessageText;
import com.wire.bots.sdk.exceptions.MissingStateException;
import com.wire.bots.sdk.server.model.ErrorMessage;
import com.wire.bots.sdk.tools.Logger;
Expand All @@ -28,7 +25,6 @@
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
Expand All @@ -41,11 +37,11 @@
@Produces(MediaType.APPLICATION_JSON)
public class BroadcastResource {
private final DBI jdbi;
private final ClientRepo repo;
private final Sender sender;

public BroadcastResource(DBI jdbi, ClientRepo repo) {
public BroadcastResource(DBI jdbi, Sender sender) {
this.jdbi = jdbi;
this.repo = repo;
this.sender = sender;
}

@POST
Expand Down Expand Up @@ -105,24 +101,9 @@ public Response post(@Context ContainerRequestContext context,
}

private boolean send(UUID botId, IncomingMessage message) {
try (WireClient client = repo.getClient(botId)) {
switch (message.type) {
case "text": {
MessageText text = new MessageText(message.text.data);
if (message.text.mentions != null) {
for (Mention mention : message.text.mentions)
text.addMention(mention.userId, mention.offset, mention.length);
}
client.send(text);
}
break;
case "attachment": {
final byte[] decode = Base64.getDecoder().decode(message.attachment.data);
client.sendPicture(decode, message.attachment.mimeType);
}
break;
}
return true;
try {
final UUID messageId = sender.send(message, botId);
return messageId != null;
} catch (MissingStateException e) {
Logger.warning("BroadcastResource: bot: %s, e: %s", botId, e);
jdbi.onDemand(BotsDAO.class).remove(botId);
Expand Down
Loading

0 comments on commit 0beb877

Please sign in to comment.