Skip to content

Commit 057f9ef

Browse files
authored
Merge pull request #12 from hyzhak/feature/deploy-to-heroku
Feature/deploy to heroku
2 parents e877abf + 16c3e19 commit 057f9ef

11 files changed

+112
-41
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,5 @@ ENV/
9090

9191
# IDEA
9292
.idea
93+
94+
docker-compose.dev.yml

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ services:
1111

1212
env:
1313
DOCKER_COMPOSE_VERSION: 1.8.0
14-
MONGODB_URL: 127.0.0.1
14+
MONGODB_URI: 127.0.0.1
15+
MONGODB_DB_NAME: test
1516

1617
before_install:
1718
- pip install -r requirements.txt

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: ./scripts/start.sh

app.json

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
{
22
"name": "echo-bot",
33
"description": "Very simple example of using bot-story framework",
4-
"scripts": {
5-
},
6-
"env": {
7-
},
8-
"formation": {
9-
},
10-
"addons": [
11-
12-
],
13-
"buildpacks": [
14-
15-
]
4+
"scripts": {},
5+
"env": {},
6+
"formation": {},
7+
"addons": [],
8+
"buildpacks": []
169
}

docker-compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ services:
44
image: mongo
55
bot:
66
build: .
7-
command: python ./echo/main.py
7+
command: ./scripts/start.sh
8+
environment:
9+
- PORT=8080
810
ports:
911
- "80:8080"
1012
volumes:

echo/gunicorn_runner.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .main import main
2+
3+
app = main(forever=False)

echo/main.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import asyncio
2-
import botstory
32
from botstory import chat, story
43
from botstory.integrations import aiohttp, fb, mongodb
54
from botstory.middlewares import any, text
@@ -23,46 +22,55 @@ async def echo(message):
2322
@story.on(receive=any.Any())
2423
def else_story():
2524
@story.part()
26-
async def something_else():
27-
await chat.say('Hm I don''t know what is it')
25+
async def something_else(message):
26+
await chat.say('Hm I don''t know what is it', message['user'])
2827

2928

3029
# setup modules
3130

32-
async def init(fake_http_session=None):
31+
async def init(auto_start=True, fake_http_session=None):
3332
story.use(fb.FBInterface(
34-
token=os.environ.get('FB_ACCESS_TOKEN', None),
35-
webhook=os.environ.get('WEBHOOK_URL_SECRET_PART', '/webhook'),
33+
page_access_token=os.environ.get('FB_ACCESS_TOKEN', None),
34+
webhook_url='/webhook{}'.format(os.environ.get('FB_WEBHOOK_URL_SECRET_PART', '')),
35+
webhook_token=os.environ.get('FB_WEBHOOK_TOKEN', None),
3636
))
37-
story.use(aiohttp.AioHttpInterface(
37+
http = story.use(aiohttp.AioHttpInterface(
3838
port=os.environ.get('API_PORT', 8080),
39-
)).session = fake_http_session
39+
auto_start=auto_start,
40+
))
4041
story.use(mongodb.MongodbInterface(
41-
uri=os.environ.get('MONGODB_URL', 'mongo'),
42-
db_name='tests',
42+
uri=os.environ.get('MONGODB_URI', 'mongo'),
43+
db_name=os.environ.get('MONGODB_DB_NAME', 'echobot'),
4344
))
4445

4546
await story.start()
46-
logger.info('start!')
47+
48+
logger.info('started!')
49+
50+
# for test purpose
51+
http.session = fake_http_session
52+
53+
return http.app
4754

4855

4956
async def stop():
50-
await botstory.story.stop()
57+
await story.stop()
58+
# TODO: should be something like
59+
# story.clear()
60+
story.middlewares = []
5161

5262

5363
# launch app
54-
55-
def main():
56-
# init logging
64+
def main(forever=True):
5765
logging.basicConfig(level=logging.DEBUG)
5866

5967
loop = asyncio.get_event_loop()
60-
loop.run_until_complete(init())
61-
62-
story.forever(loop)
68+
app = loop.run_until_complete(init(auto_start=forever))
69+
if forever:
70+
story.forever(loop)
6371

64-
# TODO: 1) we should support gunicorn
72+
return app
6573

6674

6775
if __name__ == '__main__':
68-
main()
76+
main(forever=True)

echo/main_test.py

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
from botstory.integrations import aiohttp, fb
22
from botstory.integrations.tests.fake_server import fake_fb
3+
import os
34
import pytest
45

56
from . import main
67

78

89
@pytest.mark.asyncio
910
async def test_text_echo(event_loop):
10-
try:
11-
async with fake_fb.Server(event_loop) as server:
12-
async with server.session() as server_session:
11+
async with fake_fb.Server(event_loop) as server:
12+
async with server.session() as server_session:
13+
try:
1314
await main.init(fake_http_session=server_session)
1415

1516
# send message from user
1617
http = aiohttp.AioHttpInterface()
17-
await http.post('http://localhost:8080/webhook', json={
18+
await http.post_raw('http://0.0.0.0:{}/webhook'.format(os.environ.get('API_PORT', 8080)), json={
1819
"object": "page",
1920
"entry": [{
2021
"id": "PAGE_ID",
@@ -50,5 +51,60 @@ async def test_text_echo(event_loop):
5051
},
5152
'recipient': {'id': 'USER_ID'},
5253
}
53-
finally:
54-
await main.stop()
54+
finally:
55+
await main.stop()
56+
57+
58+
@pytest.mark.asyncio
59+
async def test_should_ignore_like(event_loop):
60+
async with fake_fb.Server(event_loop) as server:
61+
async with server.session() as server_session:
62+
try:
63+
await main.init(fake_http_session=server_session)
64+
65+
http = aiohttp.AioHttpInterface()
66+
await http.post_raw('http://0.0.0.0:{}/webhook'.format(os.environ.get('API_PORT', 8080)), json={
67+
"entry": [
68+
{
69+
"id": "329188380752158",
70+
"messaging": [
71+
{
72+
"message": {
73+
"attachments": [
74+
{
75+
"payload": {
76+
"sticker_id": 369239263222822,
77+
"url": "https://scontent.xx.fbcdn.net/t39.1997-6/851557_369239266556155_759568595_n.png?_nc_ad=z-m"
78+
},
79+
"type": "image"
80+
}
81+
],
82+
"mid": "mid.1477264110799:ac44f49883",
83+
"seq": 50,
84+
"sticker_id": 369239263222822
85+
},
86+
"recipient": {
87+
"id": "329188380752158"
88+
},
89+
"sender": {
90+
"id": "1034692249977067"
91+
},
92+
"timestamp": 1477264110799
93+
}
94+
],
95+
"time": 1477264110878
96+
}
97+
],
98+
"object": "page"
99+
})
100+
101+
# receive message from bot
102+
assert len(server.history) == 1
103+
assert await server.history[0]['request'].json() == {
104+
'message': {
105+
'text': 'Hm I don''t know what is it'
106+
},
107+
'recipient': {'id': '1034692249977067'},
108+
}
109+
finally:
110+
await main.stop()

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
botstory==0.0.14
1+
botstory==0.0.24
2+
gunicorn==19.6.0
23
pytest==3.0.3
34
pytest-aiohttp==0.1.2
45
pytest-asyncio==0.5.0

runtime.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python-3.5.2

scripts/start.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
3+
gunicorn echo.gunicorn_runner:app --bind 0.0.0.0:${PORT} --log-file - --reload --worker-class aiohttp.worker.GunicornWebWorker

0 commit comments

Comments
 (0)