Skip to content

Commit

Permalink
Merge branch 'release/0.22.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ljupcovangelski committed May 18, 2021
2 parents b0afa64 + cffc440 commit 087774f
Show file tree
Hide file tree
Showing 31 changed files with 566 additions and 467 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.21.0
0.22.0
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
import static co.airy.core.api.communication.util.Topics.applicationCommunicationChannels;
import static co.airy.core.api.communication.util.Topics.getTopics;
import static co.airy.test.Timing.retryOnException;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand Down
1 change: 1 addition & 0 deletions backend/sources/twilio/connector/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ springboot(
"//backend:base_test",
"@maven//:javax_xml_bind_jaxb_api",
"//lib/java/kafka/test:kafka-test",
"//lib/java/spring/test:spring-test",
] + app_deps,
)
for file in glob(["src/test/java/**/*Test.java"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import co.airy.avro.communication.Channel;
import co.airy.avro.communication.ChannelConnectionState;
import co.airy.avro.communication.Metadata;
import co.airy.kafka.schema.application.ApplicationCommunicationChannels;
import co.airy.model.channel.dto.ChannelContainer;
import co.airy.model.metadata.MetadataKeys;
import co.airy.model.metadata.dto.MetadataMap;
import co.airy.uuid.UUIDv5;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -22,21 +20,18 @@
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static co.airy.model.channel.ChannelPayload.fromChannelContainer;
import static co.airy.model.metadata.MetadataRepository.newChannelMetadata;

@RestController
public class ChannelsController {
private static final String applicationCommunicationChannels = new ApplicationCommunicationChannels().name();

private final Stores stores;
private final KafkaProducer<String, Channel> producer;

public ChannelsController(Stores stores, KafkaProducer<String, Channel> producer) {
public ChannelsController(Stores stores) {
this.stores = stores;
this.producer = producer;
}

@PostMapping("/channels.twilio.sms.connect")
Expand Down Expand Up @@ -131,6 +126,13 @@ private ResponseEntity<?> disconnect(@RequestBody @Valid DisconnectChannelReques
class ConnectChannelRequestPayload {
@NotNull
private String phoneNumber;

public String getPhoneNumber() {
return Optional.ofNullable(phoneNumber)
.map((phoneNumber) -> phoneNumber.replaceAll("\\s+","").trim())
.orElse(null);
}

@NotNull
private String name;
private String imageUrl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import co.airy.kafka.test.KafkaTestHelper;
import co.airy.kafka.test.junit.SharedKafkaTestResource;
import co.airy.spring.core.AirySpringBootApplication;
import co.airy.spring.test.WebTestHelper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
Expand All @@ -22,6 +25,7 @@
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.TestPropertySource;
Expand All @@ -36,9 +40,11 @@
import static org.apache.kafka.streams.KafkaStreams.State.RUNNING;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doNothing;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest(classes = AirySpringBootApplication.class)
@TestPropertySource(value = "classpath:test.properties")
@AutoConfigureMockMvc
@ExtendWith(SpringExtension.class)
class SendMessageTest {

Expand All @@ -56,6 +62,9 @@ class SendMessageTest {
@InjectMocks
private Connector worker;

@Autowired
private WebTestHelper webTestHelper;

@Autowired
private Stores stores;

Expand All @@ -77,7 +86,7 @@ static void afterAll() throws Exception {
@BeforeEach
void beforeEach() throws InterruptedException {
MockitoAnnotations.openMocks(this);
retryOnException(() -> assertEquals(stores.getStreamState(), RUNNING), "Failed to reach RUNNING state.");
webTestHelper.waitUntilHealthy();
}

@Test
Expand All @@ -86,24 +95,22 @@ void canSendMessageViaTheTwilioApi() throws Exception {
final String messageId = UUID.randomUUID().toString();
final String sourceConversationId = "+491234567";
final String sourceChannelId = "+497654321";
final String channelId = UUID.randomUUID().toString();
final String token = "token";
final String text = "Hello World";

ArgumentCaptor<String> payloadCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> fromCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> toCaptor = ArgumentCaptor.forClass(String.class);
doNothing().when(api).sendMessage(fromCaptor.capture(), toCaptor.capture(), payloadCaptor.capture());

// Test that phone number input gets cleaned up
final String payload = "{\"phone_number\":\"+49 765 4321 \",\"name\":\"Blips and Chitz\"}";
final String response = webTestHelper.post("/channels.twilio.sms.connect", payload)
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
final JsonNode jsonNode = new ObjectMapper().readTree(response);
final String channelId = jsonNode.get("id").textValue();

kafkaTestHelper.produceRecords(List.of(
new ProducerRecord<>(applicationCommunicationChannels.name(), channelId, Channel.newBuilder()
.setToken(token)
.setSourceChannelId(sourceChannelId)
.setSource("twilio.sms")
.setId(channelId)
.setConnectionState(ChannelConnectionState.CONNECTED)
.build()
),
new ProducerRecord<>(applicationCommunicationMessages.name(), "other-message-id",
Message.newBuilder()
.setId("other-message-id")
Expand Down
53 changes: 52 additions & 1 deletion docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,66 @@ title: Changelog
sidebar_label: 📝 Changelog
---

## 0.22.0

#### 🚀 Features

- [[#1743](https://github.com/airyhq/airy/issues/1743)] Return proper status code for unauthorized access [[#1785](https://github.com/airyhq/airy/pull/1785)]

#### 🐛 Bug Fixes

- [[#1743](https://github.com/airyhq/airy/issues/1743)] Permit public auth pages [[#1786](https://github.com/airyhq/airy/pull/1786)]
- [[#1768](https://github.com/airyhq/airy/issues/1768)] Bad calls to conversations info when opening inbox [[#1775](https://github.com/airyhq/airy/pull/1775)]
- [[#1764](https://github.com/airyhq/airy/issues/1764)] Filter fixed + state header bar toggle fix [[#1774](https://github.com/airyhq/airy/pull/1774)]

#### 🧰 Maintenance

- Bump prettier from 2.2.1 to 2.3.0 [[#1759](https://github.com/airyhq/airy/pull/1759)]
- Bump webpack-bundle-analyzer from 4.4.1 to 4.4.2 [[#1800](https://github.com/airyhq/airy/pull/1800)]
- Bump @typescript-eslint/parser from 4.23.0 to 4.24.0 [[#1801](https://github.com/airyhq/airy/pull/1801)]
- Bump @babel/core from 7.14.2 to 7.14.3 [[#1802](https://github.com/airyhq/airy/pull/1802)]
- Bump @typescript-eslint/eslint-plugin from 4.23.0 to 4.24.0 [[#1803](https://github.com/airyhq/airy/pull/1803)]
- Bump sass from 1.32.12 to 1.32.13 [[#1793](https://github.com/airyhq/airy/pull/1793)]
- Bump @bazel/typescript from 3.4.2 to 3.5.0 [[#1776](https://github.com/airyhq/airy/pull/1776)]
- Bump @types/node from 15.0.2 to 15.3.0 [[#1796](https://github.com/airyhq/airy/pull/1796)]
- Bump terser-webpack-plugin from 5.1.1 to 5.1.2 [[#1795](https://github.com/airyhq/airy/pull/1795)]
- Bump @typescript-eslint/parser from 4.22.1 to 4.23.0 [[#1779](https://github.com/airyhq/airy/pull/1779)]
- Bump @babel/core from 7.14.0 to 7.14.2 [[#1794](https://github.com/airyhq/airy/pull/1794)]
- Bump cypress from 7.2.0 to 7.3.0 [[#1780](https://github.com/airyhq/airy/pull/1780)]
- Bump sass-loader from 11.0.1 to 11.1.1 [[#1790](https://github.com/airyhq/airy/pull/1790)]
- Bump @babel/preset-env from 7.14.1 to 7.14.2 [[#1792](https://github.com/airyhq/airy/pull/1792)]
- Bump @types/react-dom from 16.9.2 to 17.0.5 [[#1789](https://github.com/airyhq/airy/pull/1789)]
- Bump core-js from 3.12.0 to 3.12.1 [[#1758](https://github.com/airyhq/airy/pull/1758)]
- Bump eslint from 7.25.0 to 7.26.0 [[#1760](https://github.com/airyhq/airy/pull/1760)]
- Bump @typescript-eslint/eslint-plugin from 4.22.1 to 4.23.0 [[#1769](https://github.com/airyhq/airy/pull/1769)]
- Bump webpack from 5.36.2 to 5.37.0 [[#1770](https://github.com/airyhq/airy/pull/1770)]

#### Airy CLI

You can download the Airy CLI for your operating system from the following links:

[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.22.0/darwin/amd64/airy)
[Linux](https://airy-core-binaries.s3.amazonaws.com/0.22.0/linux/amd64/airy)
[Windows](https://airy-core-binaries.s3.amazonaws.com/0.22.0/windows/amd64/airy.exe)

## 0.21.0

#### Changes

- [[#1750](https://github.com/airyhq/airy/issues/1750)] Fix tags filter [[#1765](https://github.com/airyhq/airy/pull/1765)]

#### 🚀 Features

- [[#1681](https://github.com/airyhq/airy/issues/1681)] Clean phone number input [[#1772](https://github.com/airyhq/airy/pull/1772)]
- [[#1519](https://github.com/airyhq/airy/issues/1519)] Implement auth UI behavior [[#1737](https://github.com/airyhq/airy/pull/1737)]
- [[#1721](https://github.com/airyhq/airy/issues/1721)] Webhook consumer start consuming from beginning[[#1722](https://github.com/airyhq/airy/pull/1722)]
- [[#1721](https://github.com/airyhq/airy/issues/1721)] Webhook consumer should start consuming[[#1722](https://github.com/airyhq/airy/pull/1722)]
- [[#1713](https://github.com/airyhq/airy/issues/1713)] Fix crash conversation from search [[#1720](https://github.com/airyhq/airy/pull/1720)]
- [[#1707](https://github.com/airyhq/airy/issues/1707)] Attach user profile to application logs [[#1718](https://github.com/airyhq/airy/pull/1718)]
- [[#1714](https://github.com/airyhq/airy/issues/1714)] Webhook config updates only once [[#1715](https://github.com/airyhq/airy/pull/1715)]

#### 🐛 Bug Fixes

- [[#1749](https://github.com/airyhq/airy/issues/1749)] Fixed activeFilterCount [[#1747](https://github.com/airyhq/airy/pull/1747)]
- [[#1763](https://github.com/airyhq/airy/issues/1763)] Fixed tag string length in contactInfo [[#1766](https://github.com/airyhq/airy/pull/1766)]
- [[#1736](https://github.com/airyhq/airy/issues/1736)] improve render library for facebook [[#1756](https://github.com/airyhq/airy/pull/1756)]
- [[#1748](https://github.com/airyhq/airy/issues/1748)] Add missing default redirect uri [[#1749](https://github.com/airyhq/airy/pull/1749)]
Expand Down Expand Up @@ -42,6 +90,9 @@ sidebar_label: 📝 Changelog
- Bump webpack-cli from 4.6.0 to 4.7.0 [[#1741](https://github.com/airyhq/airy/pull/1741)]
- Bump @types/node from 15.0.1 to 15.0.2 [[#1723](https://github.com/airyhq/airy/pull/1723)]
- Bump @typescript-eslint/parser from 4.22.0 to 4.22.1 [[#1724](https://github.com/airyhq/airy/pull/1724)]
- Bump typescript from 4.2.3 to 4.2.4 [[#1753](https://github.com/airyhq/airy/pull/1753)]
- Bump @types/react from 17.0.4 to 17.0.5 [[#1727](https://github.com/airyhq/airy/pull/1727)]
- Bump @typescript-eslint/eslint-plugin from 4.22.0 to 4.22.1 [[#1725](https://github.com/airyhq/airy/pull/1725)]

#### Airy CLI

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/ui/inbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Airy’s Inbox supports all [Google’s Rich Cards variants from Rich Cards to C
{
"conversation_id": "a688d36c-a85e-44af-bc02-4248c2c97622",
"message": {
"fallback": 'Hello, world!\n\nReply with "A" or "B"',
"fallback": "Hello, world!\n\nReply with \"A\" or \"B\"",
"richCard": {
"standaloneCard": {
"cardContent": {
Expand Down Expand Up @@ -135,7 +135,7 @@ link='sources/chatplugin/overview'
{
"conversation_id": "a688d36c-a85e-44af-bc02-4248c2c97622",
"message": {
"fallback": 'Card #1\n #1\n\nCard #2\n\n\nReply with "Card #1" or "Card #2"',
"fallback": "Card #1\n #1\n\nCard #2\n\n\nReply with \"Card #1\" or \"Card #2\"",
"richCard": {
"carouselCard": {
"cardWidth": "MEDIUM",
Expand Down
26 changes: 12 additions & 14 deletions frontend/ui/src/actions/channel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ export const exploreChannels = (requestPayload: ExploreChannelRequestPayload) =>
});
};

export const connectFacebookChannel = (requestPayload: ConnectChannelFacebookRequestPayload) => async (
dispatch: Dispatch<any>
) =>
HttpClientInstance.connectFacebookChannel(requestPayload).then((response: Channel) => {
dispatch(addChannelsAction([response]));
return Promise.resolve(response);
});
export const connectFacebookChannel =
(requestPayload: ConnectChannelFacebookRequestPayload) => async (dispatch: Dispatch<any>) =>
HttpClientInstance.connectFacebookChannel(requestPayload).then((response: Channel) => {
dispatch(addChannelsAction([response]));
return Promise.resolve(response);
});

export const connectChatPlugin = (requestPayload: ConnectChatPluginRequestPayload) => async (dispatch: Dispatch<any>) =>
HttpClientInstance.connectChatPluginChannel(requestPayload).then((response: Channel) => {
Expand All @@ -61,13 +60,12 @@ export const connectTwilioSms = (requestPayload: ConnectTwilioSmsRequestPayload)
return Promise.resolve(response);
});

export const connectTwilioWhatsapp = (requestPayload: ConnectTwilioWhatsappRequestPayload) => async (
dispatch: Dispatch<any>
) =>
HttpClientInstance.connectTwilioWhatsappChannel(requestPayload).then((response: Channel) => {
dispatch(addChannelsAction([response]));
return Promise.resolve(response);
});
export const connectTwilioWhatsapp =
(requestPayload: ConnectTwilioWhatsappRequestPayload) => async (dispatch: Dispatch<any>) =>
HttpClientInstance.connectTwilioWhatsappChannel(requestPayload).then((response: Channel) => {
dispatch(addChannelsAction([response]));
return Promise.resolve(response);
});

export const updateChannel = (requestPayload: UpdateChannelRequestPayload) => async (dispatch: Dispatch<any>) =>
HttpClientInstance.updateChannel(requestPayload).then((response: Channel) => {
Expand Down
13 changes: 9 additions & 4 deletions frontend/ui/src/actions/conversations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export const loadingConversationAction = createAction(
(conversationId: string) => conversationId
)<string>();

export const loadingConversationsAction = createAction(CONVERSATIONS_LOADING)();
export const loadingConversationsAction = createAction(
CONVERSATIONS_LOADING,
(isLoading: boolean) => isLoading
)<boolean>();

export const mergeConversationsAction = createAction(
CONVERSATIONS_MERGE,
Expand Down Expand Up @@ -55,19 +58,21 @@ export const setStateConversationAction = createAction(
)<{conversationId: string; state: string}>();

export const listConversations = () => async (dispatch: Dispatch<any>) => {
dispatch(loadingConversationsAction());
return HttpClientInstance.listConversations({page_size: 10}).then((response: PaginatedResponse<Conversation>) => {
dispatch(loadingConversationsAction(true));
return HttpClientInstance.listConversations({page_size: 50}).then((response: PaginatedResponse<Conversation>) => {
dispatch(mergeConversationsAction(response.data, response.paginationData));
dispatch(loadingConversationsAction(false));
return Promise.resolve(true);
});
};

export const listNextConversations = () => async (dispatch: Dispatch<any>, state: () => StateModel) => {
const cursor = state().data.conversations.all.paginationData.nextCursor;

dispatch(loadingConversationsAction());
dispatch(loadingConversationsAction(true));
return HttpClientInstance.listConversations({cursor: cursor}).then((response: PaginatedResponse<Conversation>) => {
dispatch(mergeConversationsAction(response.data, response.paginationData));
dispatch(loadingConversationsAction(false));
return Promise.resolve(true);
});
};
Expand Down
23 changes: 7 additions & 16 deletions frontend/ui/src/actions/conversationsFilter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {HttpClientInstance} from '../../InitializeAiryApi';

import {StateModel} from '../../reducers';
import {loadingConversationsAction} from '../conversations';
import {delay, isEqual} from 'lodash-es';
import {delay, isEqual, omit} from 'lodash-es';

export const RESET_FILTERED_CONVERSATIONS = '@@conversations/RESET_FILTEREDS';
export const SET_FILTERED_CONVERSATIONS = '@@conversations/SET_FILTERED';
Expand Down Expand Up @@ -38,10 +38,8 @@ export const updateFilteredConversationsAction = createAction(
)<{filter: ConversationFilter}>();

export const setSearch = (currentFilter: ConversationFilter, displayName: string) => {
return setFilter({
...currentFilter,
displayName,
});
const newFilter = omit({...currentFilter}, 'displayName');
return displayName && displayName.length > 0 ? setFilter({...newFilter, displayName}) : setFilter(newFilter);
};

export const setFilter = (filter: ConversationFilter) => {
Expand All @@ -50,28 +48,19 @@ export const setFilter = (filter: ConversationFilter) => {
};
};

export const resetFilter = () => {
return function (dispatch: Dispatch<any>, state: () => StateModel) {
dispatch(resetFilteredConversationAction());
const currentFilter = state().data.conversations.filtered.currentFilter;
const newFilter: ConversationFilter = {displayName: currentFilter.displayName};
executeFilter(newFilter, dispatch, state);
};
};

const executeFilter = (filter: ConversationFilter, dispatch: Dispatch<any>, state: () => StateModel) => {
dispatch(updateFilteredConversationsAction(filter));
refetchConversations(dispatch, state);
};

const refetchConversations = (dispatch: Dispatch<any>, state: () => StateModel, cursor?: string) => {
dispatch(loadingConversationsAction());
dispatch(loadingConversationsAction(true));
const filter = state().data.conversations.filtered.currentFilter;
if (Object.keys(filter).length > 0) {
delay(() => {
if (isEqual(filter, state().data.conversations.filtered.currentFilter)) {
return HttpClientInstance.listConversations({
page_size: 10,
page_size: 50,
cursor,
filters: filterToLuceneSyntax(filter),
}).then((response: PaginatedResponse<Conversation>) => {
Expand All @@ -85,9 +74,11 @@ const refetchConversations = (dispatch: Dispatch<any>, state: () => StateModel,
}
});
}
dispatch(loadingConversationsAction(false));
}, 100);
} else {
dispatch(resetFilteredConversationAction());
dispatch(loadingConversationsAction(false));
}
};

Expand Down
Loading

0 comments on commit 087774f

Please sign in to comment.