Skip to content

Commit 91dcafa

Browse files
Merge branch 'release/0.53.0' into main
2 parents 999a84d + 8c006f1 commit 91dcafa

File tree

80 files changed

+1009
-402
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1009
-402
lines changed

README.md

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<p align="center">
22
<img src="https://global-uploads.webflow.com/5e9d5014fb5d85233d05fa23/5ea6ab4327484b79bdb4cea4_airy_primary_rgb.svg" alt="Airy-logo" width="240">
33
<div align="center">The open source, fully-featured, production ready</div>
4-
<div align="center">Conversational Platform</div>
4+
<div align="center">Data Platform</div>
55
</p>
66

77
# Airy Core
@@ -15,10 +15,9 @@
1515

1616
---
1717

18-
![Airy_Explainer_Highlevel_Readme](https://user-images.githubusercontent.com/124274/113720584-18a8d500-96ef-11eb-97c3-362eebd6253d.jpeg)
18+
![Airy_Explainer_Highlevel_Readme](https://airy.co/docs/core/img/getting-started/introduction-light.png)
1919

20-
Airy Core is an open source, fully-featured, production ready conversational
21-
platform. With Airy you can process conversational data from a variety of
20+
Airy Core is an is an open-source streaming app framework to train ML models and supply them with historical and real-time data. With Airy you can process data from a variety of
2221
sources:
2322

2423
- **Facebook**
@@ -27,26 +26,25 @@ sources:
2726
- **SMS**
2827
- **Website Chat Plugins, like our own open source Live Chat**
2928
- **Twilio**
30-
- **Your own conversational channels**
29+
- **Any source you want with Custom Connectors**
3130

3231
You can then use Airy to:
3332

34-
- **Unify your messaging channels**
35-
- **Stream your conversational data wherever you want**
36-
- **Integrate with different NLP frameworks**
37-
- **Mediate open requests with Agents via our messaging UI**
38-
- **Analyze your conversations**
33+
- **Join historical and real-time data in the stream to create smarter ML and AI applications.**
34+
- **Build real-time data pipelines and make real-time data universally accessible with our open-source streaming app framework.**
35+
- **Standardize complex data ingestion and consume data directly from Kafka. Stream it directly to standard and customized applications, using pre-built, easily configured connectors.**
36+
- **Significantly simplify deployment and reduce development times and increase the robustness of your infrastructure and apps.**
3937

4038
Since Airy's infrastructure is built around Apache Kafka, it can process a large
41-
amount of conversations and messages simultaneously and stream the relevant
42-
conversational data to wherever you need it.
39+
amount of events simultaneously and stream the relevant
40+
real-time and historical data to wherever you need it.
4341

4442
---
4543

4644
## About Airy
4745

4846
- **What does Airy do? 🚀**
49-
[Learn more on our Website](https://airy.co/developers)
47+
[Learn more on our Website](https://airy.co/)
5048

5149
- **I'm new to Airy 😄**
5250
[Get Started with Airy](https://airy.co/docs/core/)
@@ -69,38 +67,30 @@ conversational data to wherever you need it.
6967

7068
![Airy_Explainer_Components_Readme (1)](https://user-images.githubusercontent.com/12533283/112460661-6de3fe80-8d5f-11eb-8274-8446fbfcf5c8.png)
7169

72-
Airy Core contains the following components:
70+
Airy Core comes with all the components you need to stream historical and real-time data.
7371

74-
- 💬 Connectors for all [conversational sources](https://airy.co/docs/core/sources/introduction)
72+
- 💬 Pre-built and easily configurable [connectors](https://airy.co/docs/core/sources/introduction)
7573

76-
Connect anything from our free open-source [live chat
77-
plugin](https://airy.co/docs/core/sources/chat-plugin) to Facebook
78-
Messenger & Google's Business Messages to your Airy Core. This is
79-
all possible through an ingestion platform that heavily relies on [Apache
80-
Kafka](https://kafka.apache.org) to process incoming webhook data from different
81-
sources. We make sense of the data and reshape it into source independent
82-
contacts, conversations, and messages.
74+
By ingesting all real-time events and continuously processing, aggregating and joining them in the stream, development time can be significantly reduced. Through integrations with pre-built and easily configured connectors, events are consumed from any source, including business systems such as ERP/CRM, conversational sources, third party APIs. Airy also comes with an SDK to build custom connectors to any source.
8375

8476
-[APIs](https://airy.co/docs/core/api/introduction) to access your data
8577

86-
An [API](https://airy.co/docs/core/api/introduction) to access conversational
78+
An [API](https://airy.co/docs/core/api/introduction) to access
8779
data with blazing fast HTTP endpoints.
8880

8981
- 🔌[WebSockets](https://airy.co/docs/core/api/websocket) to power real-time applications
9082

9183
A [WebSocket server](https://airy.co/docs/core/api/websocket) that allows
9284
clients to receive near real-time updates about data flowing through the system.
9385

94-
- 🎣[Webhook](https://airy.co/docs/core/api/webhook) to listen to events and participate programmatically in conversations
86+
- 🎣[Webhook](https://airy.co/docs/core/api/webhook) to listen to events and create actionable workflows
9587

96-
A webhook integration server that allows its users to programmatically
97-
participate in conversations by sending messages (the webhook integration
88+
A webhook integration server that allows its users to create actionable workflows (the webhook integration
9889
exposes events users can "listen" to and react programmatically.)
9990

100-
- 💎[UI: From an inbox to dashboards](https://airy.co/docs/core/apps/ui/introduction)
91+
- 💎[UI: From a control center to dashboards](https://airy.co/docs/core/apps/ui/introduction)
10192

102-
Not every message can be handled by code, this is why Airy comes with different
103-
UIs ready for you and your teams to use.
93+
No-code interfaces to manage and control Airy, your connectors and your streams.
10494

10595
## How to contribute
10696

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.52.0
1+
0.53.0

backend/components/cognigy/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ app_deps = [
1515
"//backend/model/metadata",
1616
"//:feign",
1717
"//lib/java/log",
18+
"//lib/java/sources-parser",
1819
"//lib/java/spring/kafka/core:spring-kafka-core",
1920
"//lib/java/spring/core:spring-core",
2021
"//lib/java/spring/kafka/streams:spring-kafka-streams",

backend/components/cognigy/src/main/java/co/airy/core/cognigy_connector/MessageHandler.java

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import co.airy.avro.communication.Message;
55
import co.airy.core.cognigy.models.MessageSendResponse;
66
import com.fasterxml.jackson.core.JsonProcessingException;
7-
import com.fasterxml.jackson.databind.JsonNode;
87
import com.fasterxml.jackson.databind.ObjectMapper;
9-
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
10-
import com.fasterxml.jackson.databind.node.ObjectNode;
8+
import com.fasterxml.jackson.databind.JsonNode;
119
import org.springframework.stereotype.Service;
10+
import co.airy.sources_parser.SourcesParser;
1211

1312
import java.time.Instant;
1413
import java.util.Map;
@@ -47,47 +46,10 @@ public String getContent(String source, MessageSendResponse response) throws Jso
4746
final String text = messageNode.get("text").textValue();
4847
final JsonNode data = messageNode.findValue("data");
4948

50-
final ObjectNode node = getNode();
51-
switch (source) {
52-
case "google": {
53-
final ObjectNode representative = getNode();
54-
representative.put("representativeType", "BOT");
55-
node.set("representative", representative);
56-
node.put("text", text);
57-
return mapper.writeValueAsString(node);
58-
}
59-
case "viber": {
60-
node.put("text", text);
61-
node.put("type", "text");
62-
return mapper.writeValueAsString(node);
63-
}
64-
case "chatplugin":
65-
case "instagram":
66-
case "facebook": {
67-
node.put("text", text);
68-
if(!data.isEmpty()){
69-
node.put("message", data);
70-
}
71-
return mapper.writeValueAsString(node);
72-
}
73-
case "twilio.sms":
74-
case "twilio.whatsapp": {
75-
node.put("Body", text);
76-
return mapper.writeValueAsString(node);
77-
}
78-
case "whatsapp": {
79-
node.put("Body", text);
80-
return mapper.writeValueAsString(node);
81-
}
82-
83-
default: {
84-
return null;
85-
}
49+
if(text == null && data == null){
50+
return null;
8651
}
87-
}
8852

89-
private ObjectNode getNode() {
90-
final JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
91-
return jsonNodeFactory.objectNode();
53+
return SourcesParser.mapContent(source, text, data);
9254
}
9355
}

backend/components/ibm-watson-assistant/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ app_deps = [
1515
"//backend/model/metadata",
1616
"//:feign",
1717
"//lib/java/log",
18+
"//lib/java/sources-parser",
1819
"//lib/java/spring/kafka/core:spring-kafka-core",
1920
"//lib/java/spring/core:spring-core",
2021
"//lib/java/spring/kafka/streams:spring-kafka-streams",
Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import co.airy.avro.communication.Message;
55
import co.airy.core.ibm_watson_assistant.models.MessageSendResponse;
66
import co.airy.log.AiryLoggerFactory;
7+
import co.airy.sources_parser.SourcesParser;
78
import com.fasterxml.jackson.core.JsonProcessingException;
89
import com.fasterxml.jackson.databind.JsonNode;
910
import com.fasterxml.jackson.databind.ObjectMapper;
10-
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
11-
import com.fasterxml.jackson.databind.node.ObjectNode;
1211
import org.springframework.stereotype.Service;
1312
import org.slf4j.Logger;
1413

@@ -54,51 +53,17 @@ public String getContent(String source, MessageSendResponse response) throws Jso
5453
text = nestedNode.get("text").textValue();
5554
}
5655

57-
if (text != "") {
58-
final ObjectNode node = getNode();
59-
switch (source) {
60-
case "google": {
61-
final ObjectNode representative = getNode();
62-
representative.put("representativeType", "BOT");
63-
node.set("representative", representative);
64-
node.put("text", text);
65-
return mapper.writeValueAsString(node);
66-
}
67-
case "viber": {
68-
node.put("text", text);
69-
node.put("type", "text");
70-
return mapper.writeValueAsString(node);
71-
}
72-
case "chatplugin":
73-
case "instagram":
74-
case "facebook": {
75-
node.put("text", text);
76-
return mapper.writeValueAsString(node);
77-
}
78-
case "twilio.sms":
79-
case "twilio.whatsapp": {
80-
node.put("Body", text);
81-
return mapper.writeValueAsString(node);
82-
}
83-
case "whatsapp": {
84-
node.put("Body", text);
85-
return mapper.writeValueAsString(node);
86-
}
87-
88-
default: {
89-
return null;
90-
}
91-
}
56+
if (text == null) {
57+
return null;
9258
}
59+
60+
return SourcesParser.mapContent(source, text, null);
61+
62+
9363
} catch (Exception e) {
9464
log.error(String.format("could not find the text node in the response %s %s", response.toString(), e));
9565
}
9666

9767
return null;
9868
}
99-
100-
private ObjectNode getNode() {
101-
final JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
102-
return jsonNodeFactory.objectNode();
103-
}
10469
}

backend/components/rasa/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ app_deps = [
1515
"//backend/model/metadata",
1616
"//:feign",
1717
"//lib/java/log",
18+
"//lib/java/sources-parser",
1819
"//lib/java/spring/kafka/core:spring-kafka-core",
1920
"//lib/java/spring/core:spring-core",
2021
"//lib/java/spring/kafka/streams:spring-kafka-streams",

backend/components/rasa/src/main/java/co/airy/core/rasa_connector/MessageHandler.java

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@
33
import co.airy.avro.communication.DeliveryState;
44
import co.airy.avro.communication.Message;
55
import co.airy.core.rasa_connector.models.MessageSendResponse;
6-
import com.fasterxml.jackson.core.JsonProcessingException;
76
import com.fasterxml.jackson.databind.ObjectMapper;
8-
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
97
import com.fasterxml.jackson.databind.node.ObjectNode;
8+
import com.fasterxml.jackson.databind.JsonNode;
9+
import com.fasterxml.jackson.core.JsonProcessingException;
1010
import org.springframework.stereotype.Service;
11+
import co.airy.sources_parser.SourcesParser;
12+
1113

1214
import java.time.Instant;
1315
import java.util.Map;
1416
import java.util.UUID;
1517

1618
@Service
1719
public class MessageHandler {
18-
private final ObjectMapper mapper = new ObjectMapper();
1920

2021
MessageHandler() {
2122
}
@@ -40,50 +41,34 @@ public Message getMessage(Message contactMessage, MessageSendResponse response)
4041
.build();
4142
}
4243

44+
45+
4346
public String getContent(String source, MessageSendResponse response) throws JsonProcessingException {
4447
final String text = response.getText();
45-
if (text == null) {
48+
final String image = response.getImage();
49+
50+
ObjectMapper mapper = new ObjectMapper();
51+
ObjectNode rootNode = mapper.createObjectNode();
52+
ObjectNode childNode1 = mapper.createObjectNode();
53+
ObjectNode childNode2 = mapper.createObjectNode();
54+
55+
if (text == null && image == null) {
4656
return null;
4757
}
4858

49-
final ObjectNode node = getNode();
50-
switch (source) {
51-
case "google": {
52-
final ObjectNode representative = getNode();
53-
representative.put("representativeType", "BOT");
54-
node.set("representative", representative);
55-
node.put("text", text);
56-
return mapper.writeValueAsString(node);
57-
}
58-
case "viber": {
59-
node.put("text", text);
60-
node.put("type", text);
61-
return mapper.writeValueAsString(node);
62-
}
63-
case "chatplugin":
64-
case "instagram":
65-
case "facebook": {
66-
node.put("text", text);
67-
return mapper.writeValueAsString(node);
68-
}
69-
case "twilio.sms":
70-
case "twilio.whatsapp": {
71-
node.put("Body", text);
72-
return mapper.writeValueAsString(node);
73-
}
74-
case "whatsapp": {
75-
node.put("Body", text);
76-
return mapper.writeValueAsString(node);
77-
}
59+
if(image != null){
60+
childNode1.put("type", "image");
61+
childNode2.put("url", image);
62+
childNode1.put("payload", childNode2);
63+
rootNode.put("attachment", childNode1);
64+
JsonNode imageJsonNode = mapper.convertValue(rootNode, JsonNode.class);
7865

79-
default: {
80-
return null;
81-
}
66+
return SourcesParser.mapContent(source, text, imageJsonNode);
67+
} else {
68+
return SourcesParser.mapContent(source, text, null);
8269
}
83-
}
8470

85-
private ObjectNode getNode() {
86-
final JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
87-
return jsonNodeFactory.objectNode();
71+
8872
}
73+
8974
}

backend/components/websocket/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ app_deps = [
1313
"//backend/model/metadata",
1414
"//backend/model/tag",
1515
"//lib/java/date",
16+
"//lib/java/kafka/schema:ops-application-components",
1617
"//lib/java/spring/auth:spring-auth",
1718
"//lib/java/spring/web:spring-web",
1819
"//lib/java/spring/kafka/core:spring-kafka-core",

backend/components/websocket/src/main/java/co/airy/core/api/websocket/Stores.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import co.airy.kafka.schema.application.ApplicationCommunicationMessages;
99
import co.airy.kafka.schema.application.ApplicationCommunicationMetadata;
1010
import co.airy.kafka.schema.application.ApplicationCommunicationTags;
11+
import co.airy.kafka.schema.ops.OpsApplicationComponents;
1112
import co.airy.kafka.streams.KafkaStreamsWrapper;
1213
import co.airy.model.metadata.dto.MetadataMap;
1314
import org.apache.kafka.streams.KeyValue;
@@ -53,6 +54,12 @@ public void onApplicationEvent(ApplicationStartedEvent event) {
5354
.toStream()
5455
.peek((identifier, metadataMap) -> webSocketController.onMetadata(metadataMap));
5556

57+
builder.<String, Metadata>table(new OpsApplicationComponents().name())
58+
.groupBy((metadataId, metadata) -> KeyValue.pair(getSubject(metadata).getIdentifier(), metadata))
59+
.aggregate(MetadataMap::new, MetadataMap::adder, MetadataMap::subtractor)
60+
.toStream()
61+
.peek((identifier, metadataMap) -> webSocketController.onComponentUpdate(metadataMap));
62+
5663
streams.start(builder.build(), appId);
5764
}
5865

0 commit comments

Comments
 (0)