Skip to content
Draft

Wip #1562

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions slack-api-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.4.8-jre</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.slack.api.model.block.composition;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ThirdPartyAuthObject {
Boolean enableDynamicAuth;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.slack.api.model.work_objects;

public class ActionBlockPayload {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.slack.api.model.work_objects;

public class ActionMenu {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.slack.api.model.work_objects;

import com.slack.api.model.block.ImageBlock;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class AppIcons {
ImageBlock image36;
ImageBlock image128;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.slack.api.model.work_objects;

import com.slack.api.model.block.composition.ConfirmationDialogObject;
import com.slack.api.model.block.composition.PlainTextObject;
import com.slack.api.model.block.composition.ThirdPartyAuthObject;
import com.slack.api.model.work_objects.external.ButtonProcessingState;
import com.slack.api.util.annotation.Required;
import com.slack.api.util.predicate.FieldPredicate;
import lombok.Builder;
import lombok.Value;

import java.util.List;

import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.instanceOf;

/**
* Button Action Payload.
* <p>
* Represents the payload sent to the server from a `button` action.
*/
@Value
@Builder
public class Button extends PrimaryActions {
@Required String blockId;
@Required String actionId;
@Required(validator = ButtonTypePredicate.class) String type;
String style;
@Required PlainTextObject text;
String value;
String url;
String accessibilityLabel;
ConfirmationDialogObject confirm;
ThirdPartyAuthObject thirdPartyAuth;
List<String> visibleToUserIds;
ButtonProcessingState processingState;

public static class ButtonTypePredicate implements FieldPredicate {
@Override
public boolean validate(Object obj) {
return instanceOf(String.class).and(equalTo("button")).test(obj);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.slack.api.model.work_objects;

import com.google.common.base.Preconditions;
import com.slack.api.util.annotation.Required;
import com.slack.api.util.predicate.IsValidChannelIdPredicate;
import lombok.Builder;
import lombok.Value;

import static com.slack.api.util.predicate.IsValidChannelIdPredicate.CHANNEL_ID_REGEX;

/**
* Representation of a Slack channel on a work object.
*/
@Value
public class Channel {
private static final IsValidChannelIdPredicate isValidChannelId = new IsValidChannelIdPredicate();

@Required(validator = IsValidChannelIdPredicate.class)
String channelId;

@Builder
public Channel(String channelId) {
Preconditions.checkArgument(
isValidChannelId.test(channelId),
String.format("Invalid slack channelId %s, required format %s", channelId, CHANNEL_ID_REGEX)
);
this.channelId = channelId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.slack.api.model.work_objects;

import com.slack.api.util.annotation.Required;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class CheckboxOption {
@Required String text;
@Required Boolean checked;
String description;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.slack.api.model.work_objects;

import com.slack.api.model.block.ImageBlock;
import com.slack.api.util.annotation.Required;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class CompactLayout {
public static final String LAYOUT_TYPE = "compact";
@Required String layoutType;
ImageBlock productIcon;
@Required Title title;
Title subtitle;
Title headerTitle;
Title hoverSubtitle;
Fields fields;
Integer updatedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.slack.api.model.work_objects;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.JsonAdapter;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Value;

import java.lang.reflect.Type;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
* Combined date/time display data for calendar events.
*/
@Value
@Builder
@JsonAdapter(DateTimeRange.DateTimeRangeSerializer.class)
public class DateTimeRange {
/**
* Start as Unix timestamp or YYYY-MM-DD dates.
*/
DateTimeImpl start;
/**
* End as Unix timestamp or YYYY-MM-DD dates
*/
DateTimeImpl end;

/**
* Whether this is an all-day event.
*/
Boolean allDay;

/**
* Recurrence description text.
*/
String recurrence;

/**
* Since java doesn't support union types, this class represents a datetime input that can either be a unix
* timestamp or a date string in YYYY-MM-DD format.
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class DateTimeImpl {
private final Instant dateTime;
@Getter @Setter
private boolean inYearMonthDayFormat = false;

public boolean isUnknown() {
return dateTime.equals(Instant.EPOCH);
}

public static DateTimeImpl atStartOfDay() {
Instant startOfDay = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC).toInstant();
return new DateTimeImpl(startOfDay);
}

public static DateTimeImpl atEndOfDay() {
Instant endOfDay = LocalDate.now(ZoneOffset.UTC).plusDays(1).atStartOfDay(ZoneOffset.UTC).toInstant();
return new DateTimeImpl(endOfDay);
}

// Used during JSON serialization/deserialization when we can't infer what the date-time value is
public static DateTimeImpl unknown() {
return new DateTimeImpl(Instant.EPOCH);
}

public static DateTimeImpl from(String in) {
// See if this is a number first
try {
return DateTimeImpl.from(Long.parseLong(in));
} catch (NumberFormatException e) {
// Swallow - means the input is not a unix timestamp, so try to parse this as a string
}

// Now make sure it's in YYYY-MM-DD format
try {
Instant dt = LocalDate.parse(in).atStartOfDay(ZoneOffset.UTC).toInstant();
DateTimeImpl dateTime = new DateTimeImpl(dt);
dateTime.setInYearMonthDayFormat(true);
return dateTime;
} catch (DateTimeParseException e) {
throw new IllegalArgumentException(String.format("Datetime input string not in a recognized format %s", in));
}
}

public static DateTimeImpl from(int in) {
return from(Long.valueOf(in));
}

public static DateTimeImpl from(long in) {
Instant dateTime = Instant.ofEpochSecond(in);
return new DateTimeImpl(dateTime);
}

public long getUnixTime() {
return dateTime.getEpochSecond();
}

public String getDateTime() {
return DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC).format(dateTime);
}
}

public static class DateTimeRangeSerializer implements JsonSerializer<DateTimeRange> {
@Override
public JsonElement serialize(DateTimeRange dateTimeRange, Type typeOfT, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
if (dateTimeRange.getStart() != null) {
DateTimeImpl start = dateTimeRange.getStart();
if (start.isInYearMonthDayFormat()) {
jsonObject.addProperty("start", start.getDateTime());
} else {
jsonObject.addProperty("start", start.getUnixTime());
}
}
if (dateTimeRange.getEnd() != null) {
DateTimeImpl end = dateTimeRange.getEnd();
if (end.isInYearMonthDayFormat()) {
jsonObject.addProperty("end", end.getDateTime());
} else {
jsonObject.addProperty("end", end.getUnixTime());
}
}
if (dateTimeRange.getAllDay() != null) {
jsonObject.addProperty("all_day", dateTimeRange.getAllDay());
}
if (dateTimeRange.getRecurrence() != null && !dateTimeRange.getRecurrence().isEmpty()) {
jsonObject.addProperty("recurrence", dateTimeRange.getRecurrence());
}

return jsonObject;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.slack.api.model.work_objects;

import com.google.gson.annotations.SerializedName;
import com.slack.api.model.block.composition.PlainTextObject;
import com.slack.api.util.annotation.Required;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Value;

@Value
@Builder
public class DefaultAction extends PrimaryActions {
@Required Type type;
String style;
PlainTextObject text;

@Getter
@RequiredArgsConstructor
public enum Type {
@SerializedName("add-to-todo") ADD_TO_TODO("add-to-todo"),
@SerializedName("open-in-app") OPEN_IN_APP("open-in-app"),
@SerializedName("share-link") SHARE_LINK("share-link"),
@SerializedName("copy-link") COPY_LINK("copy-link"),
@SerializedName("add-to-list") ADD_TO_LIST("add-to-list"),
@SerializedName("save-for-later") SAVE_FOR_LATER("save-for-later"),
@SerializedName("remind-me") REMIND_ME("remind-me"),
@SerializedName("add-to-folder") ADD_TO_FOLDER("add-to-folder");

private final String value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.slack.api.model.work_objects;

import com.google.common.base.Preconditions;
import com.slack.api.model.block.ImageBlock;
import com.slack.api.util.annotation.Required;
import com.slack.api.util.predicate.IsValidAppIdPredicate;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class EntityReference {
private static final IsValidAppIdPredicate isValidAppId = new IsValidAppIdPredicate();

@Required
String entityId;

@Required(validator = IsValidAppIdPredicate.class)
String appId;

@Required
String entityUrl;

String displayType;

@Required
String title;

ImageBlock icon;

public static class EntityReferenceBuilder {
public EntityReferenceBuilder appId(String appId) {
Preconditions.checkArgument(isValidAppId.test(appId));
this.appId = appId;
return this;
}
}
}
Loading
Loading