I am creating a chatbot using Java and program ab. In few places I can’t answer the questions directly, I have to process something or call a web service and process the result and then reply back. In such cases how to include the result of my java function to the responses in the aiml.
Say,
User: What is the price of the product A?
Bot: The price of product A is $50
In the above example, $50 is not going to be same always. I have to take that in run time. So how to solve this problem?
**AIML:**
<category>
<pattern>WHAT IS THE PRICE OF THE *</pattern>
<template>The price of <star/> is $<call some function price(productA)>
</template>
</category>
**JAVA:**
public int price(String product){
// gets the product price
// do the conversion
// apply discount
return price;
}
Please someone help me. Thanks in advance.
Typically AIML extensions are implemented as an extension tag. So you wouldn't call a programming language method/function directly from AIML script. In the AB documentation you can find more details about implementing this kind of functionality here. Below is the relevant text with an updated link to PCAIMLProcessorExtension found in a forked project on GitHub. There a couple of practical examples on of working extensions can be found.
AIMLProcessorExtension
Program AB defines a Java Interface called AIMLProcessorExtension that
you can use to define new AIML tags.
A class implementing AIMLProcessorExtension must provide:
a Set of tag names.
a function to recursively evaluate the XML parse tree for each node associated with a new tag.
The Program AB source
includes a sample implementation of this interface called
PCAIMLProcessorExtension, which defines a collection of tags
simulating a contacts database.
There is a simple and general option, you can keep a keyword to be used in switch later on, e.g.
AIML template will have a keyword for operation,
<category>
<pattern>WHAT IS THE PRICE OF THE *</pattern>
<template>PRICE,The price of <star/> is,<star/> </template>
And update java code like:
String response = aimlResponse(request);
String [] responseComponents = reponse.parse(",");
String method = responseComponents[0];
//Then use switch, also apply size check on array after parsing in case of response with No keywords
Switch method:
{
case PRICE:
//here add the price to response string
String price = price(responseComponents[2]);
response = responseComponents[1]+ price;
break;
}
Related
I am by no means experienced in programming, but I can trial and error my way through some basic code. I am currently working on integrating a couple of my business application via Zapier or make (integromat) and I always get stuck on field mapping in bulk.
Right now, I am trying to create a two-way sync between my "loan origination system" and "Monday.com" (project management system) and I am using "AirTable" as a mid point to store/hold the data.
The flow looks like this: Loan Orignation System -> Airtable -> Monday.com.
In reverse, the flow is: Monday.com -> Airtable -> Loan Origination System.
I always get stuck when I have "picklists" or "enums" - basically drop down fields that have different values in both systems.
I know I can use a lookup table in zapier but there are so many fields that it would be nearly impossible and also impracticle to add that many lookup table steps to get transformed values.
Here is an example of what is being passed from the loan origination system -
Field: "propertyType" (Display Name is "Property Type")
Potential Values:
SINGLE_FAMILY_DETACHED,
SINGLE_FAMILY_ATTACHED,
TWO_UNIT,
THREE_UNIT,
FOUR_UNIT,
MANUFACTURED_SINGLE_WIDE,
MANUFACTURED_DOUBLE_WIDE
Now in Monday.com, I have the same field listed as a status field called "Property Type" and the values are the normalized names or display names for these values. So the following:
Monday.com Property Type Status Field Options
"Single Family Detached",
"Single Family Attached",
"Two Unit",
"Three Unit",
"Four Unit",
"Manufactured Single Wide",
"Manufactured Double Wide"
Is there any good way to transform the values for all the possible inputs/outputs for either direction without having to make a million zap steps for all the fields that function this way?
It is a systems integration problem, and I don't have a ton of money to buy a fancy tool. We have zapier, airtable, integromat, etc. And the tools do not have open API's at the moment so I have to work through these tools.
Any help or guidance is super appreciated!
When using Code by Zapier (JavaScript), usually it is a good idea to put some guarantees in your code right up front. This piece of code sets 'defaults' for the inputData keys:
// ☸
class DefaultKeys {
constructor(keys={}){Object.assign(this,{
propertyType : 'default_value',
loanType : 'default_value'
}, keys)}
}
let values = new DefaultKeys(inputData)
// ☸
Now to your actual question... It is possible to use switch() like the lookups provided by Zapier:
let newPropertyType = switch (propertyType) {
case 'SINGLE_FAMILY_DETACHED':
'Single Family Detached' // a function could also make this transformation
break;
case 'SINGLE_FAMILY_ATTACHED':
'Single Family Attached'
default:
'default_value';
}
So then copy that section for each of your different 'keys'.
Lastly, output your results for the next Zapier actions to access:
output = {propertyType: newPropertyType, loanType: newLoanType};
I want to learn which promotions were applied to which products on promotionengine in order to distribute prices on products amongst themselves and send them to ERP.
When we look at the promotionService in Hybris, there is a method called getPromotionResults(order). It returns PromotionOrderResults object. In this object, two methods are related to my case, getAppliedProductPromotions() and getAppliedOrderPromotions().
If I did not miss it, I could not see product info for a promotion in these methods' results. Also, I looked at all attributes via promotion.getAppliedOrderPromotions().get(0).getAllAttributes() but i could not have them.
How can I know product info and discount amount in a promotion?
The method you are looking for is
PromotionOrderResults#getAppliedProductPromotions()
This will return all the promotions applied to order entries / products, you can navigate to the products via PromotionOrderEntryConsumed PromotionResult#getConsumedEntries()
I have a way to get the product that was Added as free gift on a promotion... Usually is something like this
Set promotionResultModels = cart.getAllPromotionResults();
if (!Objects.isNull(promotionResultModels))
{
Iterator resultsIterator = promotionResultModels.iterator();
while (resultsIterator.hasNext())
{
PromotionResultModel promoResultModel = (PromotionResultModel) resultsIterator.next();
Iterator var6 = promoResultModel.getActions().iterator();
while (var6.hasNext())
{
AbstractPromotionActionModel action = (AbstractPromotionActionModel) var6.next();
if (action instanceof RuleBasedOrderAddProductActionModel)
{
String freeGiftProductCode = ((RuleBasedOrderAddProductActionModel) action).getProduct().getCode();
}
}
}
}
However in my scenario, this is Free Gift promotion, not sure if the Bundle Based Promotion might have similar properties. As per the product that actually FIRED the promotion, I'm still looking a way to get it. The closest I've been is with this:
((RuleBasedOrderAddProductActionModel) action).getRule().getRuleContent()
However that's the Hybris Generated Code that has the RAO's and the product codes are buried within that string. So I needed to write an ugly script parser to find the codes.
Let me know if you find out the second part, the Products that triggered the promos, I'm still looking for it too.
I am trying to add a function to a JSONJavaObject and calling it from a control on an xpage.
so far I have:
json = (JsonJavaObject) JsonParser.fromJson(factory, colJson);
String func = "function () { alert('you clicked?'); }";
json.put("onClick", new JsonReference(func) );
In the first line I add key-value pairs from a column in a Notes view.
In the second line I define the function as a string.
In the last line I place the converted string as function in the jsonjava object.
I read about this in the following blog post:
http://camerongregor.com/2016/01/19/doublequoteavoidance/
In the next step I bind the function to e.g. a button control as followed:
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[obj.onClick]]></xp:this.script>
</xp:eventHandler>
</xp:button>
obj is the respresentation of the JSONJava object in SSJS.
But without success. Anyone know how I can call the function in the object?
I hope I will make sense here, let me know if anything to clarify.
If you are simply trying to dynamically output the client side script of a button event, then you don't need to use JsonReference at all. You can just use a String.
In my blog article I might not have make it clear why I needed to use JsonReference. I was using it in the process of rendering a custom UIComponent, part of this process required generating a Json object client side. To do this I created the JsonJavaObject as you did and then asked it to be turned into a string with the 'toJson' method. My problem was that when I asked the whole object to become a string, every property of that object that was a String, would begin and end with a double quote. I needed to ensure that the properties which were intended to be functions did not begin and end with "". By using the JsonReference the JsonGenerator became aware of my intention not to include these double quotes.
In your case, it looks as though you are just trying to dynamically determine what happens with onClick. To do this you could simply use a String instead of the JsonReference. The inclusion of the 'function() {}' is unnecessary as this will be generated when the event handler is rendered at the end of the page.
For Example here would be the Json Java Object
JsonJavaObject obj = new JsonJavaObject();
String func = " alert('you clicked?'); ";
obj.put("onClick", func);
return obj;
And here would be the button:
<xp:button id="button1" value="Alert Me">
<xp:eventHandler event="onclick" submit="false"
script="#{javascript: myBean.myObject.get('onClick')}">
</xp:eventHandler>
</xp:button>
This should give you the end result of seeing 'you clicked?' alert.
You can also inspect how this has all been generated in the script block near the end of the page using 'view Source' or your favourite web browser developer tools:
function view__id1__id2_clientSide_onclick(thisEvent) {
alert('you clicked?');
}
XSP.addOnLoad(function() {
XSP.attachEvent("view:_id1:_id2", "view:_id1:button1", "onclick",
view__id1__id2_clientSide_onclick, false, 2);
});
Let me know if anything isn't clear, hope it helps!
Does obj.onClick already give you a handle to the function returned by the Java class? If it does then you should be able to call it using the call or apply methods that are available in JavaScript:
obj.onClick.call();
obj.onClick.apply();
More details about those two methods can be found here: What is the difference between call and apply?
Can anyone give me at least one idea to how can I connect java with protoge?
how can I access OWL using jena API in java?!
The Jena website has plenty of tutorials available. If you have difficulties getting started, please post the code that does not work and we'll help you along.
First tutorial here
// some definitions
static String personURI = "http://somewhere/JohnSmith";
static String fullName = "John Smith";
// create an empty Model
Model model = ModelFactory.createDefaultModel();
// create the resource
Resource johnSmith = model.createResource(personURI);
// add the property
johnSmith.addProperty(VCARD.FN, fullName);
In order to make this work, you'll need the right imports. Assuming that the Java technicalities are not a problem, this example shows how to create a statement and add it to a model, i.e., an rdf file.
From the same page you can get to more complex material, including OWL tutorials.
You have not mentioned which task you're trying to carry out. Can you describe it?
When I create a new ARB subscription the response comes back and I save the id it gives us. I tried it out and it gives us back "33".
Then when the silent post callback hits our method, the response has a different id, 15631016.
15631016 is correct in matching up with the one we see in the authorize.net online portal.
So, what is 33 and why doesn't it return the real ARB ID?
Here is the code that creates the new ARB and then gets the arbId:
net.authorize.arb.Transaction arbTransaction = createARBTransaction(startDate.getTime(), creditCard, member, splitOccurrences.intValue() - 1, splitUnit, useBillingAddress, billingAddress, recurringOrder.getTotalAmount().doubleValue(), recurringOrder);
net.authorize.arb.Result<?> arbResult = (net.authorize.arb.Result<?>) merchant.postTransaction(arbTransaction);
String arbId;
if (arbResult.isOk()) {
arbId = arbResult.getResultSubscriptionId();
}
If getResultSubscriptionId() is not the correct way to get the new ARB subscription ID, what is the correct method to use?
I went through the sample code and also their community and there isn't much to go on. The only thing I can think of trying is changing:
arbResult.getResultSubscriptionId();
to:
arbTransaction.getResultSubscriptionId();
I know that doesn't sound logical but it's the best I can some up with.
According to the source code, you are using the correct method.
If you trace the calls back into the code you'll see that the subscription id gets set by the following call in importResponseMessages() of net.authorize.arb.Result
getElementText(txn.getCurrentResponse().getDocumentElement(),AuthNetField.ELEMENT_SUBSCRIPTION_ID.getFieldName());
so if you call this on your arbResult variable, you might get closer. Note that txn should be replaced by your variable arbTransaction.
Alternatively, you can dig into the response itself to see why the Authorize.net APK isn't returning the correct subscription id.
xml = arbTransaction.getCurrentResponse().dump(true);
The true determines whether the XML tree is collapsed. xml should be a string containing your XML response from authorize.net