Customizing the Fallback Policy message - chatbot

I want to customize the default fall back message that rasa return
Did you mean Yes or no
but i couldnt find a good example or how i can ovveride is from the rasa sdk

You have to create a custom action action_default_fallback which overwrites it. This action could look like the following:
from typing import Any, Text, Dict, List
from rasa_core_sdk import Action, Tracker
from rasa_core_sdk.executor import CollectingDispatcher
from rasa_core_sdk.events import UserUtteranceReverted
class ActionFallback(Action):
def name(self) -> Text:
return "action_default_fallback"
def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
dispatcher.utter_message("Did you mean Yes or no")
return [UserUtteranceReverted()]
Add the action_default_fallback to your actions in your domain file and add this to your endpoints file to connect Rasa Core and the Rasa Core SDK:
action_endpoint:
url: "http://localhost:5055/webhook"
Then run Rasa Core with the --endpoints flag and specify the endpoints file.

Related

cucumber Gherkin issue - doesn't find the matching glue code

I am learning BDD in cucumber-eclipse. I have downloaded all the jar's but still eclipse is saying it couldn't find definition for rest of the text.
Feature: Login
Scenario: Successful Login with valid Credentials
Given user is on Homepage
When user enters Username and Password
Then He can visit the practice page
In above code, it couldn't find glue codes for below text:
user is on Homepage
user enters Username and Password
He can visit the practice page
The simplest possible start is to download or clone a getting started project by the Cucumber team https://github.com/cucumber/cucumber-java-skeleton
Run it using Maven or Gradle. When you have it running, and it runs out of the box, then add Eclipse to the mix.
Check these Options
Option 1:
Make sure you ran the code as Cucumber feature and get the skeleton generated with help of cucumber plugin
In your case, Cucumber will print like this
//Print start
#Given("^user is on Homepage$")
public void user_is_on_Homepage() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#When("^user enters Username and Password$")
public void user_enters_Username_and_Password() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#Then("^He can visit the practice page$")
public void he_can_visit_the_practice_page() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
//Print End
Create package features.stepDefinitions and then create class file "ABC.java" with above generated skeleton. Proceed to Option 2
Option 2
If below class is the Runner, we need to have the glue of the feature file folder. Usually it will be in resources folder
package test.runner
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
#CucumberOptions(
features="src/test/resources/features/featureFileFolder",
glue = { "features.stepDefinitions"},
tags={"#UI"},
monochrome=true)
public class Runner{
}
Finally execute the runner file as Junit Test
Note:
Tag UI is something we will use to link scenario and annotations.
In this case feature file will be written as.
#UI
Scenario: Successful Login with valid Credentials
Given user is on Homepage
When user enters Username and Password
Then He can visit the practice page
Hope this may help!

Creating Soap messages with objectTypes using SUDS library and MessagePlugin in Robot Framework

This a continuation for this questions: Creating Soap messages with objectTypes using SUDS library in Robot Framework
In there it was determined that with RF SUDS it is not possible to create messages with objectTypes using SUDS alone. I would like to try the MessagePlugin approach, but unfortunately the information in documentation is not quite enough for me:
from robot.libraries.BuiltIn import BuiltIn
from suds.plugin import MessagePlugin
class _MyPlugin(MessagePlugin):
def marshalled(self, context):
body = context.envelope.getChild('Body')
foo = body[0]
foo.set('id', '12345')
foo.set('version', '2.0')
class SudsLibraryExtensions(object):
def attach_my_plugin(self):
client = BuiltIn().get_library_instance("SudsLibrary")._client()
# prepend so SudsLibrary's plugin is left in place
plugins = client.options.plugins
if any(isinstance(x, _MyPlugin) for x in plugins):
return
plugins.insert(0, _MyPlugin())
client.set_options(plugins=plugins)
Does anyone have any complete Robot example on how to use the above snippet? What should I be passing into marshalled as context? Do I need to call attach_my_plugin() at some point?
A general description of message plugins can be found in the Suds documentation. More detail is in the class documentation. You do not call marshalled, suds does. To better understand how to implement the marshalled method, read up on the documentation for Element. A suds plugin is essentially a listener. My example uses a public web service for demonstration.
Say your request looks like this:
...
<ns0:Body>
<ns1:GetStatistics>
<ns1:X>
...
But you need it to look like this:
....
<ns0:Body>
<ns1:GetStatistics type="specialType">
<ns1:X>
...
Here is a plugin that adds the type attribute to the GetStatistics element. This may be necessary when an element has child elements and attributes sent. Suds 0.4 does not support this, but it is valid SOAP. There may be a fork of Suds that does support this.
*** Settings ***
Library SudsLibrary
Library c:/SudsLibraryExtensions.py
*** Test Cases ***
Message Plugin
Create Soap Client http://www.webservicex.net/Statistics.asmx?WSDL
Attach My Plugin
Set GetStats Type specialType
${dbl array}= Create Wsdl Object ArrayOfDouble
Append To List ${dbl array.double} 2.0
Append To List ${dbl array.double} 3.0
${result}= Call Soap Method GetStatistics ${dbl array}
Should Be Equal As Numbers ${result.Average} 2.5
Contents of c:/SudsLibraryExtensions.py:
from robot.libraries.BuiltIn import BuiltIn
from suds.plugin import MessagePlugin
class _MyPlugin(MessagePlugin):
def __init__(self):
self._type = 'defaultType'
def marshalled(self, context):
body = context.envelope.getChild('Body')
call = body.getChild('GetStatistics')
call.set('type', self._type)
def set_getstats_type(self, value):
self._type = value
class SudsLibraryExtensions(object):
def attach_my_plugin(self):
client = BuiltIn().get_library_instance("SudsLibrary")._client()
plugins = client.options.plugins
if any(isinstance(x, _MyPlugin) for x in plugins):
return
# prepend so SudsLibrary's plugin is left in place
plugins.insert(0, _MyPlugin())
client.set_options(plugins=plugins)
def set_getstats_type(self, value):
self._get_plugin().set_getstats_type(value)
def _get_plugin(self):
client = BuiltIn().get_library_instance("SudsLibrary")._client()
plugins = client.options.plugins
my_plugin = next((plugin for plugin in plugins if isinstance(plugin, _MyPlugin)), None)
if my_plugin is None:
raise RuntimeError("Plugin not found. Did you call Attach My Plugin?")
return my_plugin
The type attribute will always be set so long as the plugin is attached with the keyword Attach My Plugin. There is a default type. To change the value of type, the keyword Set GetStats Type is used. Any type set will be used in all future requests until it is changed. The only reason that two classes are used here is to prevent "marshalled" from becoming an exposed keyword.

