Skip to content

Commit fe20bae

Browse files
committed
v13.5.0
1 parent 2de9530 commit fe20bae

File tree

8 files changed

+224
-17
lines changed

8 files changed

+224
-17
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ repositories {
5656

5757
dependencies {
5858
implementation "com.facebook.react:react-native:+"
59-
implementation group: 'io.gleap', name: 'gleap-android-sdk', version: '13.2.2'
59+
implementation group: 'io.gleap', name: 'gleap-android-sdk', version: '13.5.0'
6060

6161
if(rootProject && rootProject.ext) {
6262
if(rootProject.ext.targetSdkVersion == 30 || rootProject.ext.compileSdkVersion == 30) {

android/src/main/java/com/reactnativegleapsdk/GleapsdkModule.java

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131
import java.util.regex.Pattern;
3232

3333
import io.gleap.APPLICATIONTYPE;
34+
import io.gleap.GleapAiTool;
35+
import io.gleap.GleapAiToolParameter;
3436
import io.gleap.GleapSessionProperties;
3537
import io.gleap.SurveyType;
38+
import io.gleap.callbacks.AiToolExecutedCallback;
3639
import io.gleap.callbacks.GetActivityCallback;
3740
import io.gleap.Gleap;
3841
import io.gleap.GleapActivationMethod;
@@ -117,6 +120,14 @@ public void invoke() {
117120
}
118121
});
119122

123+
Gleap.getInstance().setAiToolExecutedCallback(new AiToolExecutedCallback() {
124+
@Override
125+
public void aiToolExecuted(JSONObject jsonObject) {
126+
getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
127+
.emit("toolExecution", jsonObject);
128+
}
129+
});
130+
120131
Gleap.getInstance().setWidgetClosedCallback(new WidgetClosedCallback() {
121132
@Override
122133
public void invoke() {
@@ -841,6 +852,88 @@ public void setCustomData(String key, String value) {
841852
Gleap.getInstance().setCustomData(key, value);
842853
}
843854

855+
/**
856+
* Set the ai tools.
857+
* @param tools
858+
*/
859+
@ReactMethod
860+
public void setAiTools(ReadableArray tools) {
861+
try {
862+
if (Gleap.getInstance() == null) {
863+
return;
864+
}
865+
866+
ArrayList<GleapAiTool> gleapAiTools = new ArrayList<>();
867+
868+
// Loop through the tools array
869+
for (int i = 0; i < tools.size(); i++) {
870+
ReadableMap tool = tools.getMap(i);
871+
if (tool == null) continue;
872+
873+
String name = tool.getString("name");
874+
String description = tool.getString("description");
875+
String response = tool.getString("response");
876+
ReadableArray parametersArray = tool.getArray("parameters");
877+
ArrayList<GleapAiToolParameter> gleapParameters = new ArrayList<>();
878+
879+
if (parametersArray != null) {
880+
// Loop through the parameters array
881+
for (int j = 0; j < parametersArray.size(); j++) {
882+
ReadableMap parameter = parametersArray.getMap(j);
883+
if (parameter == null) continue;
884+
885+
String paramName = parameter.getString("name");
886+
String paramDescription = parameter.getString("description");
887+
String type = parameter.getString("type");
888+
boolean required = parameter.getBoolean("required");
889+
String[] enums = null;
890+
if (parameter.hasKey("enum") && !parameter.isNull("enum")) {
891+
ReadableArray enumsArray = parameter.getArray("enum");
892+
enums = new String[enumsArray.size()];
893+
for (int k = 0; k < enumsArray.size(); k++) {
894+
enums[k] = enumsArray.getString(k);
895+
}
896+
}
897+
898+
// Create a new parameter and add it to the list
899+
GleapAiToolParameter gleapParameter = new GleapAiToolParameter(
900+
paramName, paramDescription, type, required, enums);
901+
gleapParameters.add(gleapParameter);
902+
}
903+
}
904+
905+
// Create the AI tool with parameters
906+
GleapAiToolParameter[] paramsArray = new GleapAiToolParameter[gleapParameters.size()];
907+
paramsArray = gleapParameters.toArray(paramsArray);
908+
GleapAiTool gleapAiTool = new GleapAiTool(
909+
name, description, response, paramsArray);
910+
911+
// Add the AI tool to the list
912+
gleapAiTools.add(gleapAiTool);
913+
}
914+
915+
// Convert the list to an array and set the AI tools
916+
GleapAiTool[] toolsArray = new GleapAiTool[gleapAiTools.size()];
917+
toolsArray = gleapAiTools.toArray(toolsArray);
918+
Gleap.getInstance().setAiTools(toolsArray);
919+
920+
} catch (Exception e) {
921+
System.out.println("Error setting AI tools: " + e);
922+
}
923+
}
924+
925+
/**
926+
* Set the value for a ticket attribute with key.
927+
*
928+
* @param value The value you want to add
929+
* @param key The key of the attribute
930+
* @author Gleap
931+
*/
932+
@ReactMethod
933+
public void setTicketAttribute(String key, String value) {
934+
Gleap.getInstance().setTicketAttribute(key, value);
935+
}
936+
844937
/**
845938
* Removes one key from existing custom data.
846939
*

example/index.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,40 @@ import App from './App';
77
import { name as appName } from './app.json';
88
import Gleap from 'react-native-gleapsdk';
99

10-
Gleap.initialize('ogWhNhuiZcGWrva5nlDS8l7a78OfaLlV');
10+
const transactionTool = {
11+
// Name the tool. Only lowecase letters and - are allowed.
12+
name: 'send-money',
13+
// Describe the tool. This can also contain further instructions for the LLM.
14+
description: 'Send money to a given contact.',
15+
// Let the LLM know what the tool is doing. This will allow Kai to update the customer accordingly.
16+
response: 'The transfer got initiated but not completed yet. The user must confirm the transfer in the banking app.',
17+
// Specify the parameters (it's also possible to pass an empty array)
18+
parameters: [{
19+
name: 'amount',
20+
description: 'The amount of money to send. Must be positive and provided by the user.',
21+
type: 'number',
22+
required: true
23+
}, {
24+
name: 'contact',
25+
description: 'The contact to send money to.',
26+
type: 'string',
27+
enum: ["Alice", "Bob"], // Optional
28+
required: true
29+
}]
30+
};
1131

12-
Gleap.registerListener('customActionTriggered', (data) => {
32+
// Add all available tools to the array.
33+
const tools = [transactionTool];
34+
35+
// Set the AI tools.
36+
Gleap.setAiTools(tools);
37+
38+
Gleap.setTicketAttribute("note", "This is a test value.");
39+
40+
Gleap.initialize('rnKAHkPdeQBsRlZ1zh4AfbszdqqxASY0');
41+
42+
Gleap.registerListener('toolExecution', (data) => {
1343
console.log("data", data);
14-
if (data.name === 'CUSTOM_HELP') {
15-
setTimeout(() => {
16-
Gleap?.openHelpCenterCollection("1", true);
17-
}, 1500);
18-
}
1944
});
2045

2146
AppRegistry.registerComponent(appName, () => App);

example/ios/Podfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ PODS:
7272
- FlipperKit/Core
7373
- FlipperKit/FlipperKitNetworkPlugin
7474
- fmt (6.2.1)
75-
- Gleap (13.2.2)
75+
- Gleap (13.5.0)
7676
- glog (0.3.5)
7777
- hermes-engine (0.71.11):
7878
- hermes-engine/Pre-built (= 0.71.11)
@@ -330,8 +330,8 @@ PODS:
330330
- React-jsinspector (0.71.11)
331331
- React-logger (0.71.11):
332332
- glog
333-
- react-native-gleapsdk (13.2.3):
334-
- Gleap (= 13.2.2)
333+
- react-native-gleapsdk (13.5.0):
334+
- Gleap (= 13.5.0)
335335
- React-Core
336336
- React-perflogger (0.71.11)
337337
- React-RCTActionSheet (0.71.11):
@@ -591,7 +591,7 @@ SPEC CHECKSUMS:
591591
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
592592
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
593593
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
594-
Gleap: 5925886a54c9926bc29223ea64b04d671a2b28c1
594+
Gleap: f2fd0c4087e573ce6a45a625db8ae6ea61e68bd7
595595
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
596596
hermes-engine: 34c863b446d0135b85a6536fa5fd89f48196f848
597597
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
@@ -610,7 +610,7 @@ SPEC CHECKSUMS:
610610
React-jsiexecutor: 18b5b33c5f2687a784a61bc8176611b73524ae77
611611
React-jsinspector: b6ed4cb3ffa27a041cd440300503dc512b761450
612612
React-logger: 186dd536128ae5924bc38ed70932c00aa740cd5b
613-
react-native-gleapsdk: 730d824a5d36ad0dc76f6b2348140d7ac740dbbd
613+
react-native-gleapsdk: bfc353c61d1524f25769c551009336ade4f21209
614614
React-perflogger: e706562ab7eb8eb590aa83a224d26fa13963d7f2
615615
React-RCTActionSheet: 57d4bd98122f557479a3359ad5dad8e109e20c5a
616616
React-RCTAnimation: ccf3ef00101ea74bda73a045d79a658b36728a60

ios/Gleapsdk.m

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ - (void)unregisterPushMessageGroup:(NSString *)pushMessageGroup {
133133
}
134134
}
135135

136+
- (void)onToolExecution:(NSDictionary *)toolExecution {
137+
if (_hasListeners) {
138+
[self sendEventWithName:@"toolExecution" body: toolExecution];
139+
}
140+
}
141+
136142
- (void)feedbackSent:(NSDictionary *)data {
137143
if (_hasListeners) {
138144
[self sendEventWithName:@"feedbackSent" body: data];
@@ -164,7 +170,7 @@ - (void)stopObserving
164170
}
165171

166172
- (NSArray<NSString *> *)supportedEvents {
167-
return @[@"feedbackSent", @"feedbackSendingFailed", @"notificationCountUpdated", @"initialized", @"configLoaded", @"customActionTriggered", @"feedbackFlowStarted", @"widgetOpened", @"widgetClosed", @"registerPushMessageGroup", @"unregisterPushMessageGroup"];
173+
return @[@"feedbackSent", @"toolExecution", @"feedbackSendingFailed", @"notificationCountUpdated", @"initialized", @"configLoaded", @"customActionTriggered", @"feedbackFlowStarted", @"widgetOpened", @"widgetClosed", @"registerPushMessageGroup", @"unregisterPushMessageGroup"];
168174
}
169175

170176
RCT_EXPORT_METHOD(sendSilentCrashReport:(NSString *)description andSeverity:(NSString *)severity)
@@ -556,7 +562,70 @@ - (void)stopObserving
556562
});
557563
}
558564

559-
RCT_EXPORT_METHOD(setCustomData:(NSString *)key andData:(NSString *)value)
565+
RCT_EXPORT_METHOD(setTicketAttribute:(NSString *)key andValue:(NSString *)value)
566+
{
567+
dispatch_async(dispatch_get_main_queue(), ^{
568+
[Gleap setTicketAttributeWithKey: key value: value];
569+
});
570+
}
571+
572+
RCT_EXPORT_METHOD(setAiTools:(NSArray *)toolsArray) {
573+
dispatch_async(dispatch_get_main_queue(), ^{
574+
@try {
575+
NSMutableArray *aiTools = [[NSMutableArray alloc] init];
576+
577+
for (NSDictionary *toolDict in toolsArray) {
578+
// Safely unwrap tool dictionary properties
579+
NSString *name = toolDict[@"name"];
580+
NSString *toolDescription = toolDict[@"description"];
581+
NSString *response = toolDict[@"response"];
582+
NSArray *parametersArray = toolDict[@"parameters"];
583+
584+
if (name && toolDescription && response && parametersArray) {
585+
NSMutableArray *parameters = [[NSMutableArray alloc] init];
586+
587+
for (NSDictionary *paramDict in parametersArray) {
588+
// Safely unwrap parameter dictionary properties
589+
NSString *paramName = paramDict[@"name"];
590+
NSString *paramDescription = paramDict[@"description"];
591+
NSString *type = paramDict[@"type"];
592+
NSNumber *required = paramDict[@"required"];
593+
NSArray *enums = paramDict[@"enum"];
594+
if (enums == nil) {
595+
enums = [[NSArray alloc] init];
596+
}
597+
598+
// Check for required properties in parameter dictionary
599+
if (paramName && paramDescription && type && required) {
600+
GleapAiToolParameter *parameter = [[GleapAiToolParameter alloc]
601+
initWithName:paramName
602+
parameterDescription:paramDescription
603+
type:type
604+
required:[required boolValue]
605+
enums:enums];
606+
607+
[parameters addObject:parameter];
608+
}
609+
}
610+
611+
GleapAiTool *aiTool = [[GleapAiTool alloc]
612+
initWithName:name
613+
toolDescription:toolDescription
614+
response:response
615+
parameters:parameters];
616+
617+
[aiTools addObject:aiTool];
618+
}
619+
}
620+
621+
[Gleap setAiTools:aiTools];
622+
} @catch (NSException *exception) {
623+
624+
}
625+
});
626+
}
627+
628+
RCT_EXPORT_METHOD(setCustomData:(NSString *)key andValue:(NSString *)value)
560629
{
561630
dispatch_async(dispatch_get_main_queue(), ^{
562631
[Gleap setCustomData: value forKey: key];

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-gleapsdk",
3-
"version": "13.2.4",
3+
"version": "13.5.0",
44
"description": "Know exactly why and how a bug happened. Get reports with screenshots, live action replays and all of the important metadata every time.",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

react-native-gleapsdk.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ Pod::Spec.new do |s|
1616
s.source_files = "ios/**/*.{h,m,mm}"
1717

1818
s.dependency "React-Core"
19-
s.dependency "Gleap", "13.2.3"
19+
s.dependency "Gleap", "13.5.0"
2020
end

src/index.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ type GleapSdkType = {
100100
): void;
101101
getIdentity(): Promise<any>;
102102
isUserIdentified(): Promise<boolean>;
103+
setTicketAttribute(key: string, value: string): void;
104+
setAiTools(tools: {
105+
name: string;
106+
description: string;
107+
response: string;
108+
parameters: {
109+
name: string;
110+
description: string;
111+
type: "string" | "number" | "boolean";
112+
required: boolean;
113+
enums?: string[];
114+
}[];
115+
}[]): void;
103116
};
104117

105118
const GleapSdk = NativeModules.Gleapsdk
@@ -194,6 +207,13 @@ if (GleapSdk && !GleapSdk.touched) {
194207
} catch (exp) { }
195208
});
196209

210+
gleapEmitter.addListener('toolExecution', (data) => {
211+
try {
212+
const dataJSON = data instanceof Object ? data : JSON.parse(data);
213+
notifyCallback('toolExecution', dataJSON);
214+
} catch (exp) { }
215+
});
216+
197217
gleapEmitter.addListener('feedbackSent', (data) => {
198218
try {
199219
const dataJSON = data instanceof Object ? data : JSON.parse(data);

0 commit comments

Comments
 (0)