Skip to content

Commit

Permalink
fb handler put message in a queue of tasks and returns 200ok
Browse files Browse the repository at this point in the history
  • Loading branch information
hyzhak committed May 20, 2017
1 parent ad4fd08 commit 6e860eb
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
26 changes: 26 additions & 0 deletions botstory/integrations/fb/messenger.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
from botstory.ast import story_context
import functools
import logging
from . import validate
from .. import commonhttp
Expand Down Expand Up @@ -226,6 +227,31 @@ async def request_profile(self, facebook_user_id):
)

async def handle(self, data):
"""
handle fb messenger message and return 200Ok as quick as possible
In background we launch process of handling incoming message
This solution is ok only for small apps for bigger one it is much better
to use a queue.
TODO: support third party queue
:param data:
:return:
"""
loop = asyncio.get_event_loop()
loop.create_task(self.process(data))
return {
'status': 200,
'text': 'Ok!',
}

async def process(self, data):
"""
async process message which comes from fb messenger
:param data:
:return:
"""
logger.debug('')
logger.debug('> handle <')
logger.debug('')
Expand Down
72 changes: 63 additions & 9 deletions botstory/integrations/fb/messenger_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ async def test_should_request_user_data_once_we_do_not_know_current_user():
}))
story.use(mockdb.MockDB())

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -595,7 +595,7 @@ async def test_should_request_user_data_and_fail():
get_raise=commonhttp.errors.HttpRequestError()))
db = story.use(mockdb.MockDB())

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -635,7 +635,7 @@ async def test_webhook_handler_should_return_ok_status_if_http_fail():
story.use(mockhttp.MockHttpInterface(get_raise=commonhttp.errors.HttpRequestError()))
story.use(mockdb.MockDB())

res = await fb_interface.handle({
res = await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -669,7 +669,7 @@ async def test_webhook_handler_should_return_ok_status_in_any_case():

fb_interface = messenger.FBInterface()
with mock.patch('botstory.integrations.fb.messenger.logger') as mock_logger:
res = await fb_interface.handle({
res = await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -741,7 +741,7 @@ def incorrect_story():
def store_result(ctx):
incorrect_trigger.receive(story_context.get_message_data(ctx))

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -792,7 +792,7 @@ def incorrect_story():
def store_result(ctx):
incorrect_trigger.receive(story_context.get_message_data(ctx))

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -847,7 +847,7 @@ def incorrect_story():
def store_result(ctx):
incorrect_trigger.receive(story_context.get_message_data(ctx))

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -885,7 +885,7 @@ def like_story():
def store_result(ctx):
like_is_here_trigger.passed()

await fb_interface.handle({
await fb_interface.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -920,7 +920,7 @@ def one_story():
def sync_part(message):
echo_trigger.passed()

await fb_interface.handle({
await fb_interface.process({
'entry': [
{
'id': '329188380752158',
Expand Down Expand Up @@ -1416,3 +1416,57 @@ def deps(self, fb):

assert isinstance(di.injector.get('one_class').fb.http, mockhttp.MockHttpInterface)
assert isinstance(di.injector.get('one_class').fb.storage, mockdb.MockDB)


def one_message(talk):
return {
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
'time': 1473204787206,
'messaging': [
{
'sender': {
'id': talk.user['facebook_user_id'],
},
'recipient': {
'id': 'PAGE_ID'
},
'timestamp': 1458692752478,
'message': {
'mid': 'mid.1457764197618:41d102a3e1ae206a38',
'seq': 73,
'text': 'hello, world!'
}
}
]
}]
}


@pytest.mark.asyncio
async def test_quickly_returns_200ok():
trigger = utils.SimpleTrigger()

with answer.Talk() as talk:
story = talk.story
fb_interface = story.use(messenger.FBInterface(page_access_token='qwerty1'))
story.use(mockdb.MockDB())
story.use(mockhttp.MockHttpInterface())

@story.on('hello, world!')
def one_story():
@story.part()
def store_result(ctx):
trigger.passed()

await story.start()

res = await fb_interface.handle(one_message(talk))
assert res == {
'status': 200,
'text': 'Ok!',
}
assert not trigger.is_passed()
await asyncio.sleep(0)
assert trigger.is_passed()
10 changes: 5 additions & 5 deletions botstory/integrations/tests/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def correct_story():
def store_result(ctx):
trigger.receive(ctx)

await facebook.handle(build_message(
await facebook.process(build_message(
user['facebook_user_id'], {
'text': 'hello, world!'
}
Expand All @@ -166,7 +166,7 @@ def correct_story():
def store_result_for_new_user(message):
trigger.receive(message)

await facebook.handle(build_message('some-facebook-id', {
await facebook.process(build_message('some-facebook-id', {
'text': 'hello, world!'
}))

Expand Down Expand Up @@ -216,7 +216,7 @@ def greeting(ctx):

await story.start()

await facebook.handle({
await facebook.process({
'object': 'page',
'entry': [{
'id': 'PAGE_ID',
Expand Down Expand Up @@ -267,10 +267,10 @@ def then_trigger_1(message):

await story.start()

await facebook.handle(build_message(user['facebook_user_id'], {
await facebook.process(build_message(user['facebook_user_id'], {
'text': 'hi there!'
}))
await facebook.handle(build_message(user['facebook_user_id'], {
await facebook.process(build_message(user['facebook_user_id'], {
'text': 'Great!'
}))

Expand Down

0 comments on commit 6e860eb

Please sign in to comment.