Integrate SecureSocial with backend user services/storages?

Using Play! 2.0.4 and SecureSocial 2 (http://securesocial.ws/). Scala implementation. Most of this question will be directly referencing the sample here: https://github.com/jaliss/securesocial/blob/2.0.12/samples/scala/demo/app/service/InMemoryUserService.scala
I'm trying to figure out the author's original intention as to backend interaction with a storage service. With respect to the def find(id: UserId) and the def findByEmailAndProvider(email: String, providerId: String): methods, is SecureSocial expecting to give either a Facebook ID or email that can be used to return a full SocialUser class?
If that's the case, then how do we assign our own IDs to each user so that we can link accounts together? Because it seems that if I extend Identity to include a universal ID then would that also require rewriting/extending the social providers, too?
At minimum, I'm trying to figure out what API/parameters I should expose for the find and save methods in a backend service. Let me know if this question needs to be clarified :)
After having a couple days to make some design considerations and better understand SecureSocial, I realized that implementing the find and save methods were not that difficult to understand. It's properly designing the logic in a backend service that matters.
Basically, I created a PlatformUser class that extends the Identity class and includes User ID and profile data pulled from a backend class. Here's how it looks:
case class PlatformUser(
guid: String,
suspended: Boolean,
id: UserId,
firstName: String,
lastName: String,
fullName: String,
email: Option[String],
avatarUrl: Option[String],
authMethod: AuthenticationMethod,
oAuth1Info: Option[OAuth1Info] = None,
oAuth2Info: Option[OAuth2Info] = None,
passwordInfo: Option[PasswordInfo] = None,
communityProfile: Option[String] = None
) extends Identity
My object PlatformUser contains code that accesses a backend HTTP API to transfer data back and forth. Here's how I implement the find and save methods:
def find(id: UserId): Option[PlatformUser] = {
PlatformUser.fetch(id)
}
def findByEmailAndProvider(email: String, providerId: String): Option[PlatformUser] = {
PlatformUser.fetch(email, providerId)
}
def save(user: Identity): PlatformUser = {
PlatformUser.store(user)
}
The logic for merging accounts remains in the backend service as well. Now if the user doesn't already exist, the backend service generates a platform ID. If an email of an incoming Identity is found to already exist on the platform, then an auto-link of identities is performed to the existing platform ID (unless its found that the email is being used on multiple accounts for the same social network, where an error will be triggered). The user is notified by email to their primary address of the auto-link.
The last thing left is populating the communityProfile. If the backend service doesn't find one, then that field returns as None. I then automatically redirect the user to a "registration" page where they need to complete their profile.
That's about it. I hope this helps future devs who are trying to figure out more complicated uses of SecureSocial.
"If an email of an incoming Identity is found to already exist on the platform, then an auto-link of identities is performed to the existing platform ID". I am assuming when you say auto-link, this would be during sign on. If so, this would be a security flaw.
A malicious user could set his twitter email to your mail id. When he logs in using twitter, it gets "auto-linked" to your account!
See this thread for further analysis https://github.com/jaliss/securesocial/issues/14

Oreilly XMPP example codes

I was reading this book Oreilly XMPP The definitive Guide
Theres and example code in chapter 2 for an EchoBot
I want to know how i can test this code...
def main():
bot = EchoBot("echobot#wonderland.lit/HelloWorld", "mypass")
bot.run()
class EchoBot(object):
def __init__(self, jid, password):
self.xmpp = sleekxmpp.ClientXMPP(jid, password)
self.xmpp.add_event_handler("session_start", self.handleXMPPConnected)
self.xmpp.add_event_handler("message", self.handleIncomingMessage)
def run(self):
self.xmpp.connect()
self.xmpp.process(threaded=False)
def handleXMPPConnected(self, event):
self.xmpp.sendPresence(pstatus="Send me a message")
def handleIncomingMessage(self, message):
self.xmpp.sendMessage(message["jid"], message["message"])
ive installed sleekxmpp, created an account on jabber.org and replaced echobot#wonderland.lit/HelloWorld with myusername#jabber.org/HelloWorld and mypass with mypassword
But when i run this code... it doesnt seem to do anything. it jus terminates.
Is there anything im missing?
This example code does not work with new version of SleekXMPP library, because API has been changed.
Last line of your bot should be:
self.xmpp.sendMessage(message["from"], message["body"])
The author of SleekXMPP library explains changes required in example code here: https://github.com/fritzy/SleekXMPP/wiki/XMPP%3A-The-Definitive-Guide
In order to test the echo bot, you can open another Jabber Client (Psi or Kopete for example), add the echo bot to your roster and then you can chat with it like you would in any other IM scenario, only the echo bot will respond with the message that you sent it.
But be sure to visit https://github.com/fritzy/SleekXMPP/wiki/XMPP%3A-The-Definitive-Guide to see the most update version of the the books examples.

Scrapy issue with iTunes' AppStore

I am using Scrapy to fetch some data from iTunes' AppStore database. I start with this list of apps: http://itunes.apple.com/us/genre/mobile-software-applications/id36?mt=8
In the following code I have used the simplest regex which targets all apps in the US store.
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule
class AppStoreSpider(CrawlSpider):
domain_name = 'itunes.apple.com'
start_urls = ['http://itunes.apple.com/us/genre/mobile-software-applications/id6015?mt=8']
rules = (
Rule(SgmlLinkExtractor(allow='itunes\.apple\.com/us/app'),
'parse_app', follow=True,
),
)
def parse_app(self, response):
....
SPIDER = AppStoreSpider()
When I run it I receive the following:
[itunes.apple.com] DEBUG: Crawled (200) <GET http://itunes.apple.com/us/genre/mobile-software-applications/id6015?mt=8> (referer: None)
[itunes.apple.com] DEBUG: Filtered offsite request to 'itunes.apple.com': <GET http://itunes.apple.com/us/app/bloomberg/id281941097?mt=8>
As you can see, when it starts crawling the first page it says: "Filtered offsite request to 'itunes.apple.com'". and then the spider stops..
it also returns this message:
[ScrapyHTTPPageGetter,client] /usr/lib/python2.5/cookielib.py:1577: exceptions.UserWarning: cookielib bug!
Traceback (most recent call last):
File "/usr/lib/python2.5/cookielib.py", line 1575, in make_cookies
parse_ns_headers(ns_hdrs), request)
File "/usr/lib/python2.5/cookielib.py", line 1532, in _cookies_from_attrs_set
cookie = self._cookie_from_cookie_tuple(tup, request)
File "/usr/lib/python2.5/cookielib.py", line 1451, in _cookie_from_cookie_tuple
if version is not None: version = int(version)
ValueError: invalid literal for int() with base 10: '"1"'
I have used the same script for other website and I didn't have this problem.
Any suggestion? 
When I hit that link in a browser, it automatically tries to open iTunes locally. That could be the "offsite request" mentioned in the error.
I would try:
1) Remove "?mt=8" from the end of the URL. It looks like it's not needed anyway and it could have something to do with the request.
2) Try the same request in the Scrapy Shell. It's a much easier way to debug your code and try new things. More details here: http://doc.scrapy.org/topics/shell.html?highlight=interactive
I see this post is pretty old, if you haven't figured out the cause yet, here it is.
I run into a similar issue working with itunesconnect using mechanize. After much frustration i found that there's a bug in cookielib that doesn't handle some cookies correctly. It's discussed here: http://bugs.python.org/issue3924
The fix at the bottom of that post worked for me. I'll repost here for convenience.
Basically you create a custom subclass of cookielib.CookieJar, override _cookie_from_cookie_tuple and use this CustomCookieJar in place of the cookielib jar
class CustomCookieJar(cookielib.CookieJar):
def _cookie_from_cookie_tuple(self, tup, request):
name, value, standard, rest = tup
version = standard.get("version", None)
if version is not None:
# Some servers add " around the version number, this module expects a pure int.
standard["version"] = version.strip('"')
return cookielib.CookieJar._cookie_from_cookie_tuple(self, tup,request)