-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add FB Messenger integration and documentation for agent (#10)
- Loading branch information
Showing
8 changed files
with
181 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Deploying a Facebook Messenger Chat Agent | ||
|
||
This guide is based on ParlAI's [chat service tutorial](https://parl.ai/docs/tutorial_chat_service.html), where we provide the base configuration and classes for deploying our example `ChattyGooseAgent` as a Facebook Messenger chatbot. The following steps deploy the webhook server to Heroku, however it is also possible to deploy it locally by setting the `local: True` parameter under `opt` in `config.yml`. | ||
|
||
1. Create a new [Facebook Page](https://www.facebook.com/pages/create) and [Facebook App for Messenger](https://developers.facebook.com/docs/messenger-platform/getting-started/app-setup) to host the Chatty Goose agent. Add your Facebook Page under the Webhooks settings for Messenger, and check the "messages" subscription field. | ||
|
||
2. If deploying to Heroku, create a free account and log into the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) on your machine. | ||
|
||
3. Run the webhook server and Chatty Goose agent using our provided configuration. This assumes you have the ParlAI Python package installed and are inside the `chatty-goose` root repository folder. | ||
|
||
``` | ||
python3.7 -m parlai.chat_service.services.messenger.run --config-path examples/messenger/config.yml | ||
``` | ||
|
||
4. Add the webhook URL outputted from the above command as a callback URL for the Messenger App settings, and set the verify token to `Messenger4ParlAI`. For Heroku, this URL should look like `https://firstname-parlai-messenger-chatbot.herokuapp.com/webhook`. | ||
|
||
5. Visiting your page and sending a message should now trigger the agent to respond! |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
tasks: | ||
default: | ||
onboard_world: ChattyGooeMessengerOnboardWorld | ||
task_world: ChattyGooseMessengerTaskWorld | ||
timeout: 180 | ||
agents_required: 1 | ||
task_name: chatbot | ||
world_module: examples.messenger.worlds | ||
overworld: ChattyGooseMessengerOverworld | ||
max_workers: 30 | ||
opt: | ||
debug: True | ||
password: ChattyGoose | ||
models: | ||
chatty_goose: | ||
model: chatty_goose.agents.cqragent:ChattyGooseAgent | ||
additional_args: | ||
page_id: ChattyGooseIR # Configure for custom page |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
from parlai.core.worlds import World | ||
from parlai.chat_service.services.messenger.worlds import OnboardWorld | ||
from parlai.core.agents import create_agent_from_shared | ||
|
||
|
||
class ChattyGooeMessengerOnboardWorld(OnboardWorld): | ||
""" | ||
Example messenger onboarding world for Chatty Goose. | ||
""" | ||
|
||
@staticmethod | ||
def generate_world(opt, agents): | ||
return ChattyGooeMessengerOnboardWorld(opt=opt, agent=agents[0]) | ||
|
||
def parley(self): | ||
self.episodeDone = True | ||
|
||
|
||
class ChattyGooseMessengerTaskWorld(World): | ||
""" | ||
Example one person world that talks to a provided agent. | ||
""" | ||
MODEL_KEY = 'chatty_goose' | ||
|
||
def __init__(self, opt, agent, bot): | ||
self.agent = agent | ||
self.episodeDone = False | ||
self.model = bot | ||
self.first_time = True | ||
|
||
@staticmethod | ||
def generate_world(opt, agents): | ||
if opt['models'] is None: | ||
raise RuntimeError("Model must be specified") | ||
return ChattyGooseMessengerTaskWorld( | ||
opt, | ||
agents[0], | ||
create_agent_from_shared( | ||
opt['shared_bot_params'][ChattyGooseMessengerTaskWorld.MODEL_KEY] | ||
), | ||
) | ||
|
||
@staticmethod | ||
def assign_roles(agents): | ||
agents[0].disp_id = 'ChattyGooseAgent' | ||
|
||
def parley(self): | ||
if self.first_time: | ||
self.agent.observe( | ||
{ | ||
'id': 'World', | ||
'text': 'Welcome to the Chatty Goose demo! ' | ||
'Please type a query. ' | ||
'Type [DONE] to finish the chat, or [RESET] to reset the dialogue history.', | ||
} | ||
) | ||
self.first_time = False | ||
a = self.agent.act() | ||
if a is not None: | ||
if '[DONE]' in a['text']: | ||
self.episodeDone = True | ||
elif '[RESET]' in a['text']: | ||
self.model.reset() | ||
self.agent.observe({"text": "[History Cleared]", "episode_done": False}) | ||
else: | ||
self.model.observe(a) | ||
response = self.model.act() | ||
self.agent.observe(response) | ||
|
||
def episode_done(self): | ||
return self.episodeDone | ||
|
||
def shutdown(self): | ||
self.agent.shutdown() | ||
|
||
|
||
class ChattyGooseMessengerOverworld(World): | ||
""" | ||
World to handle moving agents to their proper places. | ||
""" | ||
|
||
def __init__(self, opt, agent): | ||
self.agent = agent | ||
self.opt = opt | ||
self.first_time = True | ||
self.episodeDone = False | ||
|
||
@staticmethod | ||
def generate_world(opt, agents): | ||
return ChattyGooseMessengerOverworld(opt, agents[0]) | ||
|
||
@staticmethod | ||
def assign_roles(agents): | ||
for a in agents: | ||
a.disp_id = 'Agent' | ||
|
||
def episode_done(self): | ||
return self.episodeDone | ||
|
||
def parley(self): | ||
if self.first_time: | ||
self.agent.observe( | ||
{ | ||
'id': 'Overworld', | ||
'text': 'Welcome to the Chatty Goose Messenger overworld! ' | ||
'Please type "Start" to start, or "Exit" to exit. ', | ||
'quick_replies': ['Start', 'Exit'], | ||
} | ||
) | ||
self.first_time = False | ||
a = self.agent.act() | ||
if a is not None and a['text'].lower() == 'exit': | ||
self.episode_done = True | ||
return 'EXIT' | ||
if a is not None and a['text'].lower() == 'start': | ||
self.episodeDone = True | ||
return 'default' | ||
elif a is not None: | ||
self.agent.observe( | ||
{ | ||
'id': 'Overworld', | ||
'text': 'Invalid option. Please type "Start".', | ||
'quick_replies': ['Start'], | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
coloredlogs | ||
parlai==1.0.0 | ||
parlai==1.1.0 | ||
pydantic>=1.5 | ||
pygaggle==0.0.2 | ||
spacy>=2.2.4 